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