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