]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - RALICE/AliEvent.cxx
bugfix: corrected buffer size check
[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 "AliEvent.h"
256#include "Riostream.h"
257
258ClassImp(AliEvent) // Class implementation to enable ROOT I/O
259
260AliEvent::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///////////////////////////////////////////////////////////////////////////
274AliEvent::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///////////////////////////////////////////////////////////////////////////
292AliEvent::~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///////////////////////////////////////////////////////////////////////////
322AliEvent::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///////////////////////////////////////////////////////////////////////////
358void 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///////////////////////////////////////////////////////////////////////////
398void 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///////////////////////////////////////////////////////////////////////////
427void 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///////////////////////////////////////////////////////////////////////////
443void 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///////////////////////////////////////////////////////////////////////////
457void AliEvent::SetRunNumber(Int_t run)
458{
459// Set the run number for this event
460 fRun=run;
461}
462///////////////////////////////////////////////////////////////////////////
463void AliEvent::SetEventNumber(Int_t evt)
464{
465// Set the event number for this event
466 fEvent=evt;
467}
468///////////////////////////////////////////////////////////////////////////
469TTimeStamp 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///////////////////////////////////////////////////////////////////////////
483Int_t AliEvent::GetRunNumber() const
484{
485// Provide the run number for this event
486 return fRun;
487}
488///////////////////////////////////////////////////////////////////////////
489Int_t AliEvent::GetEventNumber() const
490{
491// Provide the event number for this event
492 return fEvent;
493}
494///////////////////////////////////////////////////////////////////////////
495void 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///////////////////////////////////////////////////////////////////////////
539Int_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///////////////////////////////////////////////////////////////////////////
548Int_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///////////////////////////////////////////////////////////////////////////
557Double_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///////////////////////////////////////////////////////////////////////////
566Int_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///////////////////////////////////////////////////////////////////////////
575void 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///////////////////////////////////////////////////////////////////////////
619Int_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///////////////////////////////////////////////////////////////////////////
628Int_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///////////////////////////////////////////////////////////////////////////
637Double_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///////////////////////////////////////////////////////////////////////////
646Int_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///////////////////////////////////////////////////////////////////////////
655void 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///////////////////////////////////////////////////////////////////////////
670void 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///////////////////////////////////////////////////////////////////////////
685Int_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///////////////////////////////////////////////////////////////////////////
693Int_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///////////////////////////////////////////////////////////////////////////
708void 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///////////////////////////////////////////////////////////////////////////
739void 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///////////////////////////////////////////////////////////////////////////
753void 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///////////////////////////////////////////////////////////////////////////
793Int_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///////////////////////////////////////////////////////////////////////////
812TObject* 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///////////////////////////////////////////////////////////////////////////
837TObject* 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///////////////////////////////////////////////////////////////////////////
862TObject* 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///////////////////////////////////////////////////////////////////////////
888TObject* 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///////////////////////////////////////////////////////////////////////////
909void 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///////////////////////////////////////////////////////////////////////////
959void 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///////////////////////////////////////////////////////////////////////////
1013TObjArray* 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///////////////////////////////////////////////////////////////////////////
1034Int_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///////////////////////////////////////////////////////////////////////////
1047TObjArray* 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///////////////////////////////////////////////////////////////////////////
1059AliSignal* 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///////////////////////////////////////////////////////////////////////////
1081void 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///////////////////////////////////////////////////////////////////////////
1111TObjArray* 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///////////////////////////////////////////////////////////////////////////
1146TObjArray* 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///////////////////////////////////////////////////////////////////////////
1181void 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///////////////////////////////////////////////////////////////////////////
1203void 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///////////////////////////////////////////////////////////////////////////
1222void 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///////////////////////////////////////////////////////////////////////////
1268void 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///////////////////////////////////////////////////////////////////////////
1314TObjArray* 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///////////////////////////////////////////////////////////////////////////
1340TObjArray* 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///////////////////////////////////////////////////////////////////////////
1366TObjArray* 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///////////////////////////////////////////////////////////////////////////
1426TObjArray* 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///////////////////////////////////////////////////////////////////////////
1486TObject* 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