]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - RALICE/AliDevice.cxx
13-nov-2005 NvE IceF2k updated to store also the event trigger information in the...
[u/mrichter/AliRoot.git] / RALICE / AliDevice.cxx
index acd886a6ad21d437a67a3a514777772780ada81c..89f917c8f2f1b34f08e1afb1a61d5509fc46dc64 100644 (file)
@@ -27,6 +27,8 @@
 // =========
 //
 // AliDevice m;
+// // Set user defined status word to indicate e.g. readout electronics version 
+// m.SetStatus(100201);
 // m.SetHitCopy(1);
 // m.SetName("OM123");
 //
 // s.SetSignal(-1002,3);
 // m.AddHit(s);
 //
-// TObjArray ordered=m.SortHits("TOT");
-// nhits=ordered.GetEntries();
+// TObjArray* ordered=m.SortHits("TOT");
+// nhits=ordered->GetEntries();
 // for (Int_t i=0; i<nhits; i++)
 // {
-//  AliSignal* sx=(AliSignal*)ordered.At(i);
+//  AliSignal* sx=(AliSignal*)ordered->At(i);
 //  if (sx) sx->Data();
 // }
 //
@@ -85,8 +87,15 @@ ClassImp(AliDevice) // Class implementation to enable ROOT I/O
 AliDevice::AliDevice() : AliSignal()
 {
 // Default constructor.
- fHitCopy=0;
+// The user definable status word is set to zero.
+// By default private copies of the recorded hits will be made.
+// This implies that by default the device will own the registered hits.
+// See the SetHitCopy() memberfunction for further details.
+ fStatus=0;
+ fHitCopy=1;
  fHits=0;
+ fOrdered=0;
+ fMarkers=0;
 }
 ///////////////////////////////////////////////////////////////////////////
 AliDevice::~AliDevice()
@@ -109,12 +118,31 @@ AliDevice::~AliDevice()
   delete fHits;
   fHits=0;
  }
+
+ if (fOrdered)
+ {
+  delete fOrdered;
+  fOrdered=0;
+ }
+
+ if (fMarkers)
+ {
+  delete fMarkers;
+  fMarkers=0;
+ }
 }
 ///////////////////////////////////////////////////////////////////////////
 AliDevice::AliDevice(const AliDevice& dev) : AliSignal(dev)
 {
 // Copy constructor.
+
+ fHits=0;
+ fOrdered=0;
+ fMarkers=0;
+
+ fStatus=dev.GetStatus();
  fHitCopy=dev.GetHitCopy();
+
  Int_t nhits=dev.GetNhits();
  if (nhits)
  {
@@ -128,7 +156,7 @@ AliDevice::AliDevice(const AliDevice& dev) : AliSignal(dev)
     fHits->Add(sx->Clone());
     AliSignal* s=(AliSignal*)fHits->Last();
     s->ResetLinks((AliDevice*)&dev);
-    s->AddLink(this);
+    s->SetDevice(this);
    }
    else
    {
@@ -142,6 +170,8 @@ AliDevice::AliDevice(const AliDevice& dev) : AliSignal(dev)
 void AliDevice::Reset(Int_t mode)
 {
 // Reset registered hits and AliSignal attributes.
+// Note : The status word and HitCopy flag are NOT modified.
+//        Use SetStatus() and SetHitCopy() to modify these parameters. 
 // See AliSignal::Reset() for further details.
  RemoveHits();
  AliSignal::Reset(mode);
@@ -183,11 +213,28 @@ Int_t AliDevice::GetHitCopy() const
  return fHitCopy;
 }
 ///////////////////////////////////////////////////////////////////////////
+void AliDevice::SetStatus(Int_t word)
+{
+// Set a user defined status word for this device.
+ fStatus=word;
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliDevice::GetStatus() const
+{
+// Provide the user defined status word for this device.
+ return fStatus;
+}
+///////////////////////////////////////////////////////////////////////////
 void AliDevice::AddHit(AliSignal& s)
 {
 // Register an AliSignal object as a hit to this device.
-// Note : A (backward) link to this device is added to the first slot of
-//        the AliSignal if there was no link to this device already present.
+// Note : In case this device owns the AliSignal object, the pointer to
+//        this device will be stored in the special owning device
+//        pointer of the AliSignal object.
+//        In case this device does not own the AliSignal object, a (backward)
+//        link to this device is added to the first slot of the AliSignal
+//        if there was no link to this device already present.
+
  if (!fHits)
  {
   fHits=new TObjArray(1);
@@ -201,17 +248,23 @@ void AliDevice::AddHit(AliSignal& s)
   if (&s==fHits->At(i)) return; 
  }
 
- // Set the (backward) link to this device.
- Int_t nlinks=GetNlinks(this);
- if (!nlinks) s.AddLink(this);
+ // Check for existing (backward) link to this device.
+ Int_t nlinks=s.GetNlinks(this);
 
  if (fHitCopy)
  {
   fHits->Add(s.Clone());
+  // Remove unnecessary backward link(s) from the various slots
+  // and set the owning link to this device
+  AliSignal* sx=(AliSignal*)fHits->Last();
+  if (nlinks) sx->ResetLinks(this);
+  sx->SetDevice(this);
  }
  else
  {
   fHits->Add(&s);
+  // Set (backward) link to the this device
+  if (!nlinks) s.AddLink(this);
  }
 }
 ///////////////////////////////////////////////////////////////////////////
@@ -227,6 +280,11 @@ void AliDevice::RemoveHit(AliSignal& s)
    if (fHitCopy) delete test;
   }
  }
+ if (fOrdered)
+ {
+  AliSignal* test=(AliSignal*)fOrdered->Remove(&s);
+  if (test) fOrdered->Compress();
+ }
 }
 ///////////////////////////////////////////////////////////////////////////
 void AliDevice::RemoveHits()
