]> git.uio.no Git - u/mrichter/AliRoot.git/blob - RALICE/AliDevice.cxx
24-jun-2004 NvE Coefficient kp7 changed from 7.4e-5 to 7.4e-6 in AliMath::BesselK0...
[u/mrichter/AliRoot.git] / RALICE / AliDevice.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 // $Id$
17
18 ///////////////////////////////////////////////////////////////////////////
19 // Class AliDevice
20 // Signal (Hit) handling of a generic device.
21 // Basically this class provides a user interface to group and handle
22 // various instances of AliSignal objects, called generically "hits".
23 // An AliDevice object itself has (in addition to hit storage) also the
24 // complete functionality of the class AliSignal.
25 //
26 // Example :
27 // =========
28 //
29 // AliDevice m;
30 // m.SetHitCopy(1);
31 // m.SetName("OM123");
32 //
33 // Float_t pos[3]={1,2,3};
34 // m.SetPosition(pos,"car");
35 //
36 // AliSignal s;
37 //
38 // s.Reset(1);
39 // s.SetName("OM123 Hit 1");
40 // s.SetSlotName("ADC");
41 // s.SetSignal(10);
42 // s.SetSlotName("LE",2);
43 // s.SetSignal(-100,2);
44 // s.SetSlotName("TOT",3);
45 // s.SetSignal(-1000,3);
46 // m.AddHit(s);
47 //
48 // s.Reset(1);
49 // s.SetName("OM123 Hit 2");
50 // s.SetSlotName("ADC");
51 // s.SetSignal(11);
52 // s.SetSlotName("LE",2);
53 // s.SetSignal(-101,2);
54 // s.SetSlotName("TOT",3);
55 // s.SetSignal(1001,3);
56 // m.AddHit(s);
57 //
58 // s.Reset(1);
59 // s.SetName("OM123 Hit 3");
60 // s.SetSlotName("ADC");
61 // s.SetSignal(12);
62 // s.SetSlotName("LE",2);
63 // s.SetSignal(-102,2);
64 // s.SetSlotName("TOT",3);
65 // s.SetSignal(-1002,3);
66 // m.AddHit(s);
67 //
68 // TObjArray ordered=m.SortHits("TOT");
69 // nhits=ordered.GetEntries();
70 // for (Int_t i=0; i<nhits; i++)
71 // {
72 //  AliSignal* sx=(AliSignal*)ordered.At(i);
73 //  if (sx) sx->Data();
74 // }
75 //
76 //--- Author: Nick van Eijndhoven 23-jun-2004 Utrecht University
77 //- Modified: NvE $Date$ Utrecht University
78 ///////////////////////////////////////////////////////////////////////////
79
80 #include "AliDevice.h"
81 #include "Riostream.h"
82  
83 ClassImp(AliDevice) // Class implementation to enable ROOT I/O
84  
85 AliDevice::AliDevice() : AliSignal()
86 {
87 // Default constructor.
88  fHitCopy=0;
89  fHits=0;
90 }
91 ///////////////////////////////////////////////////////////////////////////
92 AliDevice::~AliDevice()
93 {
94 // Default destructor.
95  if (fHits)
96  {
97   delete fHits;
98   fHits=0;
99  }
100 }
101 ///////////////////////////////////////////////////////////////////////////
102 AliDevice::AliDevice(const AliDevice& dev) : AliSignal(dev)
103 {
104 // Copy constructor.
105  fHitCopy=dev.GetHitCopy();
106  Int_t nhits=dev.GetNhits();
107  if (nhits)
108  {
109   fHits=new TObjArray(nhits);
110   if (fHitCopy) fHits->SetOwner();
111   for (Int_t ih=1; ih<=nhits; ih++)
112   {
113    AliSignal* sx=dev.GetHit(ih);
114    if (fHitCopy)
115    {
116     fHits->Add(sx->Clone());
117     Int_t nhits=GetNhits();
118     AliSignal* s=GetHit(nhits);
119     s->ResetLinks((AliDevice*)&dev);
120     s->AddLink(this);
121    }
122    else
123    {
124     sx->AddLink(this);
125     fHits->Add(sx);
126    }
127   }
128  }
129 }
130 ///////////////////////////////////////////////////////////////////////////
131 void AliDevice::Reset(Int_t mode)
132 {
133 // Reset registered hits and AliSignal attributes.
134 // See AliSignal::Reset() for further details.
135  RemoveHits();
136  AliSignal::Reset(mode);
137 }
138 ///////////////////////////////////////////////////////////////////////////
139 void AliDevice::SetHitCopy(Int_t j)
140 {
141 // (De)activate the creation of private copies of the AliSignals added as hits.
142 // j=0 ==> No private copies are made; pointers of original hits are stored.
143 // j=1 ==> Private copies of the hits are made and these pointers are stored.
144 //
145 // Note : Once the storage contains pointer(s) to hit(s) one cannot
146 //        change the HitCopy mode anymore.
147 //        To change the HitCopy mode for an existing AliDevice containing
148 //        hits one first has to invoke either RemoveHits() or Reset().
149  if (!fHits)
150  {
151   if (j==0 || j==1)
152   {
153    fHitCopy=j;
154   }
155   else
156   {
157    cout << "*AliDevice::SetHitCopy* Invalid argument : " << j << endl;
158   }
159  }
160  else
161  {
162   cout << "*AliDevice::SetHitCopy* Storage already contained hits."
163        << "  ==> HitCopy mode not changed." << endl; 
164  }
165 }
166 ///////////////////////////////////////////////////////////////////////////
167 Int_t AliDevice::GetHitCopy() const
168 {
169 // Provide value of the HitCopy mode.
170 // 0 ==> No private copies are made; pointers of original hits are stored.
171 // 1 ==> Private copies of the hits are made and these pointers are stored.
172  return fHitCopy;
173 }
174 ///////////////////////////////////////////////////////////////////////////
175 void AliDevice::AddHit(AliSignal& s)
176 {
177 // Register an AliSignal object as a hit to this device.
178 // Note : A (backward) link to this device is added to the first slot of
179 //        the AliSignal if there was no link to this device already present.
180  if (!fHits)
181  {
182   fHits=new TObjArray(1);
183   if (fHitCopy) fHits->SetOwner();
184  }
185
186  // Check if this signal is already stored for this device.
187  Int_t nhits=GetNhits();
188  for (Int_t i=0; i<nhits; i++)
189  {
190   if (&s==fHits->At(i)) return; 
191  }
192
193  // Set the (backward) link to this device.
194  Int_t nlinks=GetNlinks(this);
195  if (!nlinks) s.AddLink(this);
196
197  if (fHitCopy)
198  {
199   fHits->Add(s.Clone());
200  }
201  else
202  {
203   fHits->Add(&s);
204  }
205 }
206 ///////////////////////////////////////////////////////////////////////////
207 void AliDevice::RemoveHit(AliSignal& s)
208 {
209 // Remove AliSignal object registered as a hit from this device.
210  if (fHits)
211  {
212   AliSignal* test=(AliSignal*)fHits->Remove(&s);
213   if (test)
214   {
215    fHits->Compress();
216    if (fHitCopy) delete test;
217   }
218  }
219 }
220 ///////////////////////////////////////////////////////////////////////////
221 void AliDevice::RemoveHits()
222 {
223 // Remove all AliSignal objects registered as hits from this device.
224  if (fHits)
225  {
226   delete fHits;
227   fHits=0;
228  }
229 }
230 ///////////////////////////////////////////////////////////////////////////
231 Int_t AliDevice::GetNhits() const
232 {
233 // Provide the number of registered hits for this device.
234  Int_t nhits=0;
235  if (fHits) nhits=fHits->GetEntries();
236  return nhits;
237 }
238 ///////////////////////////////////////////////////////////////////////////
239 AliSignal* AliDevice::GetHit(Int_t j) const
240 {
241 // Provide the AliSignal object registered as hit number j.
242 // Note : j=1 denotes the first hit.
243  if (!fHits) return 0;
244
245  if ((j >= 1) && (j <= GetNhits()))
246  {
247   return (AliSignal*)fHits->At(j-1);
248  }
249  else
250  {
251   return 0;
252  }
253 }
254 ///////////////////////////////////////////////////////////////////////////
255 TObjArray* AliDevice::GetHits()
256 {
257 // Provide the references to all the registered hits.
258  return fHits;
259 }
260 ///////////////////////////////////////////////////////////////////////////
261 void AliDevice::ShowHit(Int_t j) const
262 {
263 // Show data of the registered j-th hit.
264 // If j=0 all associated hits will be shown.
265 // The default is j=0.
266  if (!j)
267  {
268   Int_t nhits=GetNhits();
269   for (Int_t ih=1; ih<=nhits; ih++)
270   {
271    AliSignal* sx=GetHit(ih);
272    if (sx) sx->Data();
273   }
274  }
275  else
276  {
277   AliSignal* s=GetHit(j);
278   if (s) s->Data();
279  }
280 }
281 ///////////////////////////////////////////////////////////////////////////
282 void AliDevice::Data(TString f) const
283 {
284 // Print the device and all registered hit info according to the specified
285 // coordinate frame.
286  AliSignal::Data(f);
287  Int_t nhits=GetNhits();
288  if (nhits)
289  {
290   cout << " The following " << nhits << " hits are registered : " << endl;
291   ShowHit();
292  }
293  else
294  {
295   cout << " No hits have been registered for this device." << endl;
296  }
297 }
298 ///////////////////////////////////////////////////////////////////////////
299 TObjArray AliDevice::SortHits(Int_t idx,Int_t mode,TObjArray* hits) const
300 {
301 // Order the references to an array of hits by looping over the input array "hits"
302 // and checking the signal value. The ordered array is returned as a TObjArray.
303 // In case hits=0 (default), the registered hits of the current device are used. 
304 // Note that the original hit array in not modified.
305 // A "hit" represents an abstract object which is derived from AliSignal.
306 // The user can specify the index of the signal slot to perform the sorting on.
307 // By default the slotindex will be 1.
308 // Via the "mode" argument the user can specify ordering in decreasing
309 // order (mode=-1) or ordering in increasing order (mode=1).
310 // The default is mode=-1.
311 // Signals which were declared as "Dead" will be rejected.
312 // The gain etc... corrected signals will be used in the ordering process.
313
314  TObjArray ordered;
315
316  if (!hits) hits=fHits;
317  
318  if (idx<=0 || abs(mode)!=1 || !hits) return ordered;
319
320  Int_t nhits=hits->GetEntries();
321  if (!nhits)
322  {
323   return ordered;
324  }
325  else
326  {
327   ordered.Expand(nhits);
328  }
329
330  Int_t nord=0;
331  for (Int_t i=0; i<nhits; i++) // Loop over all hits of the array
332  {
333   AliSignal* s=(AliSignal*)hits->At(i);
334
335   if (!s) continue;
336
337   if (idx > s->GetNvalues()) continue; // User specified slotindex out of range for this signal
338   if (s->GetDeadValue(idx)) continue;  // Only take alive signals
339  
340   if (nord == 0) // store the first hit with a signal at the first ordered position
341   {
342    nord++;
343    ordered.AddAt(s,nord-1);
344    continue;
345   }
346  
347   for (Int_t j=0; j<=nord; j++) // put hit in the right ordered position
348   {
349    if (j == nord) // module has smallest (mode=-1) or largest (mode=1) signal seen so far
350    {
351     nord++;
352     ordered.AddAt(s,j); // add hit at the end
353     break; // go for next hit
354    }
355  
356    if (mode==-1 && s->GetSignal(idx,1) < ((AliSignal*)ordered.At(j))->GetSignal(idx,1)) continue;
357    if (mode==1 && s->GetSignal(idx,1) > ((AliSignal*)ordered.At(j))->GetSignal(idx,1)) continue;
358  
359    nord++;
360    for (Int_t k=nord-1; k>j; k--) // create empty position
361    {
362     ordered.AddAt(ordered.At(k-1),k);
363    }
364    ordered.AddAt(s,j); // put hit at empty position
365    break; // go for next matrix module
366   }
367  }
368  return ordered;
369 }
370 ///////////////////////////////////////////////////////////////////////////
371 TObjArray AliDevice::SortHits(TString name,Int_t mode,TObjArray* hits) const
372 {
373 // Order the references to an array of hits by looping over the input array "hits"
374 // and checking the signal value. The ordered array is returned as a TObjArray.
375 // In case hits=0 (default), the registered hits of the current device are used. 
376 // Note that the input array in not modified.
377 // A "hit" represents an abstract object which is derived from AliSignal.
378 // The user can specify the name of the signal slot to perform the sorting on.
379 // In case no matching slotname is found, the signal will be skipped.
380 // Via the "mode" argument the user can specify ordering in decreasing
381 // order (mode=-1) or ordering in increasing order (mode=1).
382 // The default is mode=-1.
383 // Signals which were declared as "Dead" will be rejected.
384 // The gain etc... corrected signals will be used in the ordering process.
385
386  TObjArray ordered;
387
388  if (!hits) hits=fHits;
389  
390  if (abs(mode)!=1 || !hits) return ordered;
391
392  Int_t nhits=hits->GetEntries();
393  if (!nhits)
394  {
395   return ordered;
396  }
397  else
398  {
399   ordered.Expand(nhits);
400  }
401
402  Int_t idx=0; // The signal slotindex to perform the sorting on
403
404  Int_t nord=0;
405  for (Int_t i=0; i<nhits; i++) // loop over all hits of the array
406  {
407   AliSignal* s=(AliSignal*)hits->At(i);
408
409   if (!s) continue;
410
411   // Obtain the slotindex corresponding to the user selection
412   idx=s->GetSlotIndex(name);
413   if (!idx) continue;
414
415   if (s->GetDeadValue(idx)) continue; // only take alive signals
416  
417   if (nord == 0) // store the first hit with a signal at the first ordered position
418   {
419    nord++;
420    ordered.AddAt(s,nord-1);
421    continue;
422   }
423  
424   for (Int_t j=0; j<=nord; j++) // put hit in the right ordered position
425   {
426    if (j == nord) // module has smallest (mode=-1) or largest (mode=1) signal seen so far
427    {
428     nord++;
429     ordered.AddAt(s,j); // add hit at the end
430     break; // go for next hit
431    }
432  
433    if (mode==-1 && s->GetSignal(idx,1) < ((AliSignal*)ordered.At(j))->GetSignal(idx,1)) continue;
434    if (mode==1 && s->GetSignal(idx,1) > ((AliSignal*)ordered.At(j))->GetSignal(idx,1)) continue;
435  
436    nord++;
437    for (Int_t k=nord-1; k>j; k--) // create empty position
438    {
439     ordered.AddAt(ordered.At(k-1),k);
440    }
441    ordered.AddAt(s,j); // put hit at empty position
442    break; // go for next matrix module
443   }
444  }
445  return ordered;
446 }
447 ///////////////////////////////////////////////////////////////////////////
448 TObject* AliDevice::Clone(const char* name) const
449 {
450 // Make a deep copy of the current object and provide the pointer to the copy.
451 // This memberfunction enables automatic creation of new objects of the
452 // correct type depending on the object type, a feature which may be very useful
453 // for containers like AliEvent when adding objects in case the
454 // container owns the objects. This feature allows e.g. AliEvent
455 // to store either AliDevice objects or objects derived from AliDevice
456 // via tha AddDevice memberfunction, provided these derived classes also have
457 // a proper Clone memberfunction. 
458
459  AliDevice* dev=new AliDevice(*this);
460  if (name)
461  {
462   if (strlen(name)) dev->SetName(name);
463  }
464  return dev;
465 }
466 ///////////////////////////////////////////////////////////////////////////