]> git.uio.no Git - u/mrichter/AliRoot.git/blob - RALICE/AliEvent.cxx
Overlaps 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 : By default all quantities are in meter, GeV, GeV/c or GeV/c**2
245 //        but the user can indicate the usage of a different scale for
246 //        the metric and/or energy-momentum units via the SetUnitScale()
247 //        and SetEscale() memberfunctions, respectively.
248 //        The actual metric and energy-momentum unit scales in use can be
249 //        obtained via the GetUnitScale() and GetEscale() memberfunctions.
250 //
251 //--- Author: Nick van Eijndhoven 27-may-2001 UU-SAP Utrecht
252 //- Modified: NvE $Date: 2004/10/20 10:49:44 $ UU-SAP Utrecht
253 ///////////////////////////////////////////////////////////////////////////
254
255 #include "AliEvent.h"
256 #include "Riostream.h"
257  
258 ClassImp(AliEvent) // Class implementation to enable ROOT I/O
259  
260 AliEvent::AliEvent() : AliVertex(),AliTimestamp()
261 {
262 // Default constructor.
263 // All variables initialised to default values.
264  fRun=0;
265  fEvent=0;
266  fDevices=0;
267  fDevCopy=0;
268  fHits=0;
269  fOrdered=0;
270  fDisplay=0;
271  fDevs=0;
272 }
273 ///////////////////////////////////////////////////////////////////////////
274 AliEvent::AliEvent(Int_t n) : AliVertex(n),AliTimestamp()
275 {
276 // Create an event to hold initially a maximum of n tracks
277 // All variables initialised to default values
278  if (n<=0)
279  {
280   cout << " *** This AliVertex initialisation was invoked via the AliEvent ctor." << endl;
281  }
282  fRun=0;
283  fEvent=0;
284  fDevices=0;
285  fDevCopy=0;
286  fHits=0;
287  fOrdered=0;
288  fDisplay=0;
289  fDevs=0;
290 }
291 ///////////////////////////////////////////////////////////////////////////
292 AliEvent::~AliEvent()
293 {
294 // Default destructor
295  if (fDevices)
296  {
297   delete fDevices;
298   fDevices=0;
299  }
300  if (fHits)
301  {
302   delete fHits;
303   fHits=0;
304  }
305  if (fOrdered)
306  {
307   delete fOrdered;
308   fOrdered=0;
309  }
310  if (fDisplay)
311  {
312   delete fDisplay;
313   fDisplay=0;
314  }
315  if (fDevs)
316  {
317   delete fDevs;
318   fDevs=0;
319  }
320 }
321 ///////////////////////////////////////////////////////////////////////////
322 AliEvent::AliEvent(const AliEvent& evt) : AliVertex(evt),AliTimestamp(evt)
323 {
324 // Copy constructor.
325  fRun=evt.fRun;
326  fEvent=evt.fEvent;
327  fDevCopy=evt.fDevCopy;
328
329  fHits=0;
330  fOrdered=0;
331  fDisplay=0;
332  fDevs=0;
333
334  fDevices=0;
335  Int_t ndevs=evt.GetNdevices();
336  if (ndevs)
337  {
338   fDevices=new TObjArray(ndevs);
339   if (fDevCopy) fDevices->SetOwner();
340   for (Int_t i=1; i<=ndevs; i++)
341   {
342    TObject* dev=evt.GetDevice(i);
343    if (dev)
344    {
345     if (fDevCopy)
346     {
347      fDevices->Add(dev->Clone());
348     }
349     else
350     {
351      fDevices->Add(dev);
352     }
353    }
354   }
355  }
356 }
357 ///////////////////////////////////////////////////////////////////////////
358 void AliEvent::Reset()
359 {
360 // Reset all variables to default values
361 // The max. number of tracks is set to the initial value again
362 // The max. number of vertices is set to the default value again
363 // Note : The DevCopy mode is maintained as it was set by the user before.
364
365  AliVertex::Reset();
366
367  Set();
368  fRun=0;
369  fEvent=0;
370
371  if (fDevices)
372  {
373   delete fDevices;
374   fDevices=0;
375  }
376  if (fHits)
377  {
378   delete fHits;
379   fHits=0;
380  }
381  if (fOrdered)
382  {
383   delete fOrdered;
384   fOrdered=0;
385  }
386  if (fDisplay)
387  {
388   delete fDisplay;
389   fDisplay=0;
390  }
391  if (fDevs)
392  {
393   delete fDevs;
394   fDevs=0;
395  }
396 }
397 ///////////////////////////////////////////////////////////////////////////
398 void AliEvent::SetOwner(Bool_t own)
399 {
400 // Set ownership of all added objects. 
401 // The default parameter is own=kTRUE.
402 //
403 // Invokation of this memberfunction also sets all the copy modes
404 // (e.g. TrackCopy & co.) according to the value of own.
405 //
406 // This function (with own=kTRUE) is particularly useful when reading data
407 // from a tree/file, since Reset() will then actually remove all the
408 // added objects from memory irrespective of the copy mode settings
409 // during the tree/file creation process. In this way it provides a nice way
410 // of preventing possible memory leaks in the reading/analysis process.
411 //
412 // In addition this memberfunction can also be used as a shortcut to set all
413 // copy modes in one go during a tree/file creation process.
414 // However, in this case the user has to take care to only set/change the
415 // ownership (and copy mode) for empty objects (e.g. newly created objects
416 // or after invokation of the Reset() memberfunction) otherwise it will
417 // very likely result in inconsistent destructor behaviour.
418
419  Int_t mode=1;
420  if (!own) mode=0;
421  if (fDevices) fDevices->SetOwner(own);
422  fDevCopy=mode;
423
424  AliVertex::SetOwner(own);
425 }
426 ///////////////////////////////////////////////////////////////////////////
427 void AliEvent::SetDayTime(TTimeStamp& stamp)
428 {
429 // Set the date and time stamp for this event.
430 // An exact copy of the entered date/time stamp will be saved with an
431 // accuracy of 1 nanosecond.
432 //
433 // Note : Since the introduction of the more versatile class AliTimestamp
434 //        and the fact that AliEvent has now been derived from it,
435 //        this memberfunction has become obsolete.
436 //        It is recommended to use the corresponding AliTimestamp
437 //        functionality directly for AliEvent instances.
438 //        This memberfunction is only kept for backward compatibility.
439
440  Set(stamp.GetDate(),stamp.GetTime(),0,kTRUE,0);
441 }
442 ///////////////////////////////////////////////////////////////////////////
443 void AliEvent::SetDayTime(TDatime& stamp)
444 {
445 // Set the date and time stamp for this event.
446 // The entered date/time will be interpreted as being the local date/time
447 // and the accuracy is 1 second.
448 //
449 // This function with the TDatime argument is mainly kept for backward
450 // compatibility reasons.
451 // It is recommended to use the corresponding AliTimestamp functionality
452 // directly for AliEvent instances.
453
454  Set(stamp.GetDate(),stamp.GetTime(),0,kFALSE,0);
455 }
456 ///////////////////////////////////////////////////////////////////////////
457 void AliEvent::SetRunNumber(Int_t run)
458 {
459 // Set the run number for this event
460  fRun=run;
461 }
462 ///////////////////////////////////////////////////////////////////////////
463 void AliEvent::SetEventNumber(Int_t evt)
464 {
465 // Set the event number for this event
466  fEvent=evt;
467 }
468 ///////////////////////////////////////////////////////////////////////////
469 TTimeStamp AliEvent::GetDayTime() const
470 {
471 // Provide the date and time stamp for this event
472 //
473 // Note : Since the introduction of the more versatile class AliTimestamp
474 //        and the fact that AliEvent has now been derived from it,
475 //        this memberfunction has become obsolete.
476 //        It is recommended to use the corresponding AliTimestamp
477 //        functionality directly for AliEvent instances.
478 //        This memberfunction is only kept for backward compatibility.
479
480  return (TTimeStamp)(*this);
481 }
482 ///////////////////////////////////////////////////////////////////////////
483 Int_t AliEvent::GetRunNumber() const
484 {
485 // Provide the run number for this event
486  return fRun;
487 }
488 ///////////////////////////////////////////////////////////////////////////
489 Int_t AliEvent::GetEventNumber() const
490 {
491 // Provide the event number for this event
492  return fEvent;
493 }
494 ///////////////////////////////////////////////////////////////////////////
495 void AliEvent::SetProjectile(Int_t a,Int_t z,Double_t pnuc,Int_t id)
496 {
497 // Set the projectile A, Z, momentum per nucleon and user defined particle ID.
498 // If not explicitly specified by the user, the projectile particle ID is set
499 // to zero by default and will not be stored in the event structure.
500 // The projectile specifications will be stored in a device named "Beam"
501 // which is an instance of AliSignal.
502 // As such these data are easily retrievable from the event structure.
503 // However, for backward compatibility reasons the beam data can also be
504 // retrieved via memberfunctions like GetProjectileA() etc...
505
506  Int_t newdev=0;
507  
508  AliSignal* beam=(AliSignal*)GetDevice("Beam");
509  
510  if (!beam)
511  {
512   beam=new AliSignal();
513   beam->SetNameTitle("Beam","Beam and target specifications");
514   newdev=1;
515  }
516
517  if (a || z)
518  {
519   beam->AddNamedSlot("Aproj");
520   beam->SetSignal(a,"Aproj");
521   beam->AddNamedSlot("Zproj");
522   beam->SetSignal(z,"Zproj");
523  }
524  beam->AddNamedSlot("Pnucproj");
525  beam->SetSignal(pnuc,"Pnucproj");
526  if (id)
527  {
528   beam->AddNamedSlot("Idproj");
529   beam->SetSignal(id,"Idproj");
530  }
531
532  if (newdev)
533  {
534   AddDevice(beam);
535   if (fDevCopy) delete beam;
536  }
537 }
538 ///////////////////////////////////////////////////////////////////////////
539 Int_t AliEvent::GetProjectileA() const
540 {
541 // Provide the projectile A value.
542  Int_t val=0;
543  AliSignal* beam=(AliSignal*)GetDevice("Beam");
544  if (beam) val=int(beam->GetSignal("Aproj"));
545  return val;
546 }
547 ///////////////////////////////////////////////////////////////////////////
548 Int_t AliEvent::GetProjectileZ() const
549 {
550 // Provide the projectile Z value.
551  Int_t val=0;
552  AliSignal* beam=(AliSignal*)GetDevice("Beam");
553  if (beam) val=int(beam->GetSignal("Zproj"));
554  return val;
555 }
556 ///////////////////////////////////////////////////////////////////////////
557 Double_t AliEvent::GetProjectilePnuc() const
558 {
559 // Provide the projectile momentum value per nucleon.
560  Double_t val=0;
561  AliSignal* beam=(AliSignal*)GetDevice("Beam");
562  if (beam) val=beam->GetSignal("Pnucproj");
563  return val;
564 }
565 ///////////////////////////////////////////////////////////////////////////
566 Int_t AliEvent::GetProjectileId() const
567 {
568 // Provide the user defined particle ID of the projectile.
569  Int_t val=0;
570  AliSignal* beam=(AliSignal*)GetDevice("Beam");
571  if (beam) val=int(beam->GetSignal("Idproj"));
572  return val;
573 }
574 ///////////////////////////////////////////////////////////////////////////
575 void AliEvent::SetTarget(Int_t a,Int_t z,Double_t pnuc,Int_t id)
576 {
577 // Set the target A, Z, momentum per nucleon and user defined particle ID.
578 // If not explicitly specified by the user, the target particle ID is set
579 // to zero by default and will not be stored in the event structure.
580 // The target specifications will be stored in a device named "Beam"
581 // which is an instance of AliSignal.
582 // As such these data are easily retrievable from the event structure.
583 // However, for backward compatibility reasons the beam data can also be
584 // retrieved via memberfunctions like GetTargetA() etc...
585
586  Int_t newdev=0;
587  
588  AliSignal* beam=(AliSignal*)GetDevice("Beam");
589  
590  if (!beam)
591  {
592   beam=new AliSignal();
593   beam->SetNameTitle("Beam","Beam and target specifications");
594   newdev=1;
595  }
596
597  if (a || z)
598  {
599   beam->AddNamedSlot("Atarg");
600   beam->SetSignal(a,"Atarg");
601   beam->AddNamedSlot("Ztarg");
602   beam->SetSignal(z,"Ztarg");
603  }
604  beam->AddNamedSlot("Pnuctarg");
605  beam->SetSignal(pnuc,"Pnuctarg");
606  if (id)
607  {
608   beam->AddNamedSlot("Idtarg");
609   beam->SetSignal(id,"Idtarg");
610  }
611
612  if (newdev)
613  {
614   AddDevice(beam);
615   if (fDevCopy) delete beam;
616  }
617 }
618 ///////////////////////////////////////////////////////////////////////////
619 Int_t AliEvent::GetTargetA() const
620 {
621 // Provide the target A value.
622  Int_t val=0;
623  AliSignal* beam=(AliSignal*)GetDevice("Beam");
624  if (beam) val=int(beam->GetSignal("Atarg"));
625  return val;
626 }
627 ///////////////////////////////////////////////////////////////////////////
628 Int_t AliEvent::GetTargetZ() const
629 {
630 // Provide the target Z value.
631  Int_t val=0;
632  AliSignal* beam=(AliSignal*)GetDevice("Beam");
633  if (beam) val=int(beam->GetSignal("Ztarg"));
634  return val;
635 }
636 ///////////////////////////////////////////////////////////////////////////
637 Double_t AliEvent::GetTargetPnuc() const
638 {
639 // Provide the target momentum value per nucleon.
640  Double_t val=0;
641  AliSignal* beam=(AliSignal*)GetDevice("Beam");
642  if (beam) val=beam->GetSignal("Pnuctarg");
643  return val;
644 }
645 ///////////////////////////////////////////////////////////////////////////
646 Int_t AliEvent::GetTargetId() const
647 {
648 // Provide the user defined particle ID of the target.
649  Int_t val=0;
650  AliSignal* beam=(AliSignal*)GetDevice("Beam");
651  if (beam) val=int(beam->GetSignal("Idtarg"));
652  return val;
653 }
654 ///////////////////////////////////////////////////////////////////////////
655 void AliEvent::HeaderData()
656 {
657 // Provide event header information
658  const char* name=GetName();
659  const char* title=GetTitle();
660  cout << " *" << ClassName() << "::Data*";
661  if (strlen(name))  cout << " Name : " << GetName();
662  if (strlen(title)) cout << " Title : " << GetTitle();
663  cout << endl;
664  Date(1);
665  cout << "  Run : " << fRun << " Event : " << fEvent << endl;
666  ShowDevices(0);
667  ShowTracks(0);
668 }
669 ///////////////////////////////////////////////////////////////////////////
670 void AliEvent::Data(TString f,TString u)
671 {
672 // Provide event information within the coordinate frame f
673 //
674 // The string argument "u" allows to choose between different angular units
675 // in case e.g. a spherical frame is selected.
676 // u = "rad" : angles provided in radians
677 //     "deg" : angles provided in degrees
678 //
679 // The defaults are f="car" and u="rad".
680
681  HeaderData();
682  AliVertex::Data(f,u);
683
684 ///////////////////////////////////////////////////////////////////////////
685 Int_t AliEvent::GetNdevices() const
686 {
687 // Provide the number of stored devices
688  Int_t ndevs=0;
689  if (fDevices) ndevs=fDevices->GetEntries();
690  return ndevs;
691
692 ///////////////////////////////////////////////////////////////////////////
693 Int_t AliEvent::GetNdevices(const char* classname) const
694 {
695 // Provide the number of stored devices of the specified class.
696
697  Int_t ndevs=0;
698  for (Int_t idev=1; idev<=GetNdevices(); idev++)
699  {
700   TObject* obj=GetDevice(idev);
701   if (!obj) continue;
702
703   if (obj->InheritsFrom(classname)) ndevs++;
704  }
705  return ndevs;
706
707 ///////////////////////////////////////////////////////////////////////////
708 void AliEvent::AddDevice(TObject& d)
709 {
710 // Add a device to the event.
711 //
712 // Note :
713 // In case a private copy is made, this is performed via the Clone() memberfunction.
714 // All devices (i.e. classes derived from TObject) have the default TObject::Clone() 
715 // memberfunction.
716 // However, devices generally contain an internal (signal) data structure
717 // which may include pointers to other objects. Therefore it is recommended to provide
718 // for all devices a specific copy constructor and override the default Clone()
719 // memberfunction using this copy constructor.
720 // An example for this may be seen from AliCalorimeter.   
721
722  if (!fDevices)
723  {
724   fDevices=new TObjArray();
725   if (fDevCopy) fDevices->SetOwner();
726  }
727  
728  // Add the device to this event
729  if (fDevCopy)
730  {
731   fDevices->Add(d.Clone());
732  }
733  else
734  {
735   fDevices->Add(&d);
736  }
737 }
738 ///////////////////////////////////////////////////////////////////////////
739 void AliEvent::RemoveDevice(TObject* d)
740 {
741 // Remove the specified device from the event.
742
743  if (!fDevices || !d) return;
744
745  TObject* obj=fDevices->Remove(d);
746  if (obj)
747  {
748   if (fDevCopy) delete obj;
749   fDevices->Compress();
750  }
751 }
752 ///////////////////////////////////////////////////////////////////////////
753 void AliEvent::SetDevCopy(Int_t j)
754 {
755 // (De)activate the creation of private copies of the added devices.
756 // j=0 ==> No private copies are made; pointers of original devices are stored.
757 // j=1 ==> Private copies of the devices are made and these pointers are stored.
758 //
759 //
760 // Notes :
761 //  In case a private copy is made, this is performed via the Clone() memberfunction.
762 //  All devices (i.e. classes derived from TObject) have the default TObject::Clone() 
763 //  memberfunction.
764 //  However, devices generally contain an internal (signal) data structure
765 //  which may include pointers to other objects. Therefore it is recommended to provide
766 //  for all devices a specific copy constructor and override the default Clone()
767 //  memberfunction using this copy constructor.
768 //  An example for this may be seen from AliCalorimeter.   
769 //
770 //  Once the storage contains pointer(s) to device(s) one cannot
771 //  change the DevCopy mode anymore.
772 //  To change the DevCopy mode for an existing AliEvent containing
773 //  devices one first has to invoke Reset().
774
775  if (!fDevices)
776  {
777   if (j==0 || j==1)
778   {
779    fDevCopy=j;
780   }
781   else
782   {
783    cout << " *" << ClassName() << "::SetDevCopy* Invalid argument : " << j << endl;
784   }
785  }
786  else
787  {
788   cout << " *" << ClassName() << "::SetDevCopy* Storage already contained devices."
789        << "  ==> DevCopy mode not changed." << endl; 
790  }
791 }
792 ///////////////////////////////////////////////////////////////////////////
793 Int_t AliEvent::GetDevCopy() const
794 {
795 // Provide value of the DevCopy mode.
796 // 0 ==> No private copies are made; pointers of original devices are stored.
797 // 1 ==> Private copies of the devices are made and these pointers are stored.
798 //
799 // Note :
800 // In case a private copy is made, this is performed via the Clone() memberfunction.
801 // All devices (i.e. classes derived from TObject) have the default TObject::Clone() 
802 // memberfunction.
803 // However, devices generally contain an internal (signal) data structure
804 // which may include pointers to other objects. Therefore it is recommended to provide
805 // for all devices a specific copy constructor and override the default Clone()
806 // memberfunction using this copy constructor.
807 // An example for this may be seen from AliCalorimeter.   
808
809  return fDevCopy;
810 }
811 ///////////////////////////////////////////////////////////////////////////
812 TObject* AliEvent::GetDevice(Int_t i) const
813 {
814 // Return the i-th device of this event.
815 // The first device corresponds to i=1.
816
817  if (!fDevices)
818  {
819   return 0;
820  }
821  else
822  {
823   Int_t ndevs=GetNdevices();
824   if (i<=0 || i>ndevs)
825   {
826    cout << " *" << ClassName() << "::GetDevice* Invalid argument i : " << i
827         << " ndevs = " << ndevs << endl;
828    return 0;
829   }
830   else
831   {
832    return fDevices->At(i-1);
833   }
834  }
835 }
836 ///////////////////////////////////////////////////////////////////////////
837 TObject* AliEvent::GetDevice(TString name) const
838 {
839 // Return the device with name tag "name"
840  if (!fDevices)
841  {
842   return 0;
843  }
844  else
845  {
846   TString s;
847   Int_t ndevs=GetNdevices();
848   for (Int_t i=0; i<ndevs; i++)
849   {
850    TObject* dev=fDevices->At(i);
851    if (dev)
852    {
853     s=dev->GetName();
854     if (s == name) return dev;
855    }
856   }
857
858   return 0; // No matching name found
859  }
860 }
861 ///////////////////////////////////////////////////////////////////////////
862 TObject* AliEvent::GetIdDevice(Int_t id,TObjArray* devs) const
863 {
864 // Return the device with identifier "id" from the specified array "devs".
865 // In case devs=0 (which is the default) all devices stored in the event
866 // structure will be evaluated.
867 // Note : In case of multiple occurrences of identifier "id", the first
868 //        encountered matching device will be returned.
869
870  TObjArray* arr=devs;
871  if (!arr) arr=fDevices;
872
873  if (!arr || id<0) return 0;
874
875  Int_t idx=0;
876  for (Int_t i=0; i<arr->GetSize(); i++)
877  {
878   TObject* dev=arr->At(i);
879   if (dev)
880   {
881    idx=dev->GetUniqueID();
882    if (idx==id) return dev;
883   }
884  }
885  return 0; // No matching id found
886 }
887 ///////////////////////////////////////////////////////////////////////////
888 TObject* AliEvent::GetIdDevice(Int_t id,const char* classname) const
889 {
890 // Return the device with identifier "id" of the specified class.
891 // Note : In case of multiple occurrences of identifier "id", the first
892 //        encountered matching device will be returned.
893
894  if (!fDevices || id<0) return 0;
895
896  Int_t idx=0;
897  for (Int_t i=0; i<GetNdevices(); i++)
898  {
899   TObject* dev=fDevices->At(i);
900   if (dev)
901   {
902    idx=dev->GetUniqueID();
903    if (idx==id && dev->InheritsFrom(classname)) return dev;
904   }
905  }
906  return 0; // No matching id found for the specified class
907 }
908 ///////////////////////////////////////////////////////////////////////////
909 void AliEvent::ShowDevices(Int_t mode) const
910 {
911 // Provide an overview of the available devices.
912 // The argument mode determines the amount of information as follows :
913 // mode = 0 ==> Only printout of the number of devices
914 //        1 ==> Provide a listing with 1 line of info for each device
915 //
916 // The default is mode=1.
917 //
918  Int_t ndevs=GetNdevices();
919  if (ndevs)
920  {
921   if (!mode)
922   {
923    cout << " There are " << ndevs << " devices available." << endl; 
924   }
925   else
926   {
927    cout << " The following " << ndevs << " devices are available :" << endl; 
928    Int_t nh=0,nw=0;
929    for (Int_t i=1; i<=ndevs; i++)
930    {
931     TObject* dev=GetDevice(i);
932     if (dev)
933     {
934      const char* name=dev->GetName();
935      cout << " Device number : " << i;
936      cout << " Class : " << dev->ClassName() << " Id : " << dev->GetUniqueID();
937      if (strlen(name)) cout << " Name : " << name;
938      if (dev->InheritsFrom("AliDevice"))
939      {
940       nh=((AliDevice*)dev)->GetNhits();
941       if (nh) cout << " Nhits : " << nh;
942      }
943      if (dev->InheritsFrom("AliSignal"))
944      {
945       nw=((AliSignal*)dev)->GetNwaveforms();
946       if (nw) cout << " Nwaveforms : " << nw;
947      }
948      cout << endl;
949     }
950    }
951   }
952  }
953  else
954  {
955   cout << " No devices present for this event." << endl;
956  }
957 }
958 ///////////////////////////////////////////////////////////////////////////
959 void AliEvent::ShowDevices(const char* classname,Int_t mode) const
960 {
961 // Provide an overview of the available devices of the specified class.
962 // The argument mode determines the amount of information as follows :
963 // mode = 0 ==> Only printout of the number of devices
964 //        1 ==> Provide a listing with 1 line of info for each device
965 //
966 // The default is mode=1.
967 //
968  Int_t ndevs=GetNdevices();
969  if (ndevs)
970  {
971   Int_t ndevs2=GetNdevices(classname);
972   if (!mode || !ndevs2)
973   {
974    cout << " There are " << ndevs2 << " selected devices available." << endl; 
975   }
976   else
977   {
978    cout << " The following " << ndevs2 << " selected devices are available :" << endl; 
979    Int_t nh=0,nw=0;
980    for (Int_t i=1; i<=ndevs; i++)
981    {
982     TObject* dev=GetDevice(i);
983     if (dev)
984     {
985      if (dev->InheritsFrom(classname))
986      {
987       const char* name=dev->GetName();
988       cout << " Device number : " << i;
989       cout << " Class : " << dev->ClassName() << " Id : " << dev->GetUniqueID();
990       if (strlen(name)) cout << " Name : " << name;
991       if (dev->InheritsFrom("AliDevice"))
992       {
993        nh=((AliDevice*)dev)->GetNhits();
994        if (nh) cout << " Nhits : " << nh;
995       }
996       if (dev->InheritsFrom("AliSignal"))
997       {
998        nw=((AliSignal*)dev)->GetNwaveforms();
999        if (nw) cout << " Nwaveforms : " << nw;
1000       }
1001       cout << endl;
1002      }
1003     }
1004    }
1005   }
1006  }
1007  else
1008  {
1009   cout << " No devices present for this event." << endl;
1010  }
1011 }
1012 ///////////////////////////////////////////////////////////////////////////
1013 TObjArray* AliEvent::GetDevices(const char* classname)
1014 {
1015 // Provide the references to the various devices derived from the
1016 // specified class.
1017  if (fDevs) fDevs->Clear();
1018
1019  Int_t ndev=GetNdevices();
1020  for (Int_t idev=1; idev<=ndev; idev++)
1021  {
1022   TObject* obj=GetDevice(idev);
1023   if (!obj) continue;
1024
1025   if (obj->InheritsFrom(classname))
1026   {
1027    if (!fDevs) fDevs=new TObjArray();
1028    fDevs->Add(obj);
1029   }
1030  }
1031  return fDevs;
1032 }
1033 ///////////////////////////////////////////////////////////////////////////
1034 Int_t AliEvent::GetNhits(const char* classname)
1035 {
1036 // Provide the number of hits registered to the specified device class.
1037 // The specified device class has to be derived from AliDevice.
1038 // It is possible to indicate with the argument "classname" a specific
1039 // device instead of a whole class of devices. However, in such a case
1040 // it is more efficient to use the GetDevice() memberfunction directly.
1041  LoadHits(classname);
1042  Int_t nhits=0;
1043  if (fHits) nhits=fHits->GetEntries();
1044  return nhits;
1045 }
1046 ///////////////////////////////////////////////////////////////////////////
1047 TObjArray* AliEvent::GetHits(const char* classname)
1048 {
1049 // Provide the references to all the hits registered to the specified
1050 // device class.
1051 // The specified device class has to be derived from AliDevice.
1052 // It is possible to indicate with the argument "classname" a specific
1053 // device instead of a whole class of devices. However, in such a case
1054 // it is more efficient to use the GetDevice() memberfunction directly.
1055  LoadHits(classname);
1056  return fHits;
1057 }
1058 ///////////////////////////////////////////////////////////////////////////
1059 AliSignal* AliEvent::GetIdHit(Int_t id,const char* classname)
1060 {
1061 // Return the hit with unique identifier "id" for the specified device class.
1062  if (id<0) return 0;
1063
1064  Int_t nhits=GetNhits(classname);
1065  if (!nhits) return 0;
1066
1067  AliSignal* sx=0;
1068  Int_t sid=0;
1069  for (Int_t i=0; i<nhits; i++)
1070  {
1071   sx=(AliSignal*)fHits->At(i);
1072   if (sx)
1073   {
1074    sid=sx->GetUniqueID();
1075    if (id==sid) return sx;
1076   }
1077  }
1078  return 0; // No matching id found
1079 }
1080 ///////////////////////////////////////////////////////////////////////////
1081 void AliEvent::LoadHits(const char* classname)
1082 {
1083 // Load the references to the various hits registered to the specified
1084 // device class.
1085 // The specified device class has to be derived from AliDevice.
1086  if (fHits) fHits->Clear();
1087
1088  Int_t ndev=GetNdevices();
1089  for (Int_t idev=1; idev<=ndev; idev++)
1090  {
1091   TObject* obj=GetDevice(idev);
1092   if (!obj) continue;
1093
1094   if (obj->InheritsFrom(classname) && obj->InheritsFrom("AliDevice"))
1095   {
1096    AliDevice* dev=(AliDevice*)GetDevice(idev);
1097    Int_t nhits=dev->GetNhits();
1098    if (nhits)
1099    {
1100     if (!fHits) fHits=new TObjArray();
1101     for (Int_t ih=1; ih<=nhits; ih++)
1102     {
1103      AliSignal* sx=dev->GetHit(ih);
1104      if (sx) fHits->Add(sx);
1105     }
1106    }
1107   }
1108  }
1109 }
1110 ///////////////////////////////////////////////////////////////////////////
1111 TObjArray* AliEvent::SortHits(const char* classname,Int_t idx,Int_t mode,Int_t mcal)
1112 {
1113 // Order the references to the various hits registered to the specified
1114 // device class. The ordered array is returned as a TObjArray.
1115 // A "hit" represents an abstract object which is derived from AliSignal.
1116 // The user can specify the index of the signal slot to perform the sorting on.
1117 // By default the slotindex will be 1.
1118 // Via the "mode" argument the user can specify ordering in decreasing
1119 // order (mode=-1) or ordering in increasing order (mode=1).
1120 // The default is mode=-1.
1121 // Signals which were declared as "Dead" will be rejected.
1122 // The gain etc... corrected signals will be used in the ordering process as
1123 // specified by the "mcal" argument. The definition of this "mcal" parameter
1124 // corresponds to the signal correction mode described in the GetSignal
1125 // memberfunction of class AliSignal.
1126 // The default is mcal=1 (for backward compatibility reasons).
1127 //
1128 // For more extended functionality see class AliDevice.
1129
1130  if (idx<=0 || abs(mode)!=1) return 0;
1131
1132  LoadHits(classname);
1133
1134  AliDevice dev;
1135  TObjArray* ordered=dev.SortHits(idx,mode,fHits,mcal);
1136
1137  if (fHits)
1138  {
1139   delete fHits;
1140   fHits=0;
1141  } 
1142  if (ordered) fHits=new TObjArray(*ordered);
1143  return fHits;
1144 }
1145 ///////////////////////////////////////////////////////////////////////////
1146 TObjArray* AliEvent::SortHits(const char* classname,TString name,Int_t mode,Int_t mcal)
1147 {
1148 // Order the references to the various hits registered to the specified
1149 // device class. The ordered array is returned as a TObjArray.
1150 // A "hit" represents an abstract object which is derived from AliSignal.
1151 // The user can specify the name of the signal slot to perform the sorting on.
1152 // In case no matching slotname is found, the signal will be skipped.
1153 // Via the "mode" argument the user can specify ordering in decreasing
1154 // order (mode=-1) or ordering in increasing order (mode=1).
1155 // The default is mode=-1.
1156 // Signals which were declared as "Dead" will be rejected.
1157 // The gain etc... corrected signals will be used in the ordering process as
1158 // specified by the "mcal" argument. The definition of this "mcal" parameter
1159 // corresponds to the signal correction mode described in the GetSignal
1160 // memberfunction of class AliSignal.
1161 // The default is mcal=1 (for backward compatibility reasons).
1162 //
1163 // For more extended functionality see class AliDevice.
1164  
1165  if (abs(mode)!=1) return 0;
1166
1167  LoadHits(classname);
1168
1169  AliDevice dev;
1170  TObjArray* ordered=dev.SortHits(name,mode,fHits,mcal);
1171
1172  if (fHits)
1173  {
1174   delete fHits;
1175   fHits=0;
1176  } 
1177  if (ordered) fHits=new TObjArray(*ordered);
1178  return fHits;
1179 }
1180 ///////////////////////////////////////////////////////////////////////////
1181 void AliEvent::GetExtremes(const char* classname,Float_t& vmin,Float_t& vmax,Int_t idx,Int_t mode)
1182 {
1183 // Provide the min. and max. signal values of the various hits registered
1184 // to the specified device class.
1185 // The input argument "idx" denotes the index of the signal slots to be investigated.
1186 // The default is idx=1;
1187 // Signals which were declared as "Dead" will be rejected.
1188 // The gain etc... corrected signals will be used in the process as specified
1189 // by the  "mode" argument. The definition of this "mode" parameter corresponds to
1190 // the description provided in the GetSignal memberfunction of class AliSignal.
1191 // The default is mode=1 (for backward compatibility reasons).
1192 //
1193 // For more extended functionality see class AliDevice.
1194
1195  if (idx<=0) return;
1196
1197  LoadHits(classname);
1198
1199  AliDevice dev;
1200  dev.GetExtremes(vmin,vmax,idx,fHits,mode);
1201 }
1202 ///////////////////////////////////////////////////////////////////////////
1203 void AliEvent::GetExtremes(const char* classname,Float_t& vmin,Float_t& vmax,TString name,Int_t mode)
1204 {
1205 // Provide the min. and max. signal values of the various hits registered
1206 // to the specified device class.
1207 // The input argument "name" denotes the name of the signal slots to be investigated.
1208 // Signals which were declared as "Dead" will be rejected.
1209 // The gain etc... corrected signals will be used in the process as specified
1210 // by the  "mode" argument. The definition of this "mode" parameter corresponds to
1211 // the description provided in the GetSignal memberfunction of class AliSignal.
1212 // The default is mode=1 (for backward compatibility reasons).
1213 //
1214 // For more extended functionality see class AliDevice.
1215
1216  LoadHits(classname);
1217
1218  AliDevice dev;
1219  dev.GetExtremes(vmin,vmax,name,fHits,mode);
1220 }
1221 ///////////////////////////////////////////////////////////////////////////
1222 void AliEvent::DisplayHits(const char* classname,Int_t idx,Float_t scale,Int_t dp,Int_t mode,Int_t mcol)
1223 {
1224 // 3D color display of the various hits registered to the specified device class.
1225 // The user can specify the index (default=1) of the signal slot to perform the display for.
1226 // The marker size will indicate the absolute value of the signal (specified by the slotindex)
1227 // as a percentage of the input argument "scale".
1228 // In case scale<0 the maximum absolute signal value encountered in the hit array will be used
1229 // to define the 100% scale. The default is scale=-1.
1230 // In case dp=1 the owning device position will be used, otherwise the hit position will
1231 // be used in the display. The default is dp=0.
1232 // Via the "mcol" argument the user can specify the marker color (see TPolyMarker3D).
1233 // The default is mcol=blue.
1234 // Signals which were declared as "Dead" will not be displayed.
1235 // The gain etc... corrected signals will be used to determine the marker size.
1236 // The gain correction is performed according to "mode" argument. The definition of this
1237 // "mode" parameter corresponds to the description provided in the GetSignal
1238 // memberfunction of class AliSignal.
1239 // The default is mode=1 (for backward compatibility reasons).
1240 //
1241 // For more extended functionality see class AliDevice.
1242 //
1243 // Note :
1244 // ------
1245 // Before any display activity, a TCanvas and a TView have to be initiated
1246 // first by the user like for instance
1247 // 
1248 // TCanvas* c1=new TCanvas("c1","c1");
1249 // TView* view=new TView(1);
1250 // view->SetRange(-1000,-1000,-1000,1000,1000,1000);
1251 // view->ShowAxis();
1252
1253  if (idx<=0) return;
1254
1255  LoadHits(classname);
1256
1257  AliDevice* dev=new AliDevice();
1258  dev->DisplayHits(idx,scale,fHits,dp,mode,mcol);
1259
1260  if (fDisplay)
1261  {
1262   delete fDisplay;
1263   fDisplay=0;
1264  }
1265  fDisplay=dev;
1266 }
1267 ///////////////////////////////////////////////////////////////////////////
1268 void AliEvent::DisplayHits(const char* classname,TString name,Float_t scale,Int_t dp,Int_t mode,Int_t mcol)
1269 {
1270 // 3D color display of the various hits registered to the specified device class.
1271 // The user can specify the name of the signal slot to perform the display for.
1272 // The marker size will indicate the absolute value of the signal (specified by the slotname)
1273 // as a percentage of the input argument "scale".
1274 // In case scale<0 the maximum absolute signal value encountered in the hit array will be used
1275 // to define the 100% scale. The default is scale=-1.
1276 // In case dp=1 the owning device position will be used, otherwise the hit position will
1277 // be used in the display. The default is dp=0.
1278 // The marker size will indicate the percentage of the maximum encountered value
1279 // of the absolute value of the name-specified input signal slots.
1280 // Via the "mcol" argument the user can specify the marker color (see TPolyMarker3D).
1281 // The default is mcol=blue.
1282 // Signals which were declared as "Dead" will not be displayed.
1283 // The gain etc... corrected signals will be used to determine the marker size.
1284 // The gain correction is performed according to "mode" argument. The definition of this
1285 // "mode" parameter corresponds to the description provided in the GetSignal
1286 // memberfunction of class AliSignal.
1287 // The default is mode=1 (for backward compatibility reasons).
1288 //
1289 // For more extended functionality see class AliDevice.
1290 //
1291 // Note :
1292 // ------
1293 // Before any display activity, a TCanvas and a TView have to be initiated
1294 // first by the user like for instance
1295 // 
1296 // TCanvas* c1=new TCanvas("c1","c1");
1297 // TView* view=new TView(1);
1298 // view->SetRange(-1000,-1000,-1000,1000,1000,1000);
1299 // view->ShowAxis();
1300
1301  LoadHits(classname);
1302
1303  AliDevice* dev=new AliDevice();
1304  dev->DisplayHits(name,scale,fHits,dp,mode,mcol);
1305
1306  if (fDisplay)
1307  {
1308   delete fDisplay;
1309   fDisplay=0;
1310  }
1311  fDisplay=dev;
1312 }
1313 ///////////////////////////////////////////////////////////////////////////
1314 TObjArray* AliEvent::SortDevices(const char* classname,TString name,Int_t mode,Int_t mcal)
1315 {
1316 // Order the references to the various devices based on hit signals registered
1317 // to the specified device class. The ordered array is returned as a TObjArray.
1318 // A "hit" represents an abstract object which is derived from AliSignal.
1319 // The user can specify the name of the signal slot to perform the sorting on.
1320 // In case no matching slotname is found, the signal will be skipped.
1321 // Via the "mode" argument the user can specify ordering in decreasing
1322 // order (mode=-1) or ordering in increasing order (mode=1).
1323 // The default is mode=-1.
1324 // Signals which were declared as "Dead" will be rejected.
1325 // The gain etc... corrected signals will be used in the ordering process as
1326 // specified by the "mcal" argument. The definition of this "mcal" parameter
1327 // corresponds to the signal correction mode described in the GetSignal
1328 // memberfunction of class AliSignal.
1329 // The default is mcal=1 (for backward compatibility reasons).
1330 //
1331
1332  TObjArray* ordered=SortHits(classname,name,mode,mcal);
1333  
1334  if (!ordered) return 0;
1335
1336  TObjArray* devs=SortDevices(ordered,"*",0,mcal);
1337  return devs;
1338 }
1339 ///////////////////////////////////////////////////////////////////////////
1340 TObjArray* AliEvent::SortDevices(const char* classname,Int_t idx,Int_t mode,Int_t mcal)
1341 {
1342 // Order the references to the various devices based on hit signals registered
1343 // to the specified device class. The ordered array is returned as a TObjArray.
1344 // A "hit" represents an abstract object which is derived from AliSignal.
1345 // The user can specify the index of the signal slot to perform the sorting on.
1346 // By default the slotindex will be 1.
1347 // Via the "mode" argument the user can specify ordering in decreasing
1348 // order (mode=-1) or ordering in increasing order (mode=1).
1349 // The default is mode=-1.
1350 // Signals which were declared as "Dead" will be rejected.
1351 // The gain etc... corrected signals will be used in the ordering process as
1352 // specified by the "mcal" argument. The definition of this "mcal" parameter
1353 // corresponds to the signal correction mode described in the GetSignal
1354 // memberfunction of class AliSignal.
1355 // The default is mcal=1 (for backward compatibility reasons).
1356 //
1357
1358  TObjArray* ordered=SortHits(classname,idx,mode,mcal);
1359  
1360  if (!ordered) return 0;
1361
1362  TObjArray* devs=SortDevices(ordered,0,0,mcal);
1363  return devs;
1364 }
1365 ///////////////////////////////////////////////////////////////////////////
1366 TObjArray* AliEvent::SortDevices(TObjArray* hits,TString name,Int_t mode,Int_t mcal)
1367 {
1368 // Order the references to the various devices based on hit signals contained
1369 // in the input array. The ordered array is returned as a TObjArray.
1370 // A "hit" represents an abstract object which is derived from AliSignal.
1371 // The user can specify the name of the signal slot to perform the sorting on.
1372 // In case no matching slotname is found, the signal will be skipped.
1373 // Via the "mode" argument the user can specify ordering in decreasing
1374 // order (mode=-1), ordering in increasing order (mode=1) or no ordering (mode=0).
1375 // The latter option provides a means to quickly obtain an ordered devices list
1376 // when the hits in the array were already ordered by the user. In this case
1377 // the input argument "name" is irrelevant.
1378 // The default is mode=-1.
1379 // Signals which were declared as "Dead" will be rejected.
1380 // The gain etc... corrected signals will be used in the ordering process as
1381 // specified by the "mcal" argument. The definition of this "mcal" parameter
1382 // corresponds to the signal correction mode described in the GetSignal
1383 // memberfunction of class AliSignal.
1384 // The default is mcal=1 (for backward compatibility reasons).
1385 //
1386
1387  if (!hits) return 0;
1388
1389  TObjArray* ordered=hits;
1390  AliDevice dev;
1391  if (mode) ordered=dev.SortHits(name,mode,hits,mcal);
1392  
1393  if (!ordered) return 0;
1394
1395  if (fOrdered)
1396  {
1397   fOrdered->Clear();
1398  }
1399  else
1400  {
1401   fOrdered=new TObjArray();
1402  }
1403
1404  Int_t nhits=ordered->GetEntries();
1405  Int_t exist=0;
1406  for (Int_t ih=0; ih<nhits; ih++)
1407  {
1408   AliSignal* sx=(AliSignal*)ordered->At(ih);
1409   if (!sx) continue;
1410   AliDevice* dx=sx->GetDevice();
1411   exist=0;
1412   for (Int_t id=0; id<fOrdered->GetEntries(); id++)
1413   {
1414    AliDevice* odx=(AliDevice*)fOrdered->At(id);
1415    if (dx==odx)
1416    {
1417     exist=1;
1418     break;
1419    }
1420   }
1421   if (!exist) fOrdered->Add(dx);
1422  }
1423  return fOrdered;
1424 }
1425 ///////////////////////////////////////////////////////////////////////////
1426 TObjArray* AliEvent::SortDevices(TObjArray* hits,Int_t idx,Int_t mode,Int_t mcal)
1427 {
1428 // Order the references to the various devices based on hit signals contained
1429 // in the input array. The ordered array is returned as a TObjArray.
1430 // A "hit" represents an abstract object which is derived from AliSignal.
1431 // The user can specify the index of the signal slot to perform the sorting on.
1432 // By default the slotindex will be 1.
1433 // Via the "mode" argument the user can specify ordering in decreasing
1434 // order (mode=-1), ordering in increasing order (mode=1) or no ordering (mode=0).
1435 // The latter option provides a means to quickly obtain an ordered devices list
1436 // when the hits in the array were already ordered by the user. In this case
1437 // the input argument "idx" is irrelevant.
1438 // The default is mode=-1.
1439 // Signals which were declared as "Dead" will be rejected.
1440 // The gain etc... corrected signals will be used in the ordering process as
1441 // specified by the "mcal" argument. The definition of this "mcal" parameter
1442 // corresponds to the signal correction mode described in the GetSignal
1443 // memberfunction of class AliSignal.
1444 // The default is mcal=1 (for backward compatibility reasons).
1445 //
1446
1447  if (!hits) return 0;
1448
1449  TObjArray* ordered=hits;
1450  AliDevice dev;
1451  if (mode) ordered=dev.SortHits(idx,mode,hits,mcal);
1452  
1453  if (!ordered) return 0;
1454
1455  if (fOrdered)
1456  {
1457   fOrdered->Clear();
1458  }
1459  else
1460  {
1461   fOrdered=new TObjArray();
1462  }
1463
1464  Int_t nhits=ordered->GetEntries();
1465  Int_t exist=0;
1466  for (Int_t ih=0; ih<nhits; ih++)
1467  {
1468   AliSignal* sx=(AliSignal*)ordered->At(ih);
1469   if (!sx) continue;
1470   AliDevice* dx=sx->GetDevice();
1471   exist=0;
1472   for (Int_t id=0; id<fOrdered->GetEntries(); id++)
1473   {
1474    AliDevice* odx=(AliDevice*)fOrdered->At(id);
1475    if (dx==odx)
1476    {
1477     exist=1;
1478     break;
1479    }
1480   }
1481   if (!exist) fOrdered->Add(dx);
1482  }
1483  return fOrdered;
1484 }
1485 ///////////////////////////////////////////////////////////////////////////
1486 TObject* AliEvent::Clone(const char* name) const
1487 {
1488 // Make a deep copy of the current object and provide the pointer to the copy.
1489 // This memberfunction enables automatic creation of new objects of the
1490 // correct type depending on the object type, a feature which may be very useful
1491 // for containers when adding objects in case the container owns the objects.
1492 // This feature allows to store either AliEvent objects or objects derived from
1493 // AliEvent via some generic AddEvent memberfunction, provided these derived
1494 // classes also have a proper Clone memberfunction. 
1495
1496  AliEvent* evt=new AliEvent(*this);
1497  if (name)
1498  {
1499   if (strlen(name)) evt->SetName(name);
1500  }
1501  return evt;
1502 }
1503 ///////////////////////////////////////////////////////////////////////////
1504