@@ -237,6 +295,16 @@ void AliDevice::RemoveHits()
   delete fHits;
   fHits=0;
  }
+ if (fOrdered)
+ {
+  delete fOrdered;
+  fOrdered=0;
+ }
+ if (fMarkers)
+ {
+  delete fMarkers;
+  fMarkers=0;
+ }
 }
 ///////////////////////////////////////////////////////////////////////////
 Int_t AliDevice::GetNhits() const
@@ -263,6 +331,47 @@ AliSignal* AliDevice::GetHit(Int_t j) const
  }
 }
 ///////////////////////////////////////////////////////////////////////////
+AliSignal* AliDevice::GetHit(TString name) const
+{
+// Provide the AliSignal object registered as hit with the specified name.
+// Note : The first hit encountered with the specified name will be provided.
+
+ if (!fHits) return 0;
+
+ TString hitname;
+ Int_t nhits=GetNhits();
+ for (Int_t i=0; i<nhits; i++)
+ {
+  AliSignal* sx=(AliSignal*)fHits->At(i);
+  if (sx)
+  {
+   hitname=sx->GetName();
+   if (hitname == name) return sx;
+  }
+ }
+
+ return 0; // No matching name found
+}
+///////////////////////////////////////////////////////////////////////////
+AliSignal* AliDevice::GetIdHit(Int_t id) const
+{
+// Return the hit with unique identifier "id".
+ if (!fHits || id<0) return 0;
+
+ AliSignal* sx=0;
+ Int_t sid=0;
+ for (Int_t i=0; i<GetNhits(); i++)
+ {
+  sx=(AliSignal*)fHits->At(i);
+  if (sx)
+  {
+   sid=sx->GetUniqueID();
+   if (id==sid) return sx;
+  }
+ }
+ return 0; // No matching id found
+}
+///////////////////////////////////////////////////////////////////////////
 TObjArray* AliDevice::GetHits()
 {
 // Provide the references to all the registered hits.
@@ -290,11 +399,19 @@ void AliDevice::ShowHit(Int_t j) const
  }
 }
 ///////////////////////////////////////////////////////////////////////////
