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