4e1a761b2e2b2ae2f10bedbba1172dfca0dfd927
[u/mrichter/AliRoot.git] / RALICE / AliEvent.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, 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 // $Id: AliEvent.cxx,v 1.17 2003/12/18 09:28:06 nick Exp $
17
18 ///////////////////////////////////////////////////////////////////////////
19 // Class AliEvent
20 // Creation and investigation of an Alice physics event.
21 // An AliEvent can be constructed by adding AliTracks, Alivertices, AliJets
22 // and/or devices like AliCalorimeters.
23 // All objects which are derived from TObject can be regarded as a device.
24 //
25 // The basic functionality of AliEvent is identical to the one of AliVertex.
26 // So, an AliEvent may be used as the primary vertex with some additional
27 // functionality compared to AliVertex.
28 //
29 // To provide maximal flexibility to the user, the two modes of track/jet/vertex
30 // storage as described in AliJet and AliVertex can be used.
31 // In addition an identical structure is provided for the storage of devices like
32 // AliCalorimeter objects, which can be selected by means of the memberfunction
33 // SetDevCopy().
34 //
35 // a) SetDevCopy(0) (which is the default).
36 //    Only the pointers of the 'added' devices are stored.
37 //    This mode is typically used by making studies based on a fixed set
38 //    of devices which stays under user control or is kept on an external
39 //    file/tree. 
40 //    In this way the AliEvent just represents a 'logical structure' for the
41 //    physics analysis.
42 //
43 //    Note :
44 //    Modifications made to the original devices also affect the device
45 //    objects which are stored in the AliEvent. 
46 //
47 // b) SetDevCopy(1).
48 //    Of every 'added' device a private copy will be made of which the pointer
49 //    will be stored.
50 //    In this way the AliEvent represents an entity on its own and modifications
51 //    made to the original calorimeters do not affect the AliCalorimeter objects
52 //    which are stored in the AliEvent. 
53 //    This mode will allow 'adding' many different devices into an AliEvent by
54 //    creating only one device instance in the main programme and using the
55 //    Reset() and parameter setting memberfunctions of the object representing the device.
56 //
57 //    Note :
58 //    The copy is made using the Clone() memberfunction.
59 //    All devices (i.e. classes derived from TObject) have the default TObject::Clone() 
60 //    memberfunction.
61 //    However, devices generally contain an internal (signal) data structure
62 //    which may include pointers to other objects. Therefore it is recommended to provide
63 //    for all devices a specific copy constructor and override the default Clone()
64 //    memberfunction using this copy constructor.
65 //    An example for this may be seen from AliCalorimeter.   
66 //
67 // See also the documentation provided for the memberfunction SetOwner(). 
68 //
69 // Coding example to make an event consisting of a primary vertex,
70 // 2 secondary vertices and a calorimeter.
71 // --------------------------------------------------------------
72 // vp contains the tracks 1,2,3 and 4 (primary vertex)
73 // v1 contains the tracks 5,6 and 7   (sec. vertex)
74 // v2 contains the jets 1 and 2       (sec. vertex)
75 //
76 //        AliEvent evt;
77 //
78 // Specify the event object as the repository of all objects
79 // for the event building and physics analysis.
80 // 
81 //        evt.SetDevCopy(1);
82 //        evt.SetTrackCopy(1);
83 //
84 // Fill the event structure with the basic objects
85 // 
86 //        AliCalorimeter emcal;
87 //         ...
88 //         ... // code to fill the calorimeter data
89 //         ...
90 //
91 //        evt.AddDevice(emcal);
92 //
93 //        AliTrack* tx=new AliTrack();
94 //        for (Int_t i=0; i<10; i++)
95 //        {
96 //         ...
97 //         ... // code to fill the track data
98 //         ...
99 //         evt.AddTrack(tx);
100 //         tx->Reset(); 
101 //        }
102 //
103 //        if (tx)
104 //        {
105 //         delete tx;
106 //         tx=0;
107 //        }
108 //
109 // Build the event structure (vertices, jets, ...) for physics analysis
110 // based on the basic objects from the event repository.
111 //
112 //        AliJet j1,j2;
113 //        for (Int_t i=0; i<evt.GetNtracks(); i++)
114 //        {
115 //         tx=evt.GetTrack(i);
116 //         ...
117 //         ... // code to fill the jet data
118 //         ...
119 //        }
120 //
121 //        AliVertex vp;
122 //        tx=evt.GetTrack(1);
123 //        vp.AddTrack(tx);
124 //        tx=evt.GetTrack(2);
125 //        vp.AddTrack(tx);
126 //        tx=evt.GetTrack(3);
127 //        vp.AddTrack(tx);
128 //        tx=evt.GetTrack(4);
129 //        vp.AddTrack(tx);
130 //
131 //        Float_t rp[3]={2.4,0.1,-8.5};
132 //        vp.SetPosition(rp,"car");
133 //
134 //        AliVertex v1;
135 //        tx=evt.GetTrack(5);
136 //        v1.AddTrack(tx);
137 //        tx=evt.GetTrack(6);
138 //        v1.AddTrack(tx);
139 //        tx=evt.GetTrack(7);
140 //        v1.AddTrack(tx);
141 //
142 //        Float_t r1[3]={1.6,-3.2,5.7};
143 //        v1.SetPosition(r1,"car");
144 //
145 //
146 //        AliVertex v2;
147 //        v2.SetJetCopy(1);
148 //        v2.AddJet(j1);
149 //        v2.AddJet(j2);
150 //
151 //        Float_t r2[3]={6.2,4.8,1.3};
152 //        v2.SetPosition(r2,"car");
153 //
154 // Specify the vertices v1 and v2 as secondary vertices of the primary
155 //
156 //        vp.SetVertexCopy(1);
157 //        vp.AddVertex(v1);
158 //        vp.AddVertex(v2);
159 //
160 // Enter the physics structures into the event
161 //        evt.SetVertexCopy(1);
162 //        evt.AddVertex(vp,0);
163 //
164 // The jets j1 and j2 are already available via sec. vertex v2,
165 // but can be made available also from the event itself if desired.
166 //        AliJet* jx;
167 //        jx=v2.GetJet(1);
168 //        evt.AddJet(jx,0); 
169 //        jx=v2.GetJet(2);
170 //        evt.AddJet(jx,0); 
171 // 
172 //        evt.Data("sph");
173 //        v1.ListAll();
174 //        v2.List("cyl");
175 //
176 //        Float_t etot=evt.GetEnergy();
177 //        Ali3Vector ptot=evt.Get3Momentum();
178 //        Float_t loc[3];
179 //        evt.GetPosition(loc,"sph");
180 //        AliPosition r=v1.GetPosition();
181 //        r.Data(); 
182 //        Int_t nt=v2.GetNtracks();
183 //        AliTrack* tv=v2.GetTrack(1); // Access track number 1 of Vertex v2
184 //
185 //        evt.List();
186 //
187 //        Int_t nv=evt.GetNvtx();
188 //        AliVertex* vx=evt.GetVertex(1); // Access primary vertex
189 //        Float_t e=vx->GetEnergy();
190 //
191 //        Float_t M=evt.GetInvmass(); 
192 //
193 // Reconstruct the event from scratch
194 //
195 //        evt.Reset();
196 //        evt.SetNvmax(25); // Increase initial no. of sec. vertices
197 //        ...
198 //        ... // code to create tracks etc... 
199 //        ...
200 //
201 // Note : All quantities are in GeV, GeV/c or GeV/c**2
202 //
203 //--- Author: Nick van Eijndhoven 27-may-2001 UU-SAP Utrecht
204 //- Modified: NvE $Date: 2003/12/18 09:28:06 $ UU-SAP Utrecht
205 ///////////////////////////////////////////////////////////////////////////
206
207 #include "AliEvent.h"
208 #include "Riostream.h"
209  
210 ClassImp(AliEvent) // Class implementation to enable ROOT I/O
211  
212 AliEvent::AliEvent() : AliVertex()
213 {
214 // Default constructor.
215 // All variables initialised to default values.
216  TTimeStamp tx;
217  fDaytime=tx;
218  fRun=0;
219  fEvent=0;
220  fAproj=0;
221  fZproj=0;
222  fPnucProj=0;
223  fIdProj=0;
224  fAtarg=0;
225  fZtarg=0;
226  fPnucTarg=0;
227  fIdTarg=0;
228  fDevices=0;
229  fDevCopy=0;
230 }
231 ///////////////////////////////////////////////////////////////////////////
232 AliEvent::AliEvent(Int_t n) : AliVertex(n)
233 {
234 // Create an event to hold initially a maximum of n tracks
235 // All variables initialised to default values
236  if (n<=0)
237  {
238   cout << " *** This AliVertex initialisation was invoked via the AliEvent ctor." << endl;
239  }
240  TTimeStamp tx;
241  fDaytime=tx;
242  fRun=0;
243  fEvent=0;
244  fAproj=0;
245  fZproj=0;
246  fPnucProj=0;
247  fIdProj=0;
248  fAtarg=0;
249  fZtarg=0;
250  fPnucTarg=0;
251  fIdTarg=0;
252  fDevices=0;
253  fDevCopy=0;
254 }
255 ///////////////////////////////////////////////////////////////////////////
256 AliEvent::~AliEvent()
257 {
258 // Default destructor
259  if (fDevices)
260  {
261   delete fDevices;
262   fDevices=0;
263  }
264 }
265 ///////////////////////////////////////////////////////////////////////////
266 AliEvent::AliEvent(AliEvent& evt) : AliVertex(evt)
267 {
268 // Copy constructor.
269  fDaytime=evt.fDaytime;
270  fRun=evt.fRun;
271  fEvent=evt.fEvent;
272  fAproj=evt.fAproj;
273  fZproj=evt.fZproj;
274  fPnucProj=evt.fPnucProj;
275  fIdProj=evt.fIdProj;
276  fAtarg=evt.fAtarg;
277  fZtarg=evt.fZtarg;
278  fPnucTarg=evt.fPnucTarg;
279  fIdTarg=evt.fIdTarg;
280  fDevCopy=evt.fDevCopy;
281
282  fDevices=0;
283  Int_t ndevs=evt.GetNdevices();
284  if (ndevs)
285  {
286   fDevices=new TObjArray(ndevs);
287   if (fDevCopy) fDevices->SetOwner();
288   for (Int_t i=1; i<=ndevs; i++)
289   {
290    TObject* dev=evt.GetDevice(i);
291    if (dev)
292    {
293     if (fDevCopy)
294     {
295      fDevices->Add(dev->Clone());
296     }
297     else
298     {
299      fDevices->Add(dev);
300     }
301    }
302   }
303  }
304 }
305 ///////////////////////////////////////////////////////////////////////////
306 void AliEvent::Reset()
307 {
308 // Reset all variables to default values
309 // The max. number of tracks is set to the initial value again
310 // The max. number of vertices is set to the default value again
311 // Note : The CalCopy mode is maintained as it was set by the user before.
312
313  AliVertex::Reset();
314
315  TTimeStamp tx;
316  fDaytime=tx;
317  fRun=0;
318  fEvent=0;
319  fAproj=0;
320  fZproj=0;
321  fPnucProj=0;
322  fIdProj=0;
323  fAtarg=0;
324  fZtarg=0;
325  fPnucTarg=0;
326  fIdTarg=0;
327
328  if (fDevices)
329  {
330   delete fDevices;
331   fDevices=0;
332  }
333 }
334 ///////////////////////////////////////////////////////////////////////////
335 void AliEvent::SetOwner(Bool_t own)
336 {
337 // Set ownership of all added objects. 
338 // The default parameter is own=kTRUE.
339 //
340 // Invokation of this memberfunction also sets all the copy modes
341 // (e.g. TrackCopy & co.) according to the value of own.
342 //
343 // This function (with own=kTRUE) is particularly useful when reading data
344 // from a tree/file, since Reset() will then actually remove all the
345 // added objects from memory irrespective of the copy mode settings
346 // during the tree/file creation process. In this way it provides a nice way
347 // of preventing possible memory leaks in the reading/analysis process.
348 //
349 // In addition this memberfunction can also be used as a shortcut to set all
350 // copy modes in one go during a tree/file creation process.
351 // However, in this case the user has to take care to only set/change the
352 // ownership (and copy mode) for empty objects (e.g. newly created objects
353 // or after invokation of the Reset() memberfunction) otherwise it will
354 // very likely result in inconsistent destructor behaviour.
355
356  Int_t mode=1;
357  if (!own) mode=0;
358  if (fDevices) fDevices->SetOwner(own);
359  fDevCopy=mode;
360
361  AliVertex::SetOwner(own);
362 }
363 ///////////////////////////////////////////////////////////////////////////
364 void AliEvent::SetDayTime(TTimeStamp& stamp)
365 {
366 // Set the date and time stamp for this event.
367 // An exact copy of the entered date/time stamp will be saved with an
368 // accuracy of 1 nanosecond.
369  fDaytime=stamp;
370 }
371 ///////////////////////////////////////////////////////////////////////////
372 void AliEvent::SetDayTime(TDatime& stamp)
373 {
374 // Set the date and time stamp for this event.
375 // The entered date/time will be interpreted as being the local date/time
376 // and the accuracy is 1 second.
377 // This function with the TDatime argument is mainly kept for backward
378 // compatibility reasons. It is recommended to use the corresponding
379 // function with the TTimeStamp argument.
380
381  TTimeStamp ts(stamp.GetDate(),stamp.GetTime(),0,kFALSE);
382  fDaytime=ts;
383 }
384 ///////////////////////////////////////////////////////////////////////////
385 void AliEvent::SetRunNumber(Int_t run)
386 {
387 // Set the run number for this event
388  fRun=run;
389 }
390 ///////////////////////////////////////////////////////////////////////////
391 void AliEvent::SetEventNumber(Int_t evt)
392 {
393 // Set the event number for this event
394  fEvent=evt;
395 }
396 ///////////////////////////////////////////////////////////////////////////
397 TTimeStamp AliEvent::GetDayTime()
398 {
399 // Provide the date and time stamp for this event
400  return fDaytime;
401 }
402 ///////////////////////////////////////////////////////////////////////////
403 Int_t AliEvent::GetRunNumber()
404 {
405 // Provide the run number for this event
406  return fRun;
407 }
408 ///////////////////////////////////////////////////////////////////////////
409 Int_t AliEvent::GetEventNumber()
410 {
411 // Provide the event number for this event
412  return fEvent;
413 }
414 ///////////////////////////////////////////////////////////////////////////
415 void AliEvent::SetProjectile(Int_t a,Int_t z,Double_t pnuc,Int_t id)
416 {
417 // Set the projectile A, Z, momentum per nucleon and user defined particle ID.
418 // By default the particle ID is set to zero.
419  fAproj=a;
420  fZproj=z;
421  fPnucProj=pnuc;
422  fIdProj=id;
423 }
424 ///////////////////////////////////////////////////////////////////////////
425 Int_t AliEvent::GetProjectileA()
426 {
427 // Provide the projectile A value.
428  return fAproj;
429 }
430 ///////////////////////////////////////////////////////////////////////////
431 Int_t AliEvent::GetProjectileZ()
432 {
433 // Provide the projectile Z value.
434  return fZproj;
435 }
436 ///////////////////////////////////////////////////////////////////////////
437 Double_t AliEvent::GetProjectilePnuc()
438 {
439 // Provide the projectile momentum value per nucleon.
440  return fPnucProj;
441 }
442 ///////////////////////////////////////////////////////////////////////////
443 Int_t AliEvent::GetProjectileId()
444 {
445 // Provide the user defined particle ID of the projectile.
446  return fIdProj;
447 }
448 ///////////////////////////////////////////////////////////////////////////
449 void AliEvent::SetTarget(Int_t a,Int_t z,Double_t pnuc,Int_t id)
450 {
451 // Set the target A, Z, momentum per nucleon and user defined particle ID.
452 // By default the particle ID is set to zero.
453  fAtarg=a;
454  fZtarg=z;
455  fPnucTarg=pnuc;
456  fIdTarg=id;
457 }
458 ///////////////////////////////////////////////////////////////////////////
459 Int_t AliEvent::GetTargetA()
460 {
461 // Provide the target A value.
462  return fAtarg;
463 }
464 ///////////////////////////////////////////////////////////////////////////
465 Int_t AliEvent::GetTargetZ()
466 {
467 // Provide the target Z value.
468  return fZtarg;
469 }
470 ///////////////////////////////////////////////////////////////////////////
471 Double_t AliEvent::GetTargetPnuc()
472 {
473 // Provide the target momentum value per nucleon.
474  return fPnucTarg;
475 }
476 ///////////////////////////////////////////////////////////////////////////
477 Int_t AliEvent::GetTargetId()
478 {
479 // Provide the user defined particle ID of the target.
480  return fIdTarg;
481 }
482 ///////////////////////////////////////////////////////////////////////////
483 void AliEvent::HeaderData()
484 {
485 // Provide event header information
486  const char* name=GetName();
487  const char* title=GetTitle();
488  Int_t ndevs=GetNdevices();
489  cout << " *" << ClassName() << "::Data*";
490  if (strlen(name))  cout << " Name : " << GetName();
491  if (strlen(title)) cout << " Title : " << GetTitle();
492  cout << endl;
493  cout << "  " << fDaytime.AsString() << endl;
494  cout << "  Run : " << fRun << " Event : " << fEvent
495       << " Number of devices : " << ndevs << endl;
496
497  if (ndevs) ShowDevices();
498 }
499 ///////////////////////////////////////////////////////////////////////////
500 void AliEvent::Data(TString f)
501 {
502 // Provide event information within the coordinate frame f
503  HeaderData();
504  AliVertex::Data(f);
505
506 ///////////////////////////////////////////////////////////////////////////
507 Int_t AliEvent::GetNdevices()
508 {
509 // Provide the number of stored devices
510  Int_t ndevs=0;
511  if (fDevices) ndevs=fDevices->GetEntries();
512  return ndevs;
513
514 ///////////////////////////////////////////////////////////////////////////
515 void AliEvent::AddDevice(TObject& d)
516 {
517 // Add a device to the event.
518 //
519 // Note :
520 // In case a private copy is made, this is performed via the Clone() memberfunction.
521 // All devices (i.e. classes derived from TObject) have the default TObject::Clone() 
522 // memberfunction.
523 // However, devices generally contain an internal (signal) data structure
524 // which may include pointers to other objects. Therefore it is recommended to provide
525 // for all devices a specific copy constructor and override the default Clone()
526 // memberfunction using this copy constructor.
527 // An example for this may be seen from AliCalorimeter.   
528
529  if (!fDevices)
530  {
531   fDevices=new TObjArray();
532   if (fDevCopy) fDevices->SetOwner();
533  }
534  
535  // Add the device to this event
536  if (fDevCopy)
537  {
538   fDevices->Add(d.Clone());
539  }
540  else
541  {
542   fDevices->Add(&d);
543  }
544 }
545 ///////////////////////////////////////////////////////////////////////////
546 void AliEvent::SetDevCopy(Int_t j)
547 {
548 // (De)activate the creation of private copies of the added devices.
549 // j=0 ==> No private copies are made; pointers of original devices are stored.
550 // j=1 ==> Private copies of the devices are made and these pointers are stored.
551 //
552 //
553 // Notes :
554 //  In case a private copy is made, this is performed via the Clone() memberfunction.
555 //  All devices (i.e. classes derived from TObject) have the default TObject::Clone() 
556 //  memberfunction.
557 //  However, devices generally contain an internal (signal) data structure
558 //  which may include pointers to other objects. Therefore it is recommended to provide
559 //  for all devices a specific copy constructor and override the default Clone()
560 //  memberfunction using this copy constructor.
561 //  An example for this may be seen from AliCalorimeter.   
562 //
563 //  Once the storage contains pointer(s) to device(s) one cannot
564 //  change the DevCopy mode anymore.
565 //  To change the DevCopy mode for an existing AliEvent containing
566 //  devices one first has to invoke Reset().
567
568  if (!fDevices)
569  {
570   if (j==0 || j==1)
571   {
572    fDevCopy=j;
573   }
574   else
575   {
576    cout << " *" << ClassName() << "::SetDevCopy* Invalid argument : " << j << endl;
577   }
578  }
579  else
580  {
581   cout << " *" << ClassName() << "::SetDevCopy* Storage already contained devices."
582        << "  ==> DevCopy mode not changed." << endl; 
583  }
584 }
585 ///////////////////////////////////////////////////////////////////////////
586 Int_t AliEvent::GetDevCopy()
587 {
588 // Provide value of the DevCopy mode.
589 // 0 ==> No private copies are made; pointers of original devices are stored.
590 // 1 ==> Private copies of the devices are made and these pointers are stored.
591 //
592 // Note :
593 // In case a private copy is made, this is performed via the Clone() memberfunction.
594 // All devices (i.e. classes derived from TObject) have the default TObject::Clone() 
595 // memberfunction.
596 // However, devices generally contain an internal (signal) data structure
597 // which may include pointers to other objects. Therefore it is recommended to provide
598 // for all devices a specific copy constructor and override the default Clone()
599 // memberfunction using this copy constructor.
600 // An example for this may be seen from AliCalorimeter.   
601
602  return fDevCopy;
603 }
604 ///////////////////////////////////////////////////////////////////////////
605 TObject* AliEvent::GetDevice(Int_t i)
606 {
607 // Return the i-th device of this event.
608 // The first device corresponds to i=1.
609
610  if (!fDevices)
611  {
612   return 0;
613  }
614  else
615  {
616   Int_t ndevs=GetNdevices();
617   if (i<=0 || i>ndevs)
618   {
619    cout << " *" << ClassName() << "::GetDevice* Invalid argument i : " << i
620         << " ndevs = " << ndevs << endl;
621    return 0;
622   }
623   else
624   {
625    return fDevices->At(i-1);
626   }
627  }
628 }
629 ///////////////////////////////////////////////////////////////////////////
630 TObject* AliEvent::GetDevice(TString name)
631 {
632 // Return the device with name tag "name"
633  if (!fDevices)
634  {
635   return 0;
636  }
637  else
638  {
639   TString s;
640   Int_t ndevs=GetNdevices();
641   for (Int_t i=0; i<ndevs; i++)
642   {
643    TObject* dev=fDevices->At(i);
644    if (dev)
645    {
646     s=dev->GetName();
647     if (s == name) return dev;
648    }
649   }
650
651   return 0; // No matching name found
652  }
653 }
654 ///////////////////////////////////////////////////////////////////////////
655 void AliEvent::ShowDevices()
656 {
657 // Provide an overview of the available devices.
658  Int_t ndevs=GetNdevices();
659  if (ndevs)
660  {
661   cout << " The following " << ndevs << " devices are available :" << endl; 
662   for (Int_t i=1; i<=ndevs; i++)
663   {
664    TObject* dev=GetDevice(i);
665    if (dev)
666    {
667     cout << " Device number : " << i
668          << " Class : " << dev->ClassName()
669          << " Name : " << dev->GetName() << endl;
670    }
671   }
672  }
673  else
674  {
675   cout << " No devices present for this event." << endl;
676  }
677 }
678 ///////////////////////////////////////////////////////////////////////////
679 TObject* AliEvent::Clone(const char* name)
680 {
681 // Make a deep copy of the current object and provide the pointer to the copy.
682 // This memberfunction enables automatic creation of new objects of the
683 // correct type depending on the object type, a feature which may be very useful
684 // for containers when adding objects in case the container owns the objects.
685 // This feature allows to store either AliEvent objects or objects derived from
686 // AliEvent via some generic AddEvent memberfunction, provided these derived
687 // classes also have a proper Clone memberfunction. 
688
689  AliEvent* evt=new AliEvent(*this);
690  if (name)
691  {
692   if (strlen(name)) evt->SetName(name);
693  }
694  return evt;
695 }
696 ///////////////////////////////////////////////////////////////////////////
697