]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RALICE/AliDevice.cxx
Stand-alone library for ESD. Possibility to use only root and lidESD.so for analysis...
[u/mrichter/AliRoot.git] / RALICE / AliDevice.cxx
CommitLineData
7a086578 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//
7b825f44 68// TObjArray* ordered=m.SortHits("TOT");
69// nhits=ordered->GetEntries();
7a086578 70// for (Int_t i=0; i<nhits; i++)
71// {
7b825f44 72// AliSignal* sx=(AliSignal*)ordered->At(i);
7a086578 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
83ClassImp(AliDevice) // Class implementation to enable ROOT I/O
84
85AliDevice::AliDevice() : AliSignal()
86{
87// Default constructor.
7b825f44 88// By default private copies of the recorded hits will be made.
89// This implies that by default the device will own the registered hits.
90// See the SetHitCopy() memberfunction for further details.
91 fHitCopy=1;
7a086578 92 fHits=0;
7b825f44 93 fOrdered=0;
7a086578 94}
95///////////////////////////////////////////////////////////////////////////
96AliDevice::~AliDevice()
97{
98// Default destructor.
b055c99d 99
100 // Remove backward links to this device from the hits
101 // which were not owned by it.
102 if (!fHitCopy)
103 {
104 for (Int_t ih=1; ih<=GetNhits(); ih++)
105 {
106 AliSignal* sx=GetHit(ih);
107 if (sx) sx->ResetLinks(this);
108 }
109 }
110
7a086578 111 if (fHits)
112 {
113 delete fHits;
114 fHits=0;
115 }
7b825f44 116
117 if (fOrdered)
118 {
119 delete fOrdered;
120 fOrdered=0;
121 }
7a086578 122}
123///////////////////////////////////////////////////////////////////////////
124AliDevice::AliDevice(const AliDevice& dev) : AliSignal(dev)
125{
126// Copy constructor.
7b825f44 127
128 fHits=0;
129 fOrdered=0;
130
7a086578 131 fHitCopy=dev.GetHitCopy();
7b825f44 132
7a086578 133 Int_t nhits=dev.GetNhits();
134 if (nhits)
135 {
136 fHits=new TObjArray(nhits);
137 if (fHitCopy) fHits->SetOwner();
138 for (Int_t ih=1; ih<=nhits; ih++)
139 {
140 AliSignal* sx=dev.GetHit(ih);
141 if (fHitCopy)
142 {
143 fHits->Add(sx->Clone());
b055c99d 144 AliSignal* s=(AliSignal*)fHits->Last();
7a086578 145 s->ResetLinks((AliDevice*)&dev);
146 s->AddLink(this);
147 }
148 else
149 {
150 sx->AddLink(this);
151 fHits->Add(sx);
152 }
153 }
154 }
155}
156///////////////////////////////////////////////////////////////////////////
157void AliDevice::Reset(Int_t mode)
158{
159// Reset registered hits and AliSignal attributes.
160// See AliSignal::Reset() for further details.
161 RemoveHits();
162 AliSignal::Reset(mode);
163}
164///////////////////////////////////////////////////////////////////////////
165void AliDevice::SetHitCopy(Int_t j)
166{
167// (De)activate the creation of private copies of the AliSignals added as hits.
168// j=0 ==> No private copies are made; pointers of original hits are stored.
169// j=1 ==> Private copies of the hits are made and these pointers are stored.
170//
171// Note : Once the storage contains pointer(s) to hit(s) one cannot
172// change the HitCopy mode anymore.
173// To change the HitCopy mode for an existing AliDevice containing
174// hits one first has to invoke either RemoveHits() or Reset().
175 if (!fHits)
176 {
177 if (j==0 || j==1)
178 {
179 fHitCopy=j;
180 }
181 else
182 {
183 cout << "*AliDevice::SetHitCopy* Invalid argument : " << j << endl;
184 }
185 }
186 else
187 {
188 cout << "*AliDevice::SetHitCopy* Storage already contained hits."
189 << " ==> HitCopy mode not changed." << endl;
190 }
191}
192///////////////////////////////////////////////////////////////////////////
193Int_t AliDevice::GetHitCopy() const
194{
195// Provide value of the HitCopy mode.
196// 0 ==> No private copies are made; pointers of original hits are stored.
197// 1 ==> Private copies of the hits are made and these pointers are stored.
198 return fHitCopy;
199}
200///////////////////////////////////////////////////////////////////////////
201void AliDevice::AddHit(AliSignal& s)
202{
203// Register an AliSignal object as a hit to this device.
204// Note : A (backward) link to this device is added to the first slot of
205// the AliSignal if there was no link to this device already present.
206 if (!fHits)
207 {
208 fHits=new TObjArray(1);
209 if (fHitCopy) fHits->SetOwner();
210 }
211
212 // Check if this signal is already stored for this device.
213 Int_t nhits=GetNhits();
214 for (Int_t i=0; i<nhits; i++)
215 {
216 if (&s==fHits->At(i)) return;
217 }
218
219 // Set the (backward) link to this device.
220 Int_t nlinks=GetNlinks(this);
221 if (!nlinks) s.AddLink(this);
222
223 if (fHitCopy)
224 {
225 fHits->Add(s.Clone());
226 }
227 else
228 {
229 fHits->Add(&s);
230 }
231}
232///////////////////////////////////////////////////////////////////////////
233void AliDevice::RemoveHit(AliSignal& s)
234{
235// Remove AliSignal object registered as a hit from this device.
236 if (fHits)
237 {
238 AliSignal* test=(AliSignal*)fHits->Remove(&s);
239 if (test)
240 {
241 fHits->Compress();
242 if (fHitCopy) delete test;
243 }
244 }
7b825f44 245 if (fOrdered)
246 {
247 AliSignal* test=(AliSignal*)fOrdered->Remove(&s);
248 if (test) fOrdered->Compress();
249 }
7a086578 250}
251///////////////////////////////////////////////////////////////////////////
252void AliDevice::RemoveHits()
253{
254// Remove all AliSignal objects registered as hits from this device.
255 if (fHits)
256 {
257 delete fHits;
258 fHits=0;
259 }
7b825f44 260 if (fOrdered)
261 {
262 delete fOrdered;
263 fOrdered=0;
264 }
7a086578 265}
266///////////////////////////////////////////////////////////////////////////
267Int_t AliDevice::GetNhits() const
268{
269// Provide the number of registered hits for this device.
270 Int_t nhits=0;
271 if (fHits) nhits=fHits->GetEntries();
272 return nhits;
273}
274///////////////////////////////////////////////////////////////////////////
275AliSignal* AliDevice::GetHit(Int_t j) const
276{
277// Provide the AliSignal object registered as hit number j.
278// Note : j=1 denotes the first hit.
279 if (!fHits) return 0;
280
281 if ((j >= 1) && (j <= GetNhits()))
282 {
283 return (AliSignal*)fHits->At(j-1);
284 }
285 else
286 {
287 return 0;
288 }
289}
290///////////////////////////////////////////////////////////////////////////
291TObjArray* AliDevice::GetHits()
292{
293// Provide the references to all the registered hits.
294 return fHits;
295}
296///////////////////////////////////////////////////////////////////////////
297void AliDevice::ShowHit(Int_t j) const
298{
299// Show data of the registered j-th hit.
300// If j=0 all associated hits will be shown.
301// The default is j=0.
302 if (!j)
303 {
304 Int_t nhits=GetNhits();
305 for (Int_t ih=1; ih<=nhits; ih++)
306 {
307 AliSignal* sx=GetHit(ih);
308 if (sx) sx->Data();
309 }
310 }
311 else
312 {
313 AliSignal* s=GetHit(j);
314 if (s) s->Data();
315 }
316}
317///////////////////////////////////////////////////////////////////////////
318void AliDevice::Data(TString f) const
319{
320// Print the device and all registered hit info according to the specified
321// coordinate frame.
322 AliSignal::Data(f);
323 Int_t nhits=GetNhits();
324 if (nhits)
325 {
326 cout << " The following " << nhits << " hits are registered : " << endl;
327 ShowHit();
328 }
329 else
330 {
331 cout << " No hits have been registered for this device." << endl;
332 }
333}
334///////////////////////////////////////////////////////////////////////////
7b825f44 335TObjArray* AliDevice::SortHits(Int_t idx,Int_t mode,TObjArray* hits)
7a086578 336{
337// Order the references to an array of hits by looping over the input array "hits"
338// and checking the signal value. The ordered array is returned as a TObjArray.
339// In case hits=0 (default), the registered hits of the current device are used.
340// Note that the original hit array in not modified.
341// A "hit" represents an abstract object which is derived from AliSignal.
342// The user can specify the index of the signal slot to perform the sorting on.
343// By default the slotindex will be 1.
344// Via the "mode" argument the user can specify ordering in decreasing
345// order (mode=-1) or ordering in increasing order (mode=1).
346// The default is mode=-1.
347// Signals which were declared as "Dead" will be rejected.
348// The gain etc... corrected signals will be used in the ordering process.
349
7b825f44 350 if (fOrdered)
351 {
352 delete fOrdered;
353 fOrdered=0;
354 }
7a086578 355
356 if (!hits) hits=fHits;
357
7b825f44 358 if (idx<=0 || abs(mode)!=1 || !hits) return fOrdered;
7a086578 359
360 Int_t nhits=hits->GetEntries();
361 if (!nhits)
362 {
7b825f44 363 return fOrdered;
7a086578 364 }
365 else
366 {
7b825f44 367 fOrdered=new TObjArray(nhits);
7a086578 368 }
369
370 Int_t nord=0;
371 for (Int_t i=0; i<nhits; i++) // Loop over all hits of the array
372 {
373 AliSignal* s=(AliSignal*)hits->At(i);
374
375 if (!s) continue;
376
377 if (idx > s->GetNvalues()) continue; // User specified slotindex out of range for this signal
378 if (s->GetDeadValue(idx)) continue; // Only take alive signals
379
380 if (nord == 0) // store the first hit with a signal at the first ordered position
381 {
382 nord++;
7b825f44 383 fOrdered->AddAt(s,nord-1);
7a086578 384 continue;
385 }
386
387 for (Int_t j=0; j<=nord; j++) // put hit in the right ordered position
388 {
389 if (j == nord) // module has smallest (mode=-1) or largest (mode=1) signal seen so far
390 {
391 nord++;
7b825f44 392 fOrdered->AddAt(s,j); // add hit at the end
7a086578 393 break; // go for next hit
394 }
395
7b825f44 396 if (mode==-1 && s->GetSignal(idx,1) < ((AliSignal*)fOrdered->At(j))->GetSignal(idx,1)) continue;
397 if (mode==1 && s->GetSignal(idx,1) > ((AliSignal*)fOrdered->At(j))->GetSignal(idx,1)) continue;
7a086578 398
399 nord++;
400 for (Int_t k=nord-1; k>j; k--) // create empty position
401 {
7b825f44 402 fOrdered->AddAt(fOrdered->At(k-1),k);
7a086578 403 }
7b825f44 404 fOrdered->AddAt(s,j); // put hit at empty position
7a086578 405 break; // go for next matrix module
406 }
407 }
7b825f44 408 return fOrdered;
7a086578 409}
410///////////////////////////////////////////////////////////////////////////
7b825f44 411TObjArray* AliDevice::SortHits(TString name,Int_t mode,TObjArray* hits)
7a086578 412{
413// Order the references to an array of hits by looping over the input array "hits"
414// and checking the signal value. The ordered array is returned as a TObjArray.
415// In case hits=0 (default), the registered hits of the current device are used.
416// Note that the input array in not modified.
417// A "hit" represents an abstract object which is derived from AliSignal.
418// The user can specify the name of the signal slot to perform the sorting on.
419// In case no matching slotname is found, the signal will be skipped.
420// Via the "mode" argument the user can specify ordering in decreasing
421// order (mode=-1) or ordering in increasing order (mode=1).
422// The default is mode=-1.
423// Signals which were declared as "Dead" will be rejected.
424// The gain etc... corrected signals will be used in the ordering process.
425
7b825f44 426 if (fOrdered)
427 {
428 delete fOrdered;
429 fOrdered=0;
430 }
7a086578 431
432 if (!hits) hits=fHits;
433
7b825f44 434 if (abs(mode)!=1 || !hits) return fOrdered;
7a086578 435
436 Int_t nhits=hits->GetEntries();
437 if (!nhits)
438 {
7b825f44 439 return fOrdered;
7a086578 440 }
441 else
442 {
7b825f44 443 fOrdered=new TObjArray(nhits);
7a086578 444 }
445
446 Int_t idx=0; // The signal slotindex to perform the sorting on
447
448 Int_t nord=0;
449 for (Int_t i=0; i<nhits; i++) // loop over all hits of the array
450 {
451 AliSignal* s=(AliSignal*)hits->At(i);
452
453 if (!s) continue;
454
455 // Obtain the slotindex corresponding to the user selection
456 idx=s->GetSlotIndex(name);
457 if (!idx) continue;
458
459 if (s->GetDeadValue(idx)) continue; // only take alive signals
460
461 if (nord == 0) // store the first hit with a signal at the first ordered position
462 {
463 nord++;
7b825f44 464 fOrdered->AddAt(s,nord-1);
7a086578 465 continue;
466 }
467
468 for (Int_t j=0; j<=nord; j++) // put hit in the right ordered position
469 {
470 if (j == nord) // module has smallest (mode=-1) or largest (mode=1) signal seen so far
471 {
472 nord++;
7b825f44 473 fOrdered->AddAt(s,j); // add hit at the end
7a086578 474 break; // go for next hit
475 }
476
7b825f44 477 if (mode==-1 && s->GetSignal(idx,1) < ((AliSignal*)fOrdered->At(j))->GetSignal(idx,1)) continue;
478 if (mode==1 && s->GetSignal(idx,1) > ((AliSignal*)fOrdered->At(j))->GetSignal(idx,1)) continue;
7a086578 479
480 nord++;
481 for (Int_t k=nord-1; k>j; k--) // create empty position
482 {
7b825f44 483 fOrdered->AddAt(fOrdered->At(k-1),k);
7a086578 484 }
7b825f44 485 fOrdered->AddAt(s,j); // put hit at empty position
7a086578 486 break; // go for next matrix module
487 }
488 }
7b825f44 489 return fOrdered;
7a086578 490}
491///////////////////////////////////////////////////////////////////////////
492TObject* AliDevice::Clone(const char* name) const
493{
494// Make a deep copy of the current object and provide the pointer to the copy.
495// This memberfunction enables automatic creation of new objects of the
496// correct type depending on the object type, a feature which may be very useful
497// for containers like AliEvent when adding objects in case the
498// container owns the objects. This feature allows e.g. AliEvent
499// to store either AliDevice objects or objects derived from AliDevice
500// via tha AddDevice memberfunction, provided these derived classes also have
501// a proper Clone memberfunction.
502
503 AliDevice* dev=new AliDevice(*this);
504 if (name)
505 {
506 if (strlen(name)) dev->SetName(name);
507 }
508 return dev;
509}
510///////////////////////////////////////////////////////////////////////////