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