]> git.uio.no Git - u/mrichter/AliRoot.git/blob - RALICE/AliEvent.cxx
Number of pads along z is corrected
[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.25 2004/10/20 10:49:44 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 or AliDevice (derived) objects.
23 //
24 // All objects which are derived from TObject can be regarded as a device.
25 // However, AliDevice (or derived) objects profit from additional hit
26 // handling facilities.
27 // A "hit" is a generic name indicating an AliSignal (or derived) object.
28 // Note that AliEvent does NOT own hits; it only provides references to hits
29 // obtained from the various devices.
30 // This implies that hits should be owned by the devices themselves.
31 //
32 // The basic functionality of AliEvent is identical to the one of AliVertex.
33 // So, an AliEvent may be used as the primary vertex with some additional
34 // functionality compared to AliVertex.
35 //
36 // To provide maximal flexibility to the user, the two modes of track/jet/vertex
37 // storage as described in AliJet and AliVertex can be used.
38 // In addition an identical structure is provided for the storage of devices like
39 // AliCalorimeter objects, which can be selected by means of the memberfunction
40 // SetDevCopy().
41 //
42 // a) SetDevCopy(0) (which is the default).
43 //    Only the pointers of the 'added' devices are stored.
44 //    This mode is typically used by making studies based on a fixed set
45 //    of devices which stays under user control or is kept on an external
46 //    file/tree. 
47 //    In this way the AliEvent just represents a 'logical structure' for the
48 //    physics analysis.
49 //
50 //    Note :
51 //    Modifications made to the original devices also affect the device
52 //    objects which are stored in the AliEvent. 
53 //
54 // b) SetDevCopy(1).
55 //    Of every 'added' device a private copy will be made of which the pointer
56 //    will be stored.
57 //    In this way the AliEvent represents an entity on its own and modifications
58 //    made to the original calorimeters do not affect the AliCalorimeter objects
59 //    which are stored in the AliEvent. 
60 //    This mode will allow 'adding' many different devices into an AliEvent by
61 //    creating only one device instance in the main programme and using the
62 //    Reset() and parameter setting memberfunctions of the object representing the device.
63 //
64 //    Note :
65 //    The copy is made using the Clone() memberfunction.
66 //    All devices (i.e. classes derived from TObject) have the default TObject::Clone() 
67 //    memberfunction.
68 //    However, devices generally contain an internal (signal) data structure
69 //    which may include pointers to other objects. Therefore it is recommended to provide
70 //    for all devices a specific copy constructor and override the default Clone()
71 //    memberfunction using this copy constructor.
72 //    Examples for this may be seen from AliCalorimeter, AliSignal and AliDevice.   
73 //
74 // See also the documentation provided for the memberfunction SetOwner(). 
75 //
76 // Coding example to make an event consisting of a primary vertex,
77 // 2 secondary vertices and a calorimeter.
78 // --------------------------------------------------------------
79 // vp contains the tracks 1,2,3 and 4 (primary vertex)
80 // v1 contains the tracks 5,6 and 7   (sec. vertex)
81 // v2 contains the jets 1 and 2       (sec. vertex)
82 //
83 //        AliEvent evt;
84 //
85 // Specify the event object as the repository of all objects
86 // for the event building and physics analysis.
87 // 
88 //        evt.SetDevCopy(1);
89 //        evt.SetTrackCopy(1);
90 //
91 // Fill the event structure with the basic objects
92 // 
93 //        AliCalorimeter emcal1;
94 //        AliCalorimeter emcal2;
95 //         ...
96 //         ... // code to fill the emcal1 and emcal2 calorimeter data
97 //         ...
98 //
99 //        evt.AddDevice(emcal1);
100 //        evt.AddDevice(emcal2);
101 //
102 //        // Assume AliTOF has been derived from AliDevice
103 //        AliTOF tof1;
104 //        AliTOF tof2;
105 //         ...
106 //         ... // code to fill the tof1 and tof2 data
107 //         ...
108 //
109 //        evt.AddDevice(tof1);
110 //        evt.AddDevice(tof2);
111 //
112 //        AliTrack* tx=new AliTrack();
113 //        for (Int_t i=0; i<10; i++)
114 //        {
115 //         ...
116 //         ... // code to fill the track data
117 //         ...
118 //         evt.AddTrack(tx);
119 //         tx->Reset(); 
120 //        }
121 //
122 //        if (tx)
123 //        {
124 //         delete tx;
125 //         tx=0;
126 //        }
127 //
128 // Order and investigate all the hits of all the TOF devices
129 //
130 //        TObjArray* hits=evt.GetHits("AliTOF");
131 //        TObjArray* orderedtofs=evt.SortHits(hits);
132 //        Int_t nhits=0;
133 //        if (orderedtofs) nhits=orderedtofs->GetEntries();
134 //        for (Int_t i=0; i<nhits; i++)
135 //        {
136 //         AliSignal* sx=(AliSignal*)orderedtofs->At(i);
137 //         if (sx) sx->Data();
138 //        }
139 //
140 // Order and investigate all the hits of all the calorimeter devices
141 //
142 //        TObjArray* hits=evt.GetHits("AliCalorimeter");
143 //        TObjArray* orderedcals=evt.SortHits(hits);
144 //        Int_t nhits=0;
145 //        if (orderedcals) nhits=orderedcals->GetEntries();
146 //        for (Int_t i=0; i<nhits; i++)
147 //        {
148 //         AliSignal* sx=(AliSignal*)orderedcals->At(i);
149 //         if (sx) sx->Data();
150 //        }
151 //
152 // Build the event structure (vertices, jets, ...) for physics analysis
153 // based on the basic objects from the event repository.
154 //
155 //        AliJet j1,j2;
156 //        for (Int_t i=0; i<evt.GetNtracks(); i++)
157 //        {
158 //         tx=evt.GetTrack(i);
159 //         ...
160 //         ... // code to fill the jet data
161 //         ...
162 //        }
163 //
164 //        AliVertex vp;
165 //        tx=evt.GetTrack(1);
166 //        vp.AddTrack(tx);
167 //        tx=evt.GetTrack(2);
168 //        vp.AddTrack(tx);
169 //        tx=evt.GetTrack(3);
170 //        vp.AddTrack(tx);
171 //        tx=evt.GetTrack(4);
172 //        vp.AddTrack(tx);
173 //
174 //        Float_t rp[3]={2.4,0.1,-8.5};
175 //        vp.SetPosition(rp,"car");
176 //
177 //        AliVertex v1;
178 //        tx=evt.GetTrack(5);
179 //        v1.AddTrack(tx);
180 //        tx=evt.GetTrack(6);
181 //        v1.AddTrack(tx);
182 //        tx=evt.GetTrack(7);
183 //        v1.AddTrack(tx);
184 //
185 //        Float_t r1[3]={1.6,-3.2,5.7};
186 //        v1.SetPosition(r1,"car");
187 //
188 //
189 //        AliVertex v2;
190 //        v2.SetJetCopy(1);
191 //        v2.AddJet(j1);
192 //        v2.AddJet(j2);
193 //
194 //        Float_t r2[3]={6.2,4.8,1.3};
195 //        v2.SetPosition(r2,"car");
196 //
197 // Specify the vertices v1 and v2 as secondary vertices of the primary
198 //
199 //        vp.SetVertexCopy(1);
200 //        vp.AddVertex(v1);
201 //        vp.AddVertex(v2);
202 //
203 // Enter the physics structures into the event
204 //        evt.SetVertexCopy(1);
205 //        evt.AddVertex(vp,0);
206 //
207 // The jets j1 and j2 are already available via sec. vertex v2,
208 // but can be made available also from the event itself if desired.
209 //        AliJet* jx;
210 //        jx=v2.GetJet(1);
211 //        evt.AddJet(jx,0); 
212 //        jx=v2.GetJet(2);
213 //        evt.AddJet(jx,0); 
214 // 
215 //        evt.Data("sph");
216 //        v1.ListAll();
217 //        v2.List("cyl");
218 //
219 //        Float_t etot=evt.GetEnergy();
220 //        Ali3Vector ptot=evt.Get3Momentum();
221 //        Float_t loc[3];
222 //        evt.GetPosition(loc,"sph");
223 //        AliPosition r=v1.GetPosition();
224 //        r.Data(); 
225 //        Int_t nt=v2.GetNtracks();
226 //        AliTrack* tv=v2.GetTrack(1); // Access track number 1 of Vertex v2
227 //
228 //        evt.List();
229 //
230 //        Int_t nv=evt.GetNvtx();
231 //        AliVertex* vx=evt.GetVertex(1); // Access primary vertex
232 //        Float_t e=vx->GetEnergy();
233 //
234 //        Float_t M=evt.GetInvmass(); 
235 //
236 // Reconstruct the event from scratch
237 //
238 //        evt.Reset();
239 //        evt.SetNvmax(25); // Increase initial no. of sec. vertices
240 //        ...
241 //        ... // code to create tracks etc... 
242 //        ...
243 //
244 // Note : All quantities are in GeV, GeV/c or GeV/c**2
245 //
246 //--- Author: Nick van Eijndhoven 27-may-2001 UU-SAP Utrecht
247 //- Modified: NvE $Date: 2004/10/20 10:49:44 $ UU-SAP Utrecht
248 ///////////////////////////////////////////////////////////////////////////
249
250 #include "AliEvent.h"
251 #include "Riostream.h"
252  
253 ClassImp(AliEvent) // Class implementation to enable ROOT I/O
254  
255 AliEvent::AliEvent() : AliVertex(),AliTimestamp()
256 {
257 // Default constructor.
258 // All variables initialised to default values.
259  fRun=0;
260  fEvent=0;
261  fAproj=0;
262  fZproj=0;
263  fPnucProj=0;
264  fIdProj=0;
265  fAtarg=0;
266  fZtarg=0;
267  fPnucTarg=0;
268  fIdTarg=0;
269  fDevices=0;
270  fDevCopy=0;
271  fHits=0;
272  fOrdered=0;
273  fDisplay=0;
274  fDevs=0;
275 }
276 ///////////////////////////////////////////////////////////////////////////
277 AliEvent::AliEvent(Int_t n) : AliVertex(n),AliTimestamp()
278 {
279 // Create an event to hold initially a maximum of n tracks
280 // All variables initialised to default values
281  if (n<=0)
282  {
283   cout << " *** This AliVertex initialisation was invoked via the AliEvent ctor." << endl;
284  }
285  fRun=0;
286  fEvent=0;
287  fAproj=0;
288  fZproj=0;
289  fPnucProj=0;
290  fIdProj=0;
291  fAtarg=0;
292  fZtarg=0;
293  fPnucTarg=0;
294  fIdTarg=0;
295  fDevices=0;
296  fDevCopy=0;
297  fHits=0;
298  fOrdered=0;
299  fDisplay=0;
300  fDevs=0;
301 }
302 ///////////////////////////////////////////////////////////////////////////
303 AliEvent::~AliEvent()
304 {
305 // Default destructor
306  if (fDevices)
307  {
308   delete fDevices;
309   fDevices=0;
310  }
311  if (fHits)
312  {
313   delete fHits;
314   fHits=0;
315  }
316  if (fOrdered)
317  {
318   delete fOrdered;
319   fOrdered=0;
320  }
321  if (fDisplay)
322  {
323   delete fDisplay;
324   fDisplay=0;
325  }
326  if (fDevs)
327  {
328   delete fDevs;
329   fDevs=0;
330  }
331 }
332 ///////////////////////////////////////////////////////////////////////////
333 AliEvent::AliEvent(const AliEvent& evt) : AliVertex(evt),AliTimestamp(evt)
334 {
335 // Copy constructor.
336  fRun=evt.fRun;
337  fEvent=evt.fEvent;
338  fAproj=evt.fAproj;
339  fZproj=evt.fZproj;
340  fPnucProj=evt.fPnucProj;
341  fIdProj=evt.fIdProj;
342  fAtarg=evt.fAtarg;
343  fZtarg=evt.fZtarg;
344  fPnucTarg=evt.fPnucTarg;
345  fIdTarg=evt.fIdTarg;
346  fDevCopy=evt.fDevCopy;
347
348  fHits=0;
349  fOrdered=0;
350  fDisplay=0;
351  fDevs=0;
352
353  fDevices=0;
354  Int_t ndevs=evt.GetNdevices();
355  if (ndevs)
356  {
357   fDevices=new TObjArray(ndevs);
358   if (fDevCopy) fDevices->SetOwner();
359   for (Int_t i=1; i<=ndevs; i++)
360   {
361    TObject* dev=evt.GetDevice(i);
362    if (dev)
363    {
364     if (fDevCopy)
365     {
366      fDevices->Add(dev->Clone());
367     }
368     else
369     {
370      fDevices->Add(dev);
371     }
372    }
373   }
374  }
375 }
376 ///////////////////////////////////////////////////////////////////////////
377 void AliEvent::Reset()
378 {
379 // Reset all variables to default values
380 // The max. number of tracks is set to the initial value again
381 // The max. number of vertices is set to the default value again
382 // Note : The DevCopy mode is maintained as it was set by the user before.
383
384  AliVertex::Reset();
385
386  Set();
387  fRun=0;
388  fEvent=0;
389  fAproj=0;
390  fZproj=0;
391  fPnucProj=0;
392  fIdProj=0;
393  fAtarg=0;
394  fZtarg=0;
395  fPnucTarg=0;
396  fIdTarg=0;
397
398  if (fDevices)
399  {
400   delete fDevices;
401   fDevices=0;
402  }
403  if (fHits)
404  {
405   delete fHits;
406   fHits=0;
407  }
408  if (fOrdered)
409  {
410   delete fOrdered;
411   fOrdered=0;
412  }
413  if (fDisplay)
414  {
415   delete fDisplay;
416   fDisplay=0;
417  }
418  if (fDevs)
419  {
420   delete fDevs;
421   fDevs=0;
422  }
423 }
424 ///////////////////////////////////////////////////////////////////////////
425 void AliEvent::SetOwner(Bool_t own)
426 {
427 // Set ownership of all added objects. 
428 // The default parameter is own=kTRUE.
429 //
430 // Invokation of this memberfunction also sets all the copy modes
431 // (e.g. TrackCopy & co.) according to the value of own.
432 //
433 // This function (with own=kTRUE) is particularly useful when reading data
434 // from a tree/file, since Reset() will then actually remove all the
435 // added objects from memory irrespective of the copy mode settings
436 // during the tree/file creation process. In this way it provides a nice way
437 // of preventing possible memory leaks in the reading/analysis process.
438 //
439 // In addition this memberfunction can also be used as a shortcut to set all
440 // copy modes in one go during a tree/file creation process.
441 // However, in this case the user has to take care to only set/change the
442 // ownership (and copy mode) for empty objects (e.g. newly created objects
443 // or after invokation of the Reset() memberfunction) otherwise it will
444 // very likely result in inconsistent destructor behaviour.
445
446  Int_t mode=1;
447  if (!own) mode=0;
448  if (fDevices) fDevices->SetOwner(own);
449  fDevCopy=mode;
450
451  AliVertex::SetOwner(own);
452 }
453 ///////////////////////////////////////////////////////////////////////////
454 void AliEvent::SetDayTime(TTimeStamp& stamp)
455 {
456 // Set the date and time stamp for this event.
457 // An exact copy of the entered date/time stamp will be saved with an
458 // accuracy of 1 nanosecond.
459 //
460 // Note : Since the introduction of the more versatile class AliTimestamp
461 //        and the fact that AliEvent has now been derived from it,
462 //        this memberfunction has become obsolete.
463 //        It is recommended to use the corresponding AliTimestamp
464 //        functionality directly for AliEvent instances.
465 //        This memberfunction is only kept for backward compatibility.
466
467  Set(stamp.GetDate(),stamp.GetTime(),0,kTRUE,0);
468 }
469 ///////////////////////////////////////////////////////////////////////////
470 void AliEvent::SetDayTime(TDatime& stamp)
471 {
472 // Set the date and time stamp for this event.
473 // The entered date/time will be interpreted as being the local date/time
474 // and the accuracy is 1 second.
475 //
476 // This function with the TDatime argument is mainly kept for backward
477 // compatibility reasons.
478 // It is recommended to use the corresponding AliTimestamp functionality
479 // directly for AliEvent instances.
480
481  Set(stamp.GetDate(),stamp.GetTime(),0,kFALSE,0);
482 }
483 ///////////////////////////////////////////////////////////////////////////
484 void AliEvent::SetRunNumber(Int_t run)
485 {
486 // Set the run number for this event
487  fRun=run;
488 }
489 ///////////////////////////////////////////////////////////////////////////
490 void AliEvent::SetEventNumber(Int_t evt)
491 {
492 // Set the event number for this event
493  fEvent=evt;
494 }
495 ///////////////////////////////////////////////////////////////////////////
496 TTimeStamp AliEvent::GetDayTime() const
497 {
498 // Provide the date and time stamp for this event
499 //
500 // Note : Since the introduction of the more versatile class AliTimestamp
501 //        and the fact that AliEvent has now been derived from it,
502 //        this memberfunction has become obsolete.
503 //        It is recommended to use the corresponding AliTimestamp
504 //        functionality directly for AliEvent instances.
505 //        This memberfunction is only kept for backward compatibility.
506
507  return (TTimeStamp)(*this);
508 }
509 ///////////////////////////////////////////////////////////////////////////
510 Int_t AliEvent::GetRunNumber() const
511 {
512 // Provide the run number for this event
513  return fRun;
514 }
515 ///////////////////////////////////////////////////////////////////////////
516 Int_t AliEvent::GetEventNumber() const
517 {
518 // Provide the event number for this event
519  return fEvent;
520 }
521 ///////////////////////////////////////////////////////////////////////////
522 void AliEvent::SetProjectile(Int_t a,Int_t z,Double_t pnuc,Int_t id)
523 {
524 // Set the projectile A, Z, momentum per nucleon and user defined particle ID.
525 // By default the particle ID is set to zero.
526  fAproj=a;
527  fZproj=z;
528  fPnucProj=pnuc;
529  fIdProj=id;
530 }
531 ///////////////////////////////////////////////////////////////////////////
532 Int_t AliEvent::GetProjectileA() const
533 {
534 // Provide the projectile A value.
535  return fAproj;
536 }
537 ///////////////////////////////////////////////////////////////////////////
538 Int_t AliEvent::GetProjectileZ() const
539 {
540 // Provide the projectile Z value.
541  return fZproj;
542 }
543 ///////////////////////////////////////////////////////////////////////////
544 Double_t AliEvent::GetProjectilePnuc() const
545 {
546 // Provide the projectile momentum value per nucleon.
547  return fPnucProj;
548 }
549 ///////////////////////////////////////////////////////////////////////////
550 Int_t AliEvent::GetProjectileId() const
551 {
552 // Provide the user defined particle ID of the projectile.
553  return fIdProj;
554 }
555 ///////////////////////////////////////////////////////////////////////////
556 void AliEvent::SetTarget(Int_t a,Int_t z,Double_t pnuc,Int_t id)
557 {
558 // Set the target A, Z, momentum per nucleon and user defined particle ID.
559 // By default the particle ID is set to zero.
560  fAtarg=a;
561  fZtarg=z;
562  fPnucTarg=pnuc;
563  fIdTarg=id;
564 }
565 ///////////////////////////////////////////////////////////////////////////
566 Int_t AliEvent::GetTargetA() const
567 {
568 // Provide the target A value.
569  return fAtarg;
570 }
571 ///////////////////////////////////////////////////////////////////////////
572 Int_t AliEvent::GetTargetZ() const
573 {
574 // Provide the target Z value.
575  return fZtarg;
576 }
577 ///////////////////////////////////////////////////////////////////////////
578 Double_t AliEvent::GetTargetPnuc() const
579 {
580 // Provide the target momentum value per nucleon.
581  return fPnucTarg;
582 }
583 ///////////////////////////////////////////////////////////////////////////
584 Int_t AliEvent::GetTargetId() const
585 {
586 // Provide the user defined particle ID of the target.
587  return fIdTarg;
588 }
589 ///////////////////////////////////////////////////////////////////////////
590 void AliEvent::HeaderData()
591 {
592 // Provide event header information
593  const char* name=GetName();
594  const char* title=GetTitle();
595  cout << " *" << ClassName() << "::Data*";
596  if (strlen(name))  cout << " Name : " << GetName();
597  if (strlen(title)) cout << " Title : " << GetTitle();
598  cout << endl;
599  Date(1);
600  cout << "  Run : " << fRun << " Event : " << fEvent << endl;
601  ShowDevices(0);
602  ShowTracks(0);
603 }
604 ///////////////////////////////////////////////////////////////////////////
605 void AliEvent::Data(TString f,TString u)
606 {
607 // Provide event information within the coordinate frame f
608 //
609 // The string argument "u" allows to choose between different angular units
610 // in case e.g. a spherical frame is selected.
611 // u = "rad" : angles provided in radians
612 //     "deg" : angles provided in degrees
613 //
614 // The defaults are f="car" and u="rad".
615
616  HeaderData();
617  AliVertex::Data(f,u);
618
619 ///////////////////////////////////////////////////////////////////////////
620 Int_t AliEvent::GetNdevices() const
621 {
622 // Provide the number of stored devices
623  Int_t ndevs=0;
624  if (fDevices) ndevs=fDevices->GetEntries();
625  return ndevs;
626
627 ///////////////////////////////////////////////////////////////////////////
628 void AliEvent::AddDevice(TObject& d)
629 {
630 // Add a device to the event.
631 //
632 // Note :
633 // In case a private copy is made, this is performed via the Clone() memberfunction.
634 // All devices (i.e. classes derived from TObject) have the default TObject::Clone() 
635 // memberfunction.
636 // However, devices generally contain an internal (signal) data structure
637 // which may include pointers to other objects. Therefore it is recommended to provide
638 // for all devices a specific copy constructor and override the default Clone()
639 // memberfunction using this copy constructor.
640 // An example for this may be seen from AliCalorimeter.   
641
642  if (!fDevices)
643  {
644   fDevices=new TObjArray();
645   if (fDevCopy) fDevices->SetOwner();
646  }
647  
648  // Add the device to this event
649  if (fDevCopy)
650  {
651   fDevices->Add(d.Clone());
652  }
653  else
654  {
655   fDevices->Add(&d);
656  }
657 }
658 ///////////////////////////////////////////////////////////////////////////
659 void AliEvent::SetDevCopy(Int_t j)
660 {
661 // (De)activate the creation of private copies of the added devices.
662 // j=0 ==> No private copies are made; pointers of original devices are stored.
663 // j=1 ==> Private copies of the devices are made and these pointers are stored.
664 //
665 //
666 // Notes :
667 //  In case a private copy is made, this is performed via the Clone() memberfunction.
668 //  All devices (i.e. classes derived from TObject) have the default TObject::Clone() 
669 //  memberfunction.
670 //  However, devices generally contain an internal (signal) data structure
671 //  which may include pointers to other objects. Therefore it is recommended to provide
672 //  for all devices a specific copy constructor and override the default Clone()
673 //  memberfunction using this copy constructor.
674 //  An example for this may be seen from AliCalorimeter.   
675 //
676 //  Once the storage contains pointer(s) to device(s) one cannot
677 //  change the DevCopy mode anymore.
678 //  To change the DevCopy mode for an existing AliEvent containing
679 //  devices one first has to invoke Reset().
680
681  if (!fDevices)
682  {
683   if (j==0 || j==1)
684   {
685    fDevCopy=j;
686   }
687   else
688   {
689    cout << " *" << ClassName() << "::SetDevCopy* Invalid argument : " << j << endl;
690   }
691  }
692  else
693  {
694   cout << " *" << ClassName() << "::SetDevCopy* Storage already contained devices."
695        << "  ==> DevCopy mode not changed." << endl; 
696  }
697 }
698 ///////////////////////////////////////////////////////////////////////////
699 Int_t AliEvent::GetDevCopy() const
700 {
701 // Provide value of the DevCopy mode.
702 // 0 ==> No private copies are made; pointers of original devices are stored.
703 // 1 ==> Private copies of the devices are made and these pointers are stored.
704 //
705 // Note :
706 // In case a private copy is made, this is performed via the Clone() memberfunction.
707 // All devices (i.e. classes derived from TObject) have the default TObject::Clone() 
708 // memberfunction.
709 // However, devices generally contain an internal (signal) data structure
710 // which may include pointers to other objects. Therefore it is recommended to provide
711 // for all devices a specific copy constructor and override the default Clone()
712 // memberfunction using this copy constructor.
713 // An example for this may be seen from AliCalorimeter.   
714
715  return fDevCopy;
716 }
717 ///////////////////////////////////////////////////////////////////////////
718 TObject* AliEvent::GetDevice(Int_t i) const
719 {
720 // Return the i-th device of this event.
721 // The first device corresponds to i=1.
722
723  if (!fDevices)
724  {
725   return 0;
726  }
727  else
728  {
729   Int_t ndevs=GetNdevices();
730   if (i<=0 || i>ndevs)
731   {
732    cout << " *" << ClassName() << "::GetDevice* Invalid argument i : " << i
733         << " ndevs = " << ndevs << endl;
734    return 0;
735   }
736   else
737   {
738    return fDevices->At(i-1);
739   }
740  }
741 }
742 ///////////////////////////////////////////////////////////////////////////
743 TObject* AliEvent::GetDevice(TString name) const
744 {
745 // Return the device with name tag "name"
746  if (!fDevices)
747  {
748   return 0;
749  }
750  else
751  {
752   TString s;
753   Int_t ndevs=GetNdevices();
754   for (Int_t i=0; i<ndevs; i++)
755   {
756    TObject* dev=fDevices->At(i);
757    if (dev)
758    {
759     s=dev->GetName();
760     if (s == name) return dev;
761    }
762   }
763
764   return 0; // No matching name found
765  }
766 }
767 ///////////////////////////////////////////////////////////////////////////
768 TObject* AliEvent::GetIdDevice(Int_t id) const
769 {
770 // Return the device with unique identifier "id".
771  if (!fDevices || id<0) return 0;
772
773  Int_t idx=0;
774  for (Int_t i=0; i<GetNdevices(); i++)
775  {
776   TObject* dev=fDevices->At(i);
777   if (dev)
778   {
779    idx=dev->GetUniqueID();
780    if (idx==id) return dev;
781   }
782  }
783  return 0; // No matching id found
784 }
785 ///////////////////////////////////////////////////////////////////////////
786 void AliEvent::ShowDevices(Int_t mode) const
787 {
788 // Provide an overview of the available devices.
789 // The argument mode determines the amount of information as follows :
790 // mode = 0 ==> Only printout of the number of devices
791 //        1 ==> Provide a listing with 1 line of info for each device
792 //
793 // The default is mode=1.
794 //
795  Int_t ndevs=GetNdevices();
796  if (ndevs)
797  {
798   if (!mode)
799   {
800    cout << " There are " << ndevs << " devices available." << endl; 
801   }
802   else
803   {
804    cout << " The following " << ndevs << " devices are available :" << endl; 
805    for (Int_t i=1; i<=ndevs; i++)
806    {
807     TObject* dev=GetDevice(i);
808     if (dev)
809     {
810      const char* name=dev->GetName();
811      cout << " Device number : " << i;
812      cout << " Class : " << dev->ClassName() << " Id : " << dev->GetUniqueID();
813      if (strlen(name)) cout << " Name : " << name;
814      if (dev->InheritsFrom("AliDevice")) cout << " Nhits : " << ((AliDevice*)dev)->GetNhits();
815      if (dev->InheritsFrom("AliSignal")) cout << " Nwaveforms : " << ((AliSignal*)dev)->GetNwaveforms();
816      cout << endl;
817     }
818    }
819   }
820  }
821  else
822  {
823   cout << " No devices present for this event." << endl;
824  }
825 }
826 ///////////////////////////////////////////////////////////////////////////
827 TObjArray* AliEvent::GetDevices(const char* classname)
828 {
829 // Provide the references to the various devices derived from the
830 // specified class.
831  if (fDevs) fDevs->Clear();
832
833  Int_t ndev=GetNdevices();
834  for (Int_t idev=1; idev<=ndev; idev++)
835  {
836   TObject* obj=GetDevice(idev);
837   if (!obj) continue;
838
839   if (obj->InheritsFrom(classname))
840   {
841    if (!fDevs) fDevs=new TObjArray();
842    fDevs->Add(obj);
843   }
844  }
845  return fDevs;
846 }
847 ///////////////////////////////////////////////////////////////////////////
848 Int_t AliEvent::GetNhits(const char* classname)
849 {
850 // Provide the number of hits registered to the specified device class.
851 // The specified device class has to be derived from AliDevice.
852 // It is possible to indicate with the argument "classname" a specific
853 // device instead of a whole class of devices. However, in such a case
854 // it is more efficient to use the GetDevice() memberfunction directly.
855  LoadHits(classname);
856  Int_t nhits=0;
857  if (fHits) nhits=fHits->GetEntries();
858  return nhits;
859 }
860 ///////////////////////////////////////////////////////////////////////////
861 TObjArray* AliEvent::GetHits(const char* classname)
862 {
863 // Provide the references to all the hits registered to the specified
864 // device class.
865 // The specified device class has to be derived from AliDevice.
866 // It is possible to indicate with the argument "classname" a specific
867 // device instead of a whole class of devices. However, in such a case
868 // it is more efficient to use the GetDevice() memberfunction directly.
869  LoadHits(classname);
870  return fHits;
871 }
872 ///////////////////////////////////////////////////////////////////////////
873 AliSignal* AliEvent::GetIdHit(Int_t id,const char* classname)
874 {
875 // Return the hit with unique identifier "id" for the specified device class.
876  if (id<0) return 0;
877
878  Int_t nhits=GetNhits(classname);
879  if (!nhits) return 0;
880
881  AliSignal* sx=0;
882  Int_t sid=0;
883  for (Int_t i=0; i<nhits; i++)
884  {
885   sx=(AliSignal*)fHits->At(i);
886   if (sx)
887   {
888    sid=sx->GetUniqueID();
889    if (id==sid) return sx;
890   }
891  }
892  return 0; // No matching id found
893 }
894 ///////////////////////////////////////////////////////////////////////////
895 void AliEvent::LoadHits(const char* classname)
896 {
897 // Load the references to the various hits registered to the specified
898 // device class.
899 // The specified device class has to be derived from AliDevice.
900  if (fHits) fHits->Clear();
901
902  Int_t ndev=GetNdevices();
903  for (Int_t idev=1; idev<=ndev; idev++)
904  {
905   TObject* obj=GetDevice(idev);
906   if (!obj) continue;
907
908   if (obj->InheritsFrom(classname) && obj->InheritsFrom("AliDevice"))
909   {
910    AliDevice* dev=(AliDevice*)GetDevice(idev);
911    Int_t nhits=dev->GetNhits();
912    if (nhits)
913    {
914     if (!fHits) fHits=new TObjArray();
915     for (Int_t ih=1; ih<=nhits; ih++)
916     {
917      AliSignal* sx=dev->GetHit(ih);
918      if (sx) fHits->Add(sx);
919     }
920    }
921   }
922  }
923 }
924 ///////////////////////////////////////////////////////////////////////////
925 TObjArray* AliEvent::SortHits(const char* classname,Int_t idx,Int_t mode,Int_t mcal)
926 {
927 // Order the references to the various hits registered to the specified
928 // device class. The ordered array is returned as a TObjArray.
929 // A "hit" represents an abstract object which is derived from AliSignal.
930 // The user can specify the index of the signal slot to perform the sorting on.
931 // By default the slotindex will be 1.
932 // Via the "mode" argument the user can specify ordering in decreasing
933 // order (mode=-1) or ordering in increasing order (mode=1).
934 // The default is mode=-1.
935 // Signals which were declared as "Dead" will be rejected.
936 // The gain etc... corrected signals will be used in the ordering process as
937 // specified by the "mcal" argument. The definition of this "mcal" parameter
938 // corresponds to the signal correction mode described in the GetSignal
939 // memberfunction of class AliSignal.
940 // The default is mcal=1 (for backward compatibility reasons).
941 //
942 // For more extended functionality see class AliDevice.
943
944  if (idx<=0 || abs(mode)!=1) return 0;
945
946  LoadHits(classname);
947
948  AliDevice dev;
949  TObjArray* ordered=dev.SortHits(idx,mode,fHits,mcal);
950
951  if (fHits)
952  {
953   delete fHits;
954   fHits=0;
955  } 
956  if (ordered) fHits=new TObjArray(*ordered);
957  return fHits;
958 }
959 ///////////////////////////////////////////////////////////////////////////
960 TObjArray* AliEvent::SortHits(const char* classname,TString name,Int_t mode,Int_t mcal)
961 {
962 // Order the references to the various hits registered to the specified
963 // device class. The ordered array is returned as a TObjArray.
964 // A "hit" represents an abstract object which is derived from AliSignal.
965 // The user can specify the name of the signal slot to perform the sorting on.
966 // In case no matching slotname is found, the signal will be skipped.
967 // Via the "mode" argument the user can specify ordering in decreasing
968 // order (mode=-1) or ordering in increasing order (mode=1).
969 // The default is mode=-1.
970 // Signals which were declared as "Dead" will be rejected.
971 // The gain etc... corrected signals will be used in the ordering process as
972 // specified by the "mcal" argument. The definition of this "mcal" parameter
973 // corresponds to the signal correction mode described in the GetSignal
974 // memberfunction of class AliSignal.
975 // The default is mcal=1 (for backward compatibility reasons).
976 //
977 // For more extended functionality see class AliDevice.
978  
979  if (abs(mode)!=1) return 0;
980
981  LoadHits(classname);
982
983  AliDevice dev;
984  TObjArray* ordered=dev.SortHits(name,mode,fHits,mcal);
985
986  if (fHits)
987  {
988   delete fHits;
989   fHits=0;
990  } 
991  if (ordered) fHits=new TObjArray(*ordered);
992  return fHits;
993 }
994 ///////////////////////////////////////////////////////////////////////////
995 void AliEvent::GetExtremes(const char* classname,Float_t& vmin,Float_t& vmax,Int_t idx,Int_t mode)
996 {
997 // Provide the min. and max. signal values of the various hits registered
998 // to the specified device class.
999 // The input argument "idx" denotes the index of the signal slots to be investigated.
1000 // The default is idx=1;
1001 // Signals which were declared as "Dead" will be rejected.
1002 // The gain etc... corrected signals will be used in the process as specified
1003 // by the  "mode" argument. The definition of this "mode" parameter corresponds to
1004 // the description provided in the GetSignal memberfunction of class AliSignal.
1005 // The default is mode=1 (for backward compatibility reasons).
1006 //
1007 // For more extended functionality see class AliDevice.
1008
1009  if (idx<=0) return;
1010
1011  LoadHits(classname);
1012
1013  AliDevice dev;
1014  dev.GetExtremes(vmin,vmax,idx,fHits,mode);
1015 }
1016 ///////////////////////////////////////////////////////////////////////////
1017 void AliEvent::GetExtremes(const char* classname,Float_t& vmin,Float_t& vmax,TString name,Int_t mode)
1018 {
1019 // Provide the min. and max. signal values of the various hits registered
1020 // to the specified device class.
1021 // The input argument "name" denotes the name of the signal slots to be investigated.
1022 // Signals which were declared as "Dead" will be rejected.
1023 // The gain etc... corrected signals will be used in the process as specified
1024 // by the  "mode" argument. The definition of this "mode" parameter corresponds to
1025 // the description provided in the GetSignal memberfunction of class AliSignal.
1026 // The default is mode=1 (for backward compatibility reasons).
1027 //
1028 // For more extended functionality see class AliDevice.
1029
1030  LoadHits(classname);
1031
1032  AliDevice dev;
1033  dev.GetExtremes(vmin,vmax,name,fHits,mode);
1034 }
1035 ///////////////////////////////////////////////////////////////////////////
1036 void AliEvent::DisplayHits(const char* classname,Int_t idx,Float_t scale,Int_t dp,Int_t mode,Int_t mcol)
1037 {
1038 // 3D color display of the various hits registered to the specified device class.
1039 // The user can specify the index (default=1) of the signal slot to perform the display for.
1040 // The marker size will indicate the absolute value of the signal (specified by the slotindex)
1041 // as a percentage of the input argument "scale".
1042 // In case scale<0 the maximum absolute signal value encountered in the hit array will be used
1043 // to define the 100% scale. The default is scale=-1.
1044 // In case dp=1 the owning device position will be used, otherwise the hit position will
1045 // be used in the display. The default is dp=0.
1046 // Via the "mcol" argument the user can specify the marker color (see TPolyMarker3D).
1047 // The default is mcol=blue.
1048 // Signals which were declared as "Dead" will not be displayed.
1049 // The gain etc... corrected signals will be used to determine the marker size.
1050 // The gain correction is performed according to "mode" argument. The definition of this
1051 // "mode" parameter corresponds to the description provided in the GetSignal
1052 // memberfunction of class AliSignal.
1053 // The default is mode=1 (for backward compatibility reasons).
1054 //
1055 // For more extended functionality see class AliDevice.
1056 //
1057 // Note :
1058 // ------
1059 // Before any display activity, a TCanvas and a TView have to be initiated
1060 // first by the user like for instance
1061 // 
1062 // TCanvas* c1=new TCanvas("c1","c1");
1063 // TView* view=new TView(1);
1064 // view->SetRange(-1000,-1000,-1000,1000,1000,1000);
1065 // view->ShowAxis();
1066
1067  if (idx<=0) return;
1068
1069  LoadHits(classname);
1070
1071  AliDevice* dev=new AliDevice();
1072  dev->DisplayHits(idx,scale,fHits,dp,mode,mcol);
1073
1074  if (fDisplay)
1075  {
1076   delete fDisplay;
1077   fDisplay=0;
1078  }
1079  fDisplay=dev;
1080 }
1081 ///////////////////////////////////////////////////////////////////////////
1082 void AliEvent::DisplayHits(const char* classname,TString name,Float_t scale,Int_t dp,Int_t mode,Int_t mcol)
1083 {
1084 // 3D color display of the various hits registered to the specified device class.
1085 // The user can specify the name of the signal slot to perform the display for.
1086 // The marker size will indicate the absolute value of the signal (specified by the slotname)
1087 // as a percentage of the input argument "scale".
1088 // In case scale<0 the maximum absolute signal value encountered in the hit array will be used
1089 // to define the 100% scale. The default is scale=-1.
1090 // In case dp=1 the owning device position will be used, otherwise the hit position will
1091 // be used in the display. The default is dp=0.
1092 // The marker size will indicate the percentage of the maximum encountered value
1093 // of the absolute value of the name-specified input signal slots.
1094 // Via the "mcol" argument the user can specify the marker color (see TPolyMarker3D).
1095 // The default is mcol=blue.
1096 // Signals which were declared as "Dead" will not be displayed.
1097 // The gain etc... corrected signals will be used to determine the marker size.
1098 // The gain correction is performed according to "mode" argument. The definition of this
1099 // "mode" parameter corresponds to the description provided in the GetSignal
1100 // memberfunction of class AliSignal.
1101 // The default is mode=1 (for backward compatibility reasons).
1102 //
1103 // For more extended functionality see class AliDevice.
1104 //
1105 // Note :
1106 // ------
1107 // Before any display activity, a TCanvas and a TView have to be initiated
1108 // first by the user like for instance
1109 // 
1110 // TCanvas* c1=new TCanvas("c1","c1");
1111 // TView* view=new TView(1);
1112 // view->SetRange(-1000,-1000,-1000,1000,1000,1000);
1113 // view->ShowAxis();
1114
1115  LoadHits(classname);
1116
1117  AliDevice* dev=new AliDevice();
1118  dev->DisplayHits(name,scale,fHits,dp,mode,mcol);
1119
1120  if (fDisplay)
1121  {
1122   delete fDisplay;
1123   fDisplay=0;
1124  }
1125  fDisplay=dev;
1126 }
1127 ///////////////////////////////////////////////////////////////////////////
1128 TObjArray* AliEvent::SortDevices(const char* classname,TString name,Int_t mode,Int_t mcal)
1129 {
1130 // Order the references to the various devices based on hit signals registered
1131 // to the specified device class. The ordered array is returned as a TObjArray.
1132 // A "hit" represents an abstract object which is derived from AliSignal.
1133 // The user can specify the name of the signal slot to perform the sorting on.
1134 // In case no matching slotname is found, the signal will be skipped.
1135 // Via the "mode" argument the user can specify ordering in decreasing
1136 // order (mode=-1) or ordering in increasing order (mode=1).
1137 // The default is mode=-1.
1138 // Signals which were declared as "Dead" will be rejected.
1139 // The gain etc... corrected signals will be used in the ordering process as
1140 // specified by the "mcal" argument. The definition of this "mcal" parameter
1141 // corresponds to the signal correction mode described in the GetSignal
1142 // memberfunction of class AliSignal.
1143 // The default is mcal=1 (for backward compatibility reasons).
1144 //
1145
1146  TObjArray* ordered=SortHits(classname,name,mode,mcal);
1147  
1148  if (!ordered) return 0;
1149
1150  TObjArray* devs=SortDevices(ordered,"*",0,mcal);
1151  return devs;
1152 }
1153 ///////////////////////////////////////////////////////////////////////////
1154 TObjArray* AliEvent::SortDevices(const char* classname,Int_t idx,Int_t mode,Int_t mcal)
1155 {
1156 // Order the references to the various devices based on hit signals registered
1157 // to the specified device class. The ordered array is returned as a TObjArray.
1158 // A "hit" represents an abstract object which is derived from AliSignal.
1159 // The user can specify the index of the signal slot to perform the sorting on.
1160 // By default the slotindex will be 1.
1161 // Via the "mode" argument the user can specify ordering in decreasing
1162 // order (mode=-1) or ordering in increasing order (mode=1).
1163 // The default is mode=-1.
1164 // Signals which were declared as "Dead" will be rejected.
1165 // The gain etc... corrected signals will be used in the ordering process as
1166 // specified by the "mcal" argument. The definition of this "mcal" parameter
1167 // corresponds to the signal correction mode described in the GetSignal
1168 // memberfunction of class AliSignal.
1169 // The default is mcal=1 (for backward compatibility reasons).
1170 //
1171
1172  TObjArray* ordered=SortHits(classname,idx,mode,mcal);
1173  
1174  if (!ordered) return 0;
1175
1176  TObjArray* devs=SortDevices(ordered,0,0,mcal);
1177  return devs;
1178 }
1179 ///////////////////////////////////////////////////////////////////////////
1180 TObjArray* AliEvent::SortDevices(TObjArray* hits,TString name,Int_t mode,Int_t mcal)
1181 {
1182 // Order the references to the various devices based on hit signals contained
1183 // in the input array. The ordered array is returned as a TObjArray.
1184 // A "hit" represents an abstract object which is derived from AliSignal.
1185 // The user can specify the name of the signal slot to perform the sorting on.
1186 // In case no matching slotname is found, the signal will be skipped.
1187 // Via the "mode" argument the user can specify ordering in decreasing
1188 // order (mode=-1), ordering in increasing order (mode=1) or no ordering (mode=0).
1189 // The latter option provides a means to quickly obtain an ordered devices list
1190 // when the hits in the array were already ordered by the user. In this case
1191 // the input argument "name" is irrelevant.
1192 // The default is mode=-1.
1193 // Signals which were declared as "Dead" will be rejected.
1194 // The gain etc... corrected signals will be used in the ordering process as
1195 // specified by the "mcal" argument. The definition of this "mcal" parameter
1196 // corresponds to the signal correction mode described in the GetSignal
1197 // memberfunction of class AliSignal.
1198 // The default is mcal=1 (for backward compatibility reasons).
1199 //
1200
1201  if (!hits) return 0;
1202
1203  TObjArray* ordered=hits;
1204  AliDevice dev;
1205  if (mode) ordered=dev.SortHits(name,mode,hits,mcal);
1206  
1207  if (!ordered) return 0;
1208
1209  if (fOrdered)
1210  {
1211   fOrdered->Clear();
1212  }
1213  else
1214  {
1215   fOrdered=new TObjArray();
1216  }
1217
1218  Int_t nhits=ordered->GetEntries();
1219  Int_t exist=0;
1220  for (Int_t ih=0; ih<nhits; ih++)
1221  {
1222   AliSignal* sx=(AliSignal*)ordered->At(ih);
1223   if (!sx) continue;
1224   AliDevice* dx=sx->GetDevice();
1225   exist=0;
1226   for (Int_t id=0; id<fOrdered->GetEntries(); id++)
1227   {
1228    AliDevice* odx=(AliDevice*)fOrdered->At(id);
1229    if (dx==odx)
1230    {
1231     exist=1;
1232     break;
1233    }
1234   }
1235   if (!exist) fOrdered->Add(dx);
1236  }
1237  return fOrdered;
1238 }
1239 ///////////////////////////////////////////////////////////////////////////
1240 TObjArray* AliEvent::SortDevices(TObjArray* hits,Int_t idx,Int_t mode,Int_t mcal)
1241 {
1242 // Order the references to the various devices based on hit signals contained
1243 // in the input array. The ordered array is returned as a TObjArray.
1244 // A "hit" represents an abstract object which is derived from AliSignal.
1245 // The user can specify the index of the signal slot to perform the sorting on.
1246 // By default the slotindex will be 1.
1247 // Via the "mode" argument the user can specify ordering in decreasing
1248 // order (mode=-1), ordering in increasing order (mode=1) or no ordering (mode=0).
1249 // The latter option provides a means to quickly obtain an ordered devices list
1250 // when the hits in the array were already ordered by the user. In this case
1251 // the input argument "idx" is irrelevant.
1252 // The default is mode=-1.
1253 // Signals which were declared as "Dead" will be rejected.
1254 // The gain etc... corrected signals will be used in the ordering process as
1255 // specified by the "mcal" argument. The definition of this "mcal" parameter
1256 // corresponds to the signal correction mode described in the GetSignal
1257 // memberfunction of class AliSignal.
1258 // The default is mcal=1 (for backward compatibility reasons).
1259 //
1260
1261  if (!hits) return 0;
1262
1263  TObjArray* ordered=hits;
1264  AliDevice dev;
1265  if (mode) ordered=dev.SortHits(idx,mode,hits,mcal);
1266  
1267  if (!ordered) return 0;
1268
1269  if (fOrdered)
1270  {
1271   fOrdered->Clear();
1272  }
1273  else
1274  {
1275   fOrdered=new TObjArray();
1276  }
1277
1278  Int_t nhits=ordered->GetEntries();
1279  Int_t exist=0;
1280  for (Int_t ih=0; ih<nhits; ih++)
1281  {
1282   AliSignal* sx=(AliSignal*)ordered->At(ih);
1283   if (!sx) continue;
1284   AliDevice* dx=sx->GetDevice();
1285   exist=0;
1286   for (Int_t id=0; id<fOrdered->GetEntries(); id++)
1287   {
1288    AliDevice* odx=(AliDevice*)fOrdered->At(id);
1289    if (dx==odx)
1290    {
1291     exist=1;
1292     break;
1293    }
1294   }
1295   if (!exist) fOrdered->Add(dx);
1296  }
1297  return fOrdered;
1298 }
1299 ///////////////////////////////////////////////////////////////////////////
1300 TObject* AliEvent::Clone(const char* name) const
1301 {
1302 // Make a deep copy of the current object and provide the pointer to the copy.
1303 // This memberfunction enables automatic creation of new objects of the
1304 // correct type depending on the object type, a feature which may be very useful
1305 // for containers when adding objects in case the container owns the objects.
1306 // This feature allows to store either AliEvent objects or objects derived from
1307 // AliEvent via some generic AddEvent memberfunction, provided these derived
1308 // classes also have a proper Clone memberfunction. 
1309
1310  AliEvent* evt=new AliEvent(*this);
1311  if (name)
1312  {
1313   if (strlen(name)) evt->SetName(name);
1314  }
1315  return evt;
1316 }
1317 ///////////////////////////////////////////////////////////////////////////
1318