* provided "as is" without express or implied warranty. *
**************************************************************************/
-// $Id: AliEvent.cxx,v 1.14 2003/10/26 14:53:44 nick Exp $
+// $Id: AliEvent.cxx,v 1.25 2004/10/20 10:49:44 nick Exp $
///////////////////////////////////////////////////////////////////////////
// Class AliEvent
// Creation and investigation of an Alice physics event.
// An AliEvent can be constructed by adding AliTracks, Alivertices, AliJets
-// and/or devices like AliCalorimeters.
+// and/or devices like AliCalorimeters or AliDevice (derived) objects.
+//
// All objects which are derived from TObject can be regarded as a device.
+// However, AliDevice (or derived) objects profit from additional hit
+// handling facilities.
+// A "hit" is a generic name indicating an AliSignal (or derived) object.
+// Note that AliEvent does NOT own hits; it only provides references to hits
+// obtained from the various devices.
+// This implies that hits should be owned by the devices themselves.
//
// The basic functionality of AliEvent is identical to the one of AliVertex.
// So, an AliEvent may be used as the primary vertex with some additional
// which may include pointers to other objects. Therefore it is recommended to provide
// for all devices a specific copy constructor and override the default Clone()
// memberfunction using this copy constructor.
-// An example for this may be seen from AliCalorimeter.
+// Examples for this may be seen from AliCalorimeter, AliSignal and AliDevice.
//
// See also the documentation provided for the memberfunction SetOwner().
//
//
// Fill the event structure with the basic objects
//
-// AliCalorimeter emcal;
+// AliCalorimeter emcal1;
+// AliCalorimeter emcal2;
+// ...
+// ... // code to fill the emcal1 and emcal2 calorimeter data
+// ...
+//
+// evt.AddDevice(emcal1);
+// evt.AddDevice(emcal2);
+//
+// // Assume AliTOF has been derived from AliDevice
+// AliTOF tof1;
+// AliTOF tof2;
// ...
-// ... // code to fill the calorimeter data
+// ... // code to fill the tof1 and tof2 data
// ...
//
-// evt.AddDevice(emcal);
+// evt.AddDevice(tof1);
+// evt.AddDevice(tof2);
//
// AliTrack* tx=new AliTrack();
// for (Int_t i=0; i<10; i++)
// tx=0;
// }
//
+// Order and investigate all the hits of all the TOF devices
+//
+// TObjArray* hits=evt.GetHits("AliTOF");
+// TObjArray* orderedtofs=evt.SortHits(hits);
+// Int_t nhits=0;
+// if (orderedtofs) nhits=orderedtofs->GetEntries();
+// for (Int_t i=0; i<nhits; i++)
+// {
+// AliSignal* sx=(AliSignal*)orderedtofs->At(i);
+// if (sx) sx->Data();
+// }
+//
+// Order and investigate all the hits of all the calorimeter devices
+//
+// TObjArray* hits=evt.GetHits("AliCalorimeter");
+// TObjArray* orderedcals=evt.SortHits(hits);
+// Int_t nhits=0;
+// if (orderedcals) nhits=orderedcals->GetEntries();
+// for (Int_t i=0; i<nhits; i++)
+// {
+// AliSignal* sx=(AliSignal*)orderedcals->At(i);
+// if (sx) sx->Data();
+// }
+//
// Build the event structure (vertices, jets, ...) for physics analysis
// based on the basic objects from the event repository.
//
// Note : All quantities are in GeV, GeV/c or GeV/c**2
//
//--- Author: Nick van Eijndhoven 27-may-2001 UU-SAP Utrecht
-//- Modified: NvE $Date: 2003/10/26 14:53:44 $ UU-SAP Utrecht
+//- Modified: NvE $Date: 2004/10/20 10:49:44 $ UU-SAP Utrecht
///////////////////////////////////////////////////////////////////////////
#include "AliEvent.h"
{
// Default constructor.
// All variables initialised to default values.
- TTimeStamp tx;
- fDaytime=tx;
+ fDaytime.Set();
fRun=0;
fEvent=0;
fAproj=0;
fIdTarg=0;
fDevices=0;
fDevCopy=0;
+ fHits=0;
+ fOrdered=0;
+ fDisplay=0;
}
///////////////////////////////////////////////////////////////////////////
AliEvent::AliEvent(Int_t n) : AliVertex(n)
{
cout << " *** This AliVertex initialisation was invoked via the AliEvent ctor." << endl;
}
- TTimeStamp tx;
- fDaytime=tx;
+ fDaytime.Set();
fRun=0;
fEvent=0;
fAproj=0;
fIdTarg=0;
fDevices=0;
fDevCopy=0;
+ fHits=0;
+ fOrdered=0;
+ fDisplay=0;
}
///////////////////////////////////////////////////////////////////////////
AliEvent::~AliEvent()
delete fDevices;
fDevices=0;
}
+ if (fHits)
+ {
+ delete fHits;
+ fHits=0;
+ }
+ if (fOrdered)
+ {
+ delete fOrdered;
+ fOrdered=0;
+ }
+ if (fDisplay)
+ {
+ delete fDisplay;
+ fDisplay=0;
+ }
}
///////////////////////////////////////////////////////////////////////////
-AliEvent::AliEvent(AliEvent& evt) : AliVertex(evt)
+AliEvent::AliEvent(const AliEvent& evt) : AliVertex(evt)
{
// Copy constructor.
fDaytime=evt.fDaytime;
fIdTarg=evt.fIdTarg;
fDevCopy=evt.fDevCopy;
+ fHits=0;
+ fOrdered=0;
+ fDisplay=0;
+
fDevices=0;
Int_t ndevs=evt.GetNdevices();
if (ndevs)
// Reset all variables to default values
// The max. number of tracks is set to the initial value again
// The max. number of vertices is set to the default value again
-// Note : The CalCopy mode is maintained as it was set by the user before.
+// Note : The DevCopy mode is maintained as it was set by the user before.
AliVertex::Reset();
- TTimeStamp tx;
- fDaytime=tx;
+ fDaytime.Set();
fRun=0;
fEvent=0;
fAproj=0;
delete fDevices;
fDevices=0;
}
+ if (fHits)
+ {
+ delete fHits;
+ fHits=0;
+ }
+ if (fOrdered)
+ {
+ delete fOrdered;
+ fOrdered=0;
+ }
+ if (fDisplay)
+ {
+ delete fDisplay;
+ fDisplay=0;
+ }
}
///////////////////////////////////////////////////////////////////////////
void AliEvent::SetOwner(Bool_t own)
{
// Set the date and time stamp for this event.
// An exact copy of the entered date/time stamp will be saved with an
-// accuracy of 1 second.
+// accuracy of 1 nanosecond.
fDaytime=stamp;
}
///////////////////////////////////////////////////////////////////////////
// compatibility reasons. It is recommended to use the corresponding
// function with the TTimeStamp argument.
- TTimeStamp ts(stamp.GetDate(),stamp.GetTime(),0,kFALSE);
- fDaytime=ts;
+ fDaytime.Set(stamp.GetDate(),stamp.GetTime(),0,kFALSE,0);
}
///////////////////////////////////////////////////////////////////////////
void AliEvent::SetRunNumber(Int_t run)
fEvent=evt;
}
///////////////////////////////////////////////////////////////////////////
-TTimeStamp AliEvent::GetDayTime()
+TTimeStamp AliEvent::GetDayTime() const
{
// Provide the date and time stamp for this event
return fDaytime;
}
///////////////////////////////////////////////////////////////////////////
-Int_t AliEvent::GetRunNumber()
+Int_t AliEvent::GetRunNumber() const
{
// Provide the run number for this event
return fRun;
}
///////////////////////////////////////////////////////////////////////////
-Int_t AliEvent::GetEventNumber()
+Int_t AliEvent::GetEventNumber() const
{
// Provide the event number for this event
return fEvent;
fIdProj=id;
}
///////////////////////////////////////////////////////////////////////////
-Int_t AliEvent::GetProjectileA()
+Int_t AliEvent::GetProjectileA() const
{
// Provide the projectile A value.
return fAproj;
}
///////////////////////////////////////////////////////////////////////////
-Int_t AliEvent::GetProjectileZ()
+Int_t AliEvent::GetProjectileZ() const
{
// Provide the projectile Z value.
return fZproj;
}
///////////////////////////////////////////////////////////////////////////
-Double_t AliEvent::GetProjectilePnuc()
+Double_t AliEvent::GetProjectilePnuc() const
{
// Provide the projectile momentum value per nucleon.
return fPnucProj;
}
///////////////////////////////////////////////////////////////////////////
-Int_t AliEvent::GetProjectileId()
+Int_t AliEvent::GetProjectileId() const
{
// Provide the user defined particle ID of the projectile.
return fIdProj;
fIdTarg=id;
}
///////////////////////////////////////////////////////////////////////////
-Int_t AliEvent::GetTargetA()
+Int_t AliEvent::GetTargetA() const
{
// Provide the target A value.
return fAtarg;
}
///////////////////////////////////////////////////////////////////////////
-Int_t AliEvent::GetTargetZ()
+Int_t AliEvent::GetTargetZ() const
{
// Provide the target Z value.
return fZtarg;
}
///////////////////////////////////////////////////////////////////////////
-Double_t AliEvent::GetTargetPnuc()
+Double_t AliEvent::GetTargetPnuc() const
{
// Provide the target momentum value per nucleon.
return fPnucTarg;
}
///////////////////////////////////////////////////////////////////////////
-Int_t AliEvent::GetTargetId()
+Int_t AliEvent::GetTargetId() const
{
// Provide the user defined particle ID of the target.
return fIdTarg;
}
///////////////////////////////////////////////////////////////////////////
-void AliEvent::HeaderData()
+void AliEvent::HeaderData() const
{
// Provide event header information
- cout << " *" << ClassName() << "::Data* Name : " << GetName()
- << " Title : " << GetTitle() << endl;
+ const char* name=GetName();
+ const char* title=GetTitle();
+ Int_t ndevs=GetNdevices();
+ cout << " *" << ClassName() << "::Data*";
+ if (strlen(name)) cout << " Name : " << GetName();
+ if (strlen(title)) cout << " Title : " << GetTitle();
+ cout << endl;
cout << " " << fDaytime.AsString() << endl;
- cout << " Run : " << fRun << " Event : " << fEvent << endl;
+ cout << " Run : " << fRun << " Event : " << fEvent
+ << " Number of devices : " << ndevs << endl;
- ShowDevices();
+ if (ndevs) ShowDevices();
}
///////////////////////////////////////////////////////////////////////////
void AliEvent::Data(TString f)
AliVertex::Data(f);
}
///////////////////////////////////////////////////////////////////////////
-Int_t AliEvent::GetNdevices()
+Int_t AliEvent::GetNdevices() const
{
// Provide the number of stored devices
Int_t ndevs=0;
}
}
///////////////////////////////////////////////////////////////////////////
-Int_t AliEvent::GetDevCopy()
+Int_t AliEvent::GetDevCopy() const
{
// Provide value of the DevCopy mode.
// 0 ==> No private copies are made; pointers of original devices are stored.
return fDevCopy;
}
///////////////////////////////////////////////////////////////////////////
-TObject* AliEvent::GetDevice(Int_t i)
+TObject* AliEvent::GetDevice(Int_t i) const
{
// Return the i-th device of this event.
// The first device corresponds to i=1.
if (!fDevices)
{
- cout << " *AliEvent::GetDevice* No devices present." << endl;
return 0;
}
else
}
}
///////////////////////////////////////////////////////////////////////////
-TObject* AliEvent::GetDevice(TString name)
+TObject* AliEvent::GetDevice(TString name) const
{
// Return the device with name tag "name"
if (!fDevices)
{
- cout << " *" << ClassName() << "::GetDevice* No devices present." << endl;
return 0;
}
else
}
}
///////////////////////////////////////////////////////////////////////////
-void AliEvent::ShowDevices()
+TObject* AliEvent::GetIdDevice(Int_t id) const
+{
+// Return the device with unique identifier "id".
+ if (!fDevices || id<0) return 0;
+
+ Int_t idx=0;
+ for (Int_t i=0; i<GetNdevices(); i++)
+ {
+ TObject* dev=fDevices->At(i);
+ if (dev)
+ {
+ idx=dev->GetUniqueID();
+ if (idx==id) return dev;
+ }
+ }
+ return 0; // No matching id found
+}
+///////////////////////////////////////////////////////////////////////////
+void AliEvent::ShowDevices() const
{
// Provide an overview of the available devices.
Int_t ndevs=GetNdevices();
TObject* dev=GetDevice(i);
if (dev)
{
- cout << " Device number : " << i
- << " Class : " << dev->ClassName()
- << " Name : " << dev->GetName() << endl;
+ const char* name=dev->GetName();
+ cout << " Device number : " << i;
+ cout << " Class : " << dev->ClassName() << " Id : " << dev->GetUniqueID();
+ if (strlen(name)) cout << " Name : " << name;
+ if (dev->InheritsFrom("AliDevice")) cout << " Nhits : " << ((AliDevice*)dev)->GetNhits();
+ cout << endl;
}
}
}
}
}
///////////////////////////////////////////////////////////////////////////
+Int_t AliEvent::GetNhits(const char* classname)
+{
+// Provide the number of hits registered to the specified device class.
+// The specified device class has to be derived from AliDevice.
+// It is possible to indicate with the argument "classname" a specific
+// device instead of a whole class of devices. However, in such a case
+// it is more efficient to use the GetDevice() memberfunction directly.
+ LoadHits(classname);
+ Int_t nhits=0;
+ if (fHits) nhits=fHits->GetEntries();
+ return nhits;
+}
+///////////////////////////////////////////////////////////////////////////
+TObjArray* AliEvent::GetHits(const char* classname)
+{
+// Provide the references to all the hits registered to the specified
+// device class.
+// The specified device class has to be derived from AliDevice.
+// It is possible to indicate with the argument "classname" a specific
+// device instead of a whole class of devices. However, in such a case
+// it is more efficient to use the GetDevice() memberfunction directly.
+ LoadHits(classname);
+ return fHits;
+}
+///////////////////////////////////////////////////////////////////////////
+AliSignal* AliEvent::GetIdHit(Int_t id,const char* classname)
+{
+// Return the hit with unique identifier "id" for the specified device class.
+ if (id<0) return 0;
+
+ Int_t nhits=GetNhits(classname);
+ if (!nhits) return 0;
+
+ AliSignal* sx=0;
+ Int_t sid=0;
+ for (Int_t i=0; i<nhits; i++)
+ {
+ sx=(AliSignal*)fHits->At(i);
+ if (sx)
+ {
+ sid=sx->GetUniqueID();
+ if (id==sid) return sx;
+ }
+ }
+ return 0; // No matching id found
+}
+///////////////////////////////////////////////////////////////////////////
+void AliEvent::LoadHits(const char* classname)
+{
+// Load the references to the various hits registered to the specified
+// device class.
+// The specified device class has to be derived from AliDevice.
+ if (fHits) fHits->Clear();
+
+ Int_t ndev=GetNdevices();
+ for (Int_t idev=1; idev<=ndev; idev++)
+ {
+ TObject* obj=GetDevice(idev);
+ if (!obj) continue;
+
+ if (obj->InheritsFrom(classname) && obj->InheritsFrom("AliDevice"))
+ {
+ AliDevice* dev=(AliDevice*)GetDevice(idev);
+ Int_t nhits=dev->GetNhits();
+ if (nhits)
+ {
+ if (!fHits) fHits=new TObjArray();
+ for (Int_t ih=1; ih<=nhits; ih++)
+ {
+ AliSignal* sx=dev->GetHit(ih);
+ if (sx) fHits->Add(sx);
+ }
+ }
+ }
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+TObjArray* AliEvent::SortHits(const char* classname,Int_t idx,Int_t mode)
+{
+// Order the references to the various hits registered to the specified
+// device class. The ordered array is returned as a TObjArray.
+// A "hit" represents an abstract object which is derived from AliSignal.
+// The user can specify the index of the signal slot to perform the sorting on.
+// By default the slotindex will be 1.
+// Via the "mode" argument the user can specify ordering in decreasing
+// order (mode=-1) or ordering in increasing order (mode=1).
+// The default is mode=-1.
+// Signals which were declared as "Dead" will be rejected.
+// The gain etc... corrected signals will be used in the ordering process.
+//
+// For more extended functionality see class AliDevice.
+
+ if (idx<=0 || abs(mode)!=1) return 0;
+
+ LoadHits(classname);
+
+ AliDevice dev;
+ TObjArray* ordered=dev.SortHits(idx,mode,fHits);
+
+ if (fHits)
+ {
+ delete fHits;
+ fHits=0;
+ }
+ if (ordered) fHits=new TObjArray(*ordered);
+ return fHits;
+}
+///////////////////////////////////////////////////////////////////////////
+TObjArray* AliEvent::SortHits(const char* classname,TString name,Int_t mode)
+{
+// Order the references to the various hits registered to the specified
+// device class. The ordered array is returned as a TObjArray.
+// A "hit" represents an abstract object which is derived from AliSignal.
+// The user can specify the name of the signal slot to perform the sorting on.
+// In case no matching slotname is found, the signal will be skipped.
+// Via the "mode" argument the user can specify ordering in decreasing
+// order (mode=-1) or ordering in increasing order (mode=1).
+// The default is mode=-1.
+// Signals which were declared as "Dead" will be rejected.
+// The gain etc... corrected signals will be used in the ordering process.
+//
+// For more extended functionality see class AliDevice.
+
+ if (abs(mode)!=1) return 0;
+
+ LoadHits(classname);
+
+ AliDevice dev;
+ TObjArray* ordered=dev.SortHits(name,mode,fHits);
+
+ if (fHits)
+ {
+ delete fHits;
+ fHits=0;
+ }
+ if (ordered) fHits=new TObjArray(*ordered);
+ return fHits;
+}
+///////////////////////////////////////////////////////////////////////////
+void AliEvent::GetExtremes(const char* classname,Float_t& vmin,Float_t& vmax,Int_t idx)
+{
+// Provide the min. and max. signal values of the various hits registered
+// to the specified device class.
+// The input argument "idx" denotes the index of the signal slots to be investigated.
+// The default is idx=1;
+// Signals which were declared as "Dead" will be rejected.
+// The gain etc... corrected signals will be used in the process.
+//
+// For more extended functionality see class AliDevice.
+
+ if (idx<=0) return;
+
+ LoadHits(classname);
+
+ AliDevice dev;
+ dev.GetExtremes(vmin,vmax,idx,fHits);
+}
+///////////////////////////////////////////////////////////////////////////
+void AliEvent::GetExtremes(const char* classname,Float_t& vmin,Float_t& vmax,TString name)
+{
+// Provide the min. and max. signal values of the various hits registered
+// to the specified device class.
+// The input argument "name" denotes the name of the signal slots to be investigated.
+// Signals which were declared as "Dead" will be rejected.
+// The gain etc... corrected signals will be used in the process.
+//
+// For more extended functionality see class AliDevice.
+
+ LoadHits(classname);
+
+ AliDevice dev;
+ dev.GetExtremes(vmin,vmax,name,fHits);
+}
+///////////////////////////////////////////////////////////////////////////
+void AliEvent::DisplayHits(const char* classname,Int_t idx,Float_t scale,Int_t dp,Int_t mstyle,Int_t mcol)
+{
+// 3D color display of the various hits registered to the specified device class.
+// The user can specify the index (default=1) of the signal slot to perform the display for.
+// The marker size will indicate the absolute value of the signal (specified by the slotindex)
+// as a percentage of the input argument "scale".
+// In case scale<0 the maximum absolute signal value encountered in the hit array will be used
+// to define the 100% scale. The default is scale=-1.
+// In case dp=1 the owning device position will be used, otherwise the hit position will
+// be used in the display. The default is dp=0.
+// Via the "mstyle" and "mcol" arguments the user can specify the marker style
+// and color (see TPolyMarker3D) respectively.
+// The defaults are mstyle="large scalable dot" and mcol=blue.
+// Signals which were declared as "Dead" will not be displayed.
+// The gain etc... corrected signals will be used to determine the marker size.
+//
+// For more extended functionality see class AliDevice.
+//
+// Note :
+// ------
+// Before any display activity, a TCanvas and a TView have to be initiated
+// first by the user like for instance
+//
+// TCanvas* c1=new TCanvas("c1","c1");
+// TView* view=new TView(1);
+// view->SetRange(-1000,-1000,-1000,1000,1000,1000);
+// view->ShowAxis();
+
+ if (idx<=0) return;
+
+ LoadHits(classname);
+
+ AliDevice* dev=new AliDevice();
+ dev->DisplayHits(idx,scale,fHits,dp,mstyle,mcol);
+
+ if (fDisplay)
+ {
+ delete fDisplay;
+ fDisplay=0;
+ }
+ fDisplay=dev;
+}
+///////////////////////////////////////////////////////////////////////////
+void AliEvent::DisplayHits(const char* classname,TString name,Float_t scale,Int_t dp,Int_t mstyle,Int_t mcol)
+{
+// 3D color display of the various hits registered to the specified device class.
+// The user can specify the name of the signal slot to perform the display for.
+// The marker size will indicate the absolute value of the signal (specified by the slotname)
+// as a percentage of the input argument "scale".
+// In case scale<0 the maximum absolute signal value encountered in the hit array will be used
+// to define the 100% scale. The default is scale=-1.
+// In case dp=1 the owning device position will be used, otherwise the hit position will
+// be used in the display. The default is dp=0.
+// The marker size will indicate the percentage of the maximum encountered value
+// of the absolute value of the name-specified input signal slots.
+// Via the "mstyle" and "mcol" arguments the user can specify the marker style
+// and color (see TPolyMarker3D) respectively.
+// The defaults are mstyle="large scalable dot" and mcol=blue.
+// Signals which were declared as "Dead" will not be displayed.
+// The gain etc... corrected signals will be used to determine the marker size.
+//
+// For more extended functionality see class AliDevice.
+//
+// Note :
+// ------
+// Before any display activity, a TCanvas and a TView have to be initiated
+// first by the user like for instance
+//
+// TCanvas* c1=new TCanvas("c1","c1");
+// TView* view=new TView(1);
+// view->SetRange(-1000,-1000,-1000,1000,1000,1000);
+// view->ShowAxis();
+
+ LoadHits(classname);
+
+ AliDevice* dev=new AliDevice();
+ dev->DisplayHits(name,scale,fHits,dp,mstyle,mcol);
+
+ if (fDisplay)
+ {
+ delete fDisplay;
+ fDisplay=0;
+ }
+ fDisplay=dev;
+}
+///////////////////////////////////////////////////////////////////////////
+TObjArray* AliEvent::SortDevices(const char* classname,TString name,Int_t mode)
+{
+// Order the references to the various devices based on hit signals registered
+// to the specified device class. The ordered array is returned as a TObjArray.
+// A "hit" represents an abstract object which is derived from AliSignal.
+// The user can specify the name of the signal slot to perform the sorting on.
+// In case no matching slotname is found, the signal will be skipped.
+// Via the "mode" argument the user can specify ordering in decreasing
+// order (mode=-1) or ordering in increasing order (mode=1).
+// The default is mode=-1.
+// Signals which were declared as "Dead" will be rejected.
+// The gain etc... corrected signals will be used in the ordering process.
+//
+
+ TObjArray* ordered=SortHits(classname,name,mode);
+
+ if (!ordered) return 0;
+
+ TObjArray* devs=SortDevices(ordered,"*",0);
+ return devs;
+}
+///////////////////////////////////////////////////////////////////////////
+TObjArray* AliEvent::SortDevices(const char* classname,Int_t idx,Int_t mode)
+{
+// Order the references to the various devices based on hit signals registered
+// to the specified device class. The ordered array is returned as a TObjArray.
+// A "hit" represents an abstract object which is derived from AliSignal.
+// The user can specify the index of the signal slot to perform the sorting on.
+// By default the slotindex will be 1.
+// Via the "mode" argument the user can specify ordering in decreasing
+// order (mode=-1) or ordering in increasing order (mode=1).
+// The default is mode=-1.
+// Signals which were declared as "Dead" will be rejected.
+// The gain etc... corrected signals will be used in the ordering process.
+//
+
+ TObjArray* ordered=SortHits(classname,idx,mode);
+
+ if (!ordered) return 0;
+
+ TObjArray* devs=SortDevices(ordered,0,0);
+ return devs;
+}
+///////////////////////////////////////////////////////////////////////////
+TObjArray* AliEvent::SortDevices(TObjArray* hits,TString name,Int_t mode)
+{
+// Order the references to the various devices based on hit signals contained
+// in the input array. The ordered array is returned as a TObjArray.
+// A "hit" represents an abstract object which is derived from AliSignal.
+// The user can specify the name of the signal slot to perform the sorting on.
+// In case no matching slotname is found, the signal will be skipped.
+// Via the "mode" argument the user can specify ordering in decreasing
+// order (mode=-1), ordering in increasing order (mode=1) or no ordering (mode=0).
+// The latter option provides a means to quickly obtain an ordered devices list
+// when the hits in the array were already ordered by the user. In this case
+// the input argument "name" is irrelevant.
+// The default is mode=-1.
+// Signals which were declared as "Dead" will be rejected.
+// The gain etc... corrected signals will be used in the ordering process.
+//
+
+ if (!hits) return 0;
+
+ TObjArray* ordered=hits;
+ AliDevice dev;
+ if (mode) ordered=dev.SortHits(name,mode,hits);
+
+ if (!ordered) return 0;
+
+ if (fOrdered)
+ {
+ fOrdered->Clear();
+ }
+ else
+ {
+ fOrdered=new TObjArray();
+ }
+
+ Int_t nhits=ordered->GetEntries();
+ Int_t exist=0;
+ for (Int_t ih=0; ih<nhits; ih++)
+ {
+ AliSignal* sx=(AliSignal*)ordered->At(ih);
+ if (!sx) continue;
+ AliDevice* dx=sx->GetDevice();
+ exist=0;
+ for (Int_t id=0; id<fOrdered->GetEntries(); id++)
+ {
+ AliDevice* odx=(AliDevice*)fOrdered->At(id);
+ if (dx==odx)
+ {
+ exist=1;
+ break;
+ }
+ }
+ if (!exist) fOrdered->Add(dx);
+ }
+ return fOrdered;
+}
+///////////////////////////////////////////////////////////////////////////
+TObjArray* AliEvent::SortDevices(TObjArray* hits,Int_t idx,Int_t mode)
+{
+// Order the references to the various devices based on hit signals contained
+// in the input array. The ordered array is returned as a TObjArray.
+// A "hit" represents an abstract object which is derived from AliSignal.
+// The user can specify the index of the signal slot to perform the sorting on.
+// By default the slotindex will be 1.
+// Via the "mode" argument the user can specify ordering in decreasing
+// order (mode=-1), ordering in increasing order (mode=1) or no ordering (mode=0).
+// The latter option provides a means to quickly obtain an ordered devices list
+// when the hits in the array were already ordered by the user. In this case
+// the input argument "idx" is irrelevant.
+// The default is mode=-1.
+// Signals which were declared as "Dead" will be rejected.
+// The gain etc... corrected signals will be used in the ordering process.
+//
+
+ if (!hits) return 0;
+
+ TObjArray* ordered=hits;
+ AliDevice dev;
+ if (mode) ordered=dev.SortHits(idx,mode,hits);
+
+ if (!ordered) return 0;
+
+ if (fOrdered)
+ {
+ fOrdered->Clear();
+ }
+ else
+ {
+ fOrdered=new TObjArray();
+ }
+
+ Int_t nhits=ordered->GetEntries();
+ Int_t exist=0;
+ for (Int_t ih=0; ih<nhits; ih++)
+ {
+ AliSignal* sx=(AliSignal*)ordered->At(ih);
+ if (!sx) continue;
+ AliDevice* dx=sx->GetDevice();
+ exist=0;
+ for (Int_t id=0; id<fOrdered->GetEntries(); id++)
+ {
+ AliDevice* odx=(AliDevice*)fOrdered->At(id);
+ if (dx==odx)
+ {
+ exist=1;
+ break;
+ }
+ }
+ if (!exist) fOrdered->Add(dx);
+ }
+ return fOrdered;
+}
+///////////////////////////////////////////////////////////////////////////
+TObject* AliEvent::Clone(const char* name) const
+{
+// Make a deep copy of the current object and provide the pointer to the copy.
+// This memberfunction enables automatic creation of new objects of the
+// correct type depending on the object type, a feature which may be very useful
+// for containers when adding objects in case the container owns the objects.
+// This feature allows to store either AliEvent objects or objects derived from
+// AliEvent via some generic AddEvent memberfunction, provided these derived
+// classes also have a proper Clone memberfunction.
+
+ AliEvent* evt=new AliEvent(*this);
+ if (name)
+ {
+ if (strlen(name)) evt->SetName(name);
+ }
+ return evt;
+}
+///////////////////////////////////////////////////////////////////////////