-void AliDevice::Data(TString f) const
+void AliDevice::Data(TString f,TString u) const
 {
 // Print the device and all registered hit info according to the specified
-// coordinate frame.
- AliSignal::Data(f);
+// coordinate frame f.
+//
+// The string argument "u" allows to choose between different angular units
+// in case e.g. a spherical frame is selected.
+// u = "rad" : angles provided in radians
+//     "deg" : angles provided in degrees
+//
+// The defaults are f="car" and u="rad".
+
+ AliSignal::Data(f,u);
  Int_t nhits=GetNhits();
  if (nhits)
  {
@@ -307,12 +424,105 @@ void AliDevice::Data(TString f) const
  }
 }
 ///////////////////////////////////////////////////////////////////////////
-TObjArray AliDevice::SortHits(Int_t idx,Int_t mode,TObjArray* hits) const
+void AliDevice::GetExtremes(Float_t& vmin,Float_t& vmax,Int_t idx,TObjArray* hits,Int_t mode) const
+{
+// Provide the min. and max. signal values of an array of hits.
+// The input argument "idx" denotes the index of the signal slots to be investigated.
+// The default is idx=1;
+// In case hits=0 (default), the registered hits of the current device are used. 
+// Signals which were declared as "Dead" will be rejected.
+// The gain etc... corrected signals will be used in the process as specified
+// by the  "mode" argument. The definition of this "mode" parameter corresponds to
+// the description provided in the GetSignal memberfunction of class AliSignal.
+// The default is mode=1 (for backward compatibility reasons).
+
+ vmin=0;
+ vmax=0;
+
+ if (!hits) hits=fHits;
+ if (idx<=0 || !hits) return;
+
+ Int_t nhits=hits->GetEntries();
+
+ Float_t sig=0;
+ for (Int_t i=0; i<nhits; i++)
+ {
+  AliSignal* sx=(AliSignal*)hits->At(i);
+
+  if (!sx) continue;
+  if (idx > sx->GetNvalues()) continue; // User specified slotindex out of range for this signal
+  if (sx->GetDeadValue(idx)) continue;  // Only take alive signals
+
+  sig=sx->GetSignal(idx,mode);
+  if (i==0)
+  {
+   vmin=sig;
+   vmax=sig;
+  }
+  else
+  {
+   if (sig<vmin) vmin=sig;
+   if (sig>vmax) vmax=sig;
+  }
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void AliDevice::GetExtremes(Float_t& vmin,Float_t& vmax,TString name,TObjArray* hits,Int_t mode) const
+{
+// Provide the min. and max. signal values of an array of hits.
+// The input argument "name" denotes the name of the signal slots to be investigated.
+// In case hits=0 (default), the registered hits of the current device are used. 
+// Signals which were declared as "Dead" will be rejected.
+// The gain etc... corrected signals will be used in the process as specified
+// by the  "mode" argument. The definition of this "mode" parameter corresponds to
+// the description provided in the GetSignal memberfunction of class AliSignal.
+// The default is mode=1 (for backward compatibility reasons).
+
+ vmin=0;
+ vmax=0;
+
+ if (!hits) hits=fHits;
+ if (!hits) return;
+
+ Int_t nhits=hits->GetEntries();
+
+ Int_t idx=0; // The signal slotindex to perform the sorting on
+
+ Float_t sig=0;
+ for (Int_t i=0; i<nhits; i++)
+ {
+  AliSignal* sx=(AliSignal*)hits->At(i);
+
+  if (!sx) continue;
+
+  // Obtain the slotindex corresponding to the user selection
+  idx=sx->GetSlotIndex(name);
+  if (!idx) continue;
+
+  if (sx->GetDeadValue(idx)) continue; // Only take alive signals
+
+  sig=sx->GetSignal(idx,mode);
+  if (i==0)
+  {
+   vmin=sig;
+   vmax=sig;
+  }
+  else
+  {
+   if (sig<vmin) vmin=sig;
+   if (sig>vmax) vmax=sig;
+  }
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+TObjArray* AliDevice::SortHits(Int_t idx,Int_t mode,TObjArray* hits,Int_t mcal)
 {
 // Order the references to an array of hits by looping over the input array "hits"
 // and checking the signal value. The ordered array is returned as a TObjArray.
 // In case hits=0 (default), the registered hits of the current device are used. 
-// Note that the original hit array in not modified.
+// Note that the original hit array is not modified.
 // 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.
@@ -320,22 +530,30 @@ TObjArray AliDevice::SortHits(Int_t idx,Int_t mode,TObjArray* hits) const
 // 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.
+// The gain etc... corrected signals will be used in the ordering process as
+// specified by the "mcal" argument. The definition of this "mcal" parameter
+// corresponds to the signal correction mode described in the GetSignal
+// memberfunction of class AliSignal.
+// The default is mcal=1 (for backward compatibility reasons).
 
- TObjArray ordered;
+ if (fOrdered)
+ {
+  delete fOrdered;
+  fOrdered=0;
+ }
 
  if (!hits) hits=fHits;
  
- if (idx<=0 || abs(mode)!=1 || !hits) return ordered;
+ if (idx<=0 || abs(mode)!=1 || !hits) return fOrdered;
 
  Int_t nhits=hits->GetEntries();
  if (!nhits)
  {
-  return ordered;
+  return fOrdered;
  }
  else
  {
-  ordered.Expand(nhits);
+  fOrdered=new TObjArray(nhits);
  }
 
  Int_t nord=0;
@@ -351,7 +569,7 @@ TObjArray AliDevice::SortHits(Int_t idx,Int_t mode,TObjArray* hits) const
   if (nord == 0) // store the first hit with a signal at the first ordered position
   {
    nord++;
-   ordered.AddAt(s,nord-1);
+   fOrdered->AddAt(s,nord-1);
    continue;
   }
  
@@ -360,31 +578,31 @@ TObjArray AliDevice::SortHits(Int_t idx,Int_t mode,TObjArray* hits) const
    if (j == nord) // module has smallest (mode=-1) or largest (mode=1) signal seen so far
    {
     nord++;
-    ordered.AddAt(s,j); // add hit at the end
+    fOrdered->AddAt(s,j); // add hit at the end
     break; // go for next hit
    }
  
-   if (mode==-1 && s->GetSignal(idx,1) < ((AliSignal*)ordered.At(j))->GetSignal(idx,1)) continue;
-   if (mode==1 && s->GetSignal(idx,1) > ((AliSignal*)ordered.At(j))->GetSignal(idx,1)) continue;
+   if (mode==-1 && s->GetSignal(idx,mcal) <= ((AliSignal*)fOrdered->At(j))->GetSignal(idx,mcal)) continue;
+   if (mode==1 && s->GetSignal(idx,mcal) >= ((AliSignal*)fOrdered->At(j))->GetSignal(idx,mcal)) continue;
  
    nord++;
    for (Int_t k=nord-1; k>j; k--) // create empty position
    {
-    ordered.AddAt(ordered.At(k-1),k);
+    fOrdered->AddAt(fOrdered->At(k-1),k);
    }
-   ordered.AddAt(s,j); // put hit at empty position
-   break; // go for next matrix module
+   fOrdered->AddAt(s,j); // put hit at empty position
+   break; // go for next hit
   }
  }
- return ordered;
+ return fOrdered;
 }
 ///////////////////////////////////////////////////////////////////////////
-TObjArray AliDevice::SortHits(TString name,Int_t mode,TObjArray* hits) const
+TObjArray* AliDevice::SortHits(TString name,Int_t mode,TObjArray* hits,Int_t mcal)
 {
 // Order the references to an array of hits by looping over the input array "hits"
 // and checking the signal value. The ordered array is returned as a TObjArray.
 // In case hits=0 (default), the registered hits of the current device are used. 
-// Note that the input array in not modified.
+// Note that the input array is not modified.
 // 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.
@@ -392,22 +610,30 @@ TObjArray AliDevice::SortHits(TString name,Int_t mode,TObjArray* hits) const
 // 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.
+// The gain etc... corrected signals will be used in the ordering process as
+// specified by the "mcal" argument. The definition of this "mcal" parameter
+// corresponds to the signal correction mode described in the GetSignal
+// memberfunction of class AliSignal.
+// The default is mcal=1 (for backward compatibility reasons).
 
- TObjArray ordered;
+ if (fOrdered)
+ {
+  delete fOrdered;
+  fOrdered=0;
+ }
 
  if (!hits) hits=fHits;
  
- if (abs(mode)!=1 || !hits) return ordered;
+ if (abs(mode)!=1 || !hits) return fOrdered;
 
  Int_t nhits=hits->GetEntries();
  if (!nhits)
  {
-  return ordered;
+  return fOrdered;
  }
  else
  {
-  ordered.Expand(nhits);
+  fOrdered=new TObjArray(nhits);
  }
 
  Int_t idx=0; // The signal slotindex to perform the sorting on
@@ -428,7 +654,7 @@ TObjArray AliDevice::SortHits(TString name,Int_t mode,TObjArray* hits) const
   if (nord == 0) // store the first hit with a signal at the first ordered position
   {
    nord++;
-   ordered.AddAt(s,nord-1);
+   fOrdered->AddAt(s,nord-1);
    continue;
   }
  
@@ -437,23 +663,223 @@ TObjArray AliDevice::SortHits(TString name,Int_t mode,TObjArray* hits) const
    if (j == nord) // module has smallest (mode=-1) or largest (mode=1) signal seen so far
    {
     nord++;
-    ordered.AddAt(s,j); // add hit at the end
+    fOrdered->AddAt(s,j); // add hit at the end
     break; // go for next hit
    }
  
-   if (mode==-1 && s->GetSignal(idx,1) < ((AliSignal*)ordered.At(j))->GetSignal(idx,1)) continue;
-   if (mode==1 && s->GetSignal(idx,1) > ((AliSignal*)ordered.At(j))->GetSignal(idx,1)) continue;
+   if (mode==-1 && s->GetSignal(idx,mcal) <= ((AliSignal*)fOrdered->At(j))->GetSignal(idx,mcal)) continue;
+   if (mode==1 && s->GetSignal(idx,mcal) >= ((AliSignal*)fOrdered->At(j))->GetSignal(idx,mcal)) continue;
  
    nord++;
    for (Int_t k=nord-1; k>j; k--) // create empty position
    {
-    ordered.AddAt(ordered.At(k-1),k);
+    fOrdered->AddAt(fOrdered->At(k-1),k);
+   }
+   fOrdered->AddAt(s,j); // put hit at empty position
+   break; // go for next hit
+  }
+ }
+ return fOrdered;
+}
+///////////////////////////////////////////////////////////////////////////
+void AliDevice::DisplayHits(Int_t idx,Float_t scale,TObjArray* hits,Int_t dp,Int_t mode,Int_t mcol)
+{
+// 3D color display of an array hits.
+// 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 hits=0 (default), the registered hits of the current device are used. 
+// Note that the input array is not modified.
+// In case dp=1 the device position will be used, otherwise the hit position will
+// be used in the display. The default is dp=0.
+// Via the "mcol" argument the user can specify the marker color (see TPolyMarker3D).
+// The default is 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.
+// The gain correction is performed according to "mode" argument. The definition of this
+// "mode" parameter corresponds to the description provided in the GetSignal
+// memberfunction of class AliSignal.
+// The default is mode=1 (for backward compatibility reasons).
+//
+// 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();
+
+ Int_t thisdev=0; // Indicate whether this is the owning device or not 
+ if (!hits)
+ {
+  hits=fHits;
+  thisdev=1;
+ }
+ if (idx<=0 || !hits) return;
+
+ Int_t nhits=hits->GetEntries();
+ if (!nhits) return;
+
+ Float_t sigmax=fabs(scale);
+ if (scale<0)
+ {
+  Float_t vmin,vmax;
+  GetExtremes(vmin,vmax,idx,hits,mode);
+  sigmax=fabs(vmax);
+  if (fabs(vmin)>sigmax) sigmax=fabs(vmin);
+ }
+
+ if (sigmax <=0) return;
+
+ if (fMarkers)
+ {
+  delete fMarkers;
+  fMarkers=0;
+ }
+ fMarkers=new TObjArray(nhits);
+ fMarkers->SetOwner();
+
+ Float_t pos[3];
+ GetPosition(pos,"car");
+
+ Float_t sig=0;
+ for (Int_t ih=0; ih<nhits; ih++)
+ {
+  AliSignal* sx=(AliSignal*)hits->At(ih);
+  if (!sx) continue;
+  if (!dp)
+  {
+   sx->GetPosition(pos,"car");
+  }
+  else
+  {
+   if (!thisdev)
+   {
+    AliDevice* dev=sx->GetDevice();
+    if (dev) dev->GetPosition(pos,"car");
    }
-   ordered.AddAt(s,j); // put hit at empty position
-   break; // go for next matrix module
   }
+  sig=sx->GetSignal(idx,mode);
+
+  // Skip dead signals
+  if (fabs(sig) <= 0.) continue;
+
+  TPolyMarker3D* m=new TPolyMarker3D();
+  m->SetMarkerStyle(8);
+  m->SetMarkerColor(mcol);
+  m->SetMarkerSize(100.*fabs(sig)/sigmax);
+  m->SetPoint(0,pos[0],pos[1],pos[2]);
+  fMarkers->Add(m);
+  m->Draw();
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void AliDevice::DisplayHits(TString name,Float_t scale,TObjArray* hits,Int_t dp,Int_t mode,Int_t mcol)
+{
+// 3D color display of an array hits.
+// 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 hits=0 (default), the registered hits of the current device are used. 
+// Note that the input array is not modified.
+// In case dp=1 the 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 "mcol" argument the user can specify the marker color (see TPolyMarker3D).
+// The default is 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.
+// The gain correction is performed according to "mode" argument. The definition of this
+// "mode" parameter corresponds to the description provided in the GetSignal
+// memberfunction of class AliSignal.
+// The default is mode=1 (for backward compatibility reasons).
+//
+// 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();
+
+ Int_t thisdev=0; // Indicate whether this is the owning device or not 
+ if (!hits)
+ {
+  hits=fHits;
+  thisdev=1;
+ }
+ if (!hits) return;
+
+ Int_t nhits=hits->GetEntries();
+
+ if (!nhits) return;
+
+ Float_t sigmax=fabs(scale);
+ if (scale<0)
+ {
+  Float_t vmin,vmax;
+  GetExtremes(vmin,vmax,name,hits,mode);
+  sigmax=fabs(vmax);
+  if (fabs(vmin)>sigmax) sigmax=fabs(vmin);
+ }
+
+ if (sigmax <=0) return;
+
+ if (fMarkers)
+ {
+  delete fMarkers;
+  fMarkers=0;
+ }
+ fMarkers=new TObjArray(nhits);
+ fMarkers->SetOwner();
+
+ Float_t pos[3];
+ GetPosition(pos,"car");
+
+ Int_t idx=0; // The slot index corresponding to the user specified name
+ Float_t sig=0;
+ for (Int_t ih=0; ih<nhits; ih++)
+ {
+  AliSignal* sx=(AliSignal*)hits->At(ih);
+  if (!sx) continue;
+  idx=sx->GetSlotIndex(name);
+  if (!idx) continue;
+  if (!dp)
+  {
+   sx->GetPosition(pos,"car");
+  }
+  else
+  {
+   if (!thisdev)
+   {
+    AliDevice* dev=sx->GetDevice();
+    if (dev) dev->GetPosition(pos,"car");
+   }
+  }
+  sig=sx->GetSignal(idx,mode);
+
+  // Skip dead signals
+  if (fabs(sig) <= 0.) continue;
+
+  TPolyMarker3D* m=new TPolyMarker3D();
+  m->SetMarkerStyle(8);
+  m->SetMarkerColor(mcol);
+  m->SetMarkerSize(100.*fabs(sig)/sigmax);
+  m->SetPoint(0,pos[0],pos[1],pos[2]);
+  fMarkers->Add(m);
+  m->Draw();
  }
- return ordered;
 }
 ///////////////////////////////////////////////////////////////////////////
 TObject* AliDevice::Clone(const char* name) const