]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RALICE/AliSignal.cxx
16-feb-2005 NvE Support for user selectable split level and buffer size of the output...
[u/mrichter/AliRoot.git] / RALICE / AliSignal.cxx
CommitLineData
4c039060 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
f531a546 16// $Id$
4c039060 17
959fbac5 18///////////////////////////////////////////////////////////////////////////
19// Class AliSignal
dafe31a2 20// Generic handling of (extrapolated) detector signals.
959fbac5 21//
22// Note :
23// ------
24// Signal positions (r) and reference frames (f) are specified via
25// SetPosition(r,f) under the following conventions :
26//
27// f="car" ==> r is Cartesian (x,y,z)
28// f="sph" ==> r is Spherical (r,theta,phi)
29// f="cyl" ==> r is Cylindrical (rho,phi,z)
30//
31// The same holds for SetPositionErrors().
32//
33// All angles are in radians.
34//
35// Example :
36// ---------
37//
38// AliSignal s;
7a5c405b 39// s.SetName("Start counter");
959fbac5 40// Float_t pos[3]={-1,25,7};
41// Float_t err[3]={0.03,0.7,0.18};
42// Float_t signal=120.8;
43// Float_t error=1.73;
1fbffa23 44// Float_t offset=-12.78;
45// Float_t gain=250;
959fbac5 46// s.SetPosition(pos,"car");
47// s.SetPositionErrors(err,"car");
48// s.SetSignal(signal);
49// s.SetSignalError(error);
1fbffa23 50// s.SetOffset(offset);
51// s.SetGain(gain);
959fbac5 52// Float_t loc[3],dr[3],sigma;
53// s.GetPosition(loc,"sph");
54// s.GetPositionErrors(dr,"sph");
55// Float_t adc=s.GetSignal();
56// Float_t sigma=s.GetSignalError();
57//
c72198f1 58// AliSignal q; // In the example below a signal contains the
959fbac5 59// // following data : timing, ADC and dE/dx
965bd237 60// q.SetNameTitle("Hybrid","Test for multiple signal data");
959fbac5 61// q.SetPosition(pos,"car");
62// q.SetPositionErrors(err,"car");
7a5c405b 63// signal=82.5; // e.g. signal time in ns
959fbac5 64// error=2.01;
1fbffa23 65// offset=0.003;
965bd237 66// q.SetSlotName("TOF");
959fbac5 67// q.SetSignal(signal,1);
68// q.SetSignalError(error,1);
1fbffa23 69// q.SetOffset(offset,1);
959fbac5 70// signal=268.1; // e.g. ADC value of signal
71// error=3.75;
1fbffa23 72// gain=120.78;
965bd237 73// // Addressing via name specification instead of index
74// q.SetSlotName("ADC");
75// q.SetSignal(signal,"ADC");
76// q.SetSignalError(error,"ADC");
77// q.SetGain(gain,"ADC");
959fbac5 78// signal=23.7; // e.g. corresponding dE/dx value
79// error=0.48;
1fbffa23 80// offset=0.2;
81// gain=150;
965bd237 82// q.SetSlotName("dE/dx");
959fbac5 83// q.SetSignal(signal,3);
84// q.SetSignalError(error,3);
1fbffa23 85// q.SetOffset(offset,3);
86// q.SetGain(gain,3);
959fbac5 87//
965bd237 88// Float_t dedx=q.GetSignal("dE/dx");
89//
959fbac5 90//--- Author: Nick van Eijndhoven 23-jan-1999 UU-SAP Utrecht
f531a546 91//- Modified: NvE $Date$ UU-SAP Utrecht
959fbac5 92///////////////////////////////////////////////////////////////////////////
93
d88f97cc 94#include "AliSignal.h"
5f25234b 95#include "AliTrack.h"
c72198f1 96#include "Riostream.h"
d88f97cc 97
98ClassImp(AliSignal) // Class implementation to enable ROOT I/O
99
1c01b4f8 100AliSignal::AliSignal() : TNamed(),AliPosition(),AliAttrib()
d88f97cc 101{
959fbac5 102// Creation of an AliSignal object and initialisation of parameters.
1fbffa23 103// Several signal values (with errors) can be stored in different slots.
fdadc78a 104// If needed, the storage for values (and errors) will be expanded automatically
105// when entering values and/or errors.
1fbffa23 106 fSignals=0;
107 fDsignals=0;
108 fWaveforms=0;
5f25234b 109 fLinks=0;
965bd237 110 fDevice=0;
d88f97cc 111}
112///////////////////////////////////////////////////////////////////////////
113AliSignal::~AliSignal()
114{
115// Destructor to delete dynamically allocated memory
1fbffa23 116 if (fSignals)
959fbac5 117 {
1fbffa23 118 delete fSignals;
119 fSignals=0;
959fbac5 120 }
1fbffa23 121 if (fDsignals)
959fbac5 122 {
1fbffa23 123 delete fDsignals;
124 fDsignals=0;
959fbac5 125 }
1fbffa23 126 if (fWaveforms)
c72198f1 127 {
1fbffa23 128 delete fWaveforms;
129 fWaveforms=0;
c72198f1 130 }
5f25234b 131 if (fLinks)
132 {
133 delete fLinks;
134 fLinks=0;
135 }
d88f97cc 136}
137///////////////////////////////////////////////////////////////////////////
261c0caf 138AliSignal::AliSignal(const AliSignal& s) : TNamed(s),AliPosition(s),AliAttrib(s)
8e8e6c7f 139{
140// Copy constructor
1fbffa23 141 fSignals=0;
142 fDsignals=0;
1fbffa23 143 fWaveforms=0;
5f25234b 144 fLinks=0;
8e8e6c7f 145
965bd237 146 // Don't copy the owning device pointer for the copy
147 fDevice=0;
148
1fbffa23 149 Int_t n=s.GetNvalues();
150 Double_t val;
151 for (Int_t i=1; i<=n; i++)
8e8e6c7f 152 {
1fbffa23 153 val=s.GetSignal(i);
154 SetSignal(val,i);
fdadc78a 155 }
156
1fbffa23 157 n=s.GetNerrors();
158 for (Int_t j=1; j<=n; j++)
fdadc78a 159 {
1fbffa23 160 val=s.GetSignalError(j);
161 SetSignalError(val,j);
c72198f1 162 }
163
1fbffa23 164 n=s.GetNwaveforms();
165 for (Int_t k=1; k<=n; k++)
166 {
167 TH1F* hist=s.GetWaveform(k);
168 if (hist) SetWaveform(hist,k);
169 }
5f25234b 170
d0a8ef71 171 TArrayI slotarr;
172 TArrayI posarr;
173 TObject* dum=0;
174 n=s.GetIndices(dum,slotarr,posarr);
175 Int_t slot,pos;
176 for (Int_t idx=0; idx<n; idx++)
5f25234b 177 {
d0a8ef71 178 slot=slotarr.At(idx);
179 pos=posarr.At(idx);
180 TObject* obj=s.GetLink(slot,pos);
181 if (obj) SetLink(obj,slot,pos);
5f25234b 182 }
8e8e6c7f 183}
184///////////////////////////////////////////////////////////////////////////
fdadc78a 185void AliSignal::Reset(Int_t mode)
d88f97cc 186{
959fbac5 187// Reset all signal and position values and errors to 0.
fdadc78a 188//
189// mode = 0 Reset position and all signal values and their errors to 0.
1fbffa23 190// The waveform histograms are reset, but the calibration
191// constants (i.e. gains and offsets) are kept.
fdadc78a 192// 1 Reset position and delete the signal and error storage arrays.
1fbffa23 193// Also the waveform histograms, gains and offset arrays are deleted.
fdadc78a 194//
195// The default when invoking Reset() corresponds to mode=0.
196//
d0a8ef71 197// Note : In all cases the storage of the various links will be reset.
4f368c8c 198// The UniqueID, name and title will NOT be reset.
199// In case the user wants to reset these attributes, this has to
200// be done explicitly via the SET facilities.
5f25234b 201//
fdadc78a 202// The usage of mode=0 allows to re-use the allocated memory for new
203// signal (and error) values. This behaviour is preferable (i.e. faster)
1fbffa23 204// in case the various signals always contain the same number of values
205// and have the same calibration constants.
fdadc78a 206// The usage of mode=1 is slower, but allows a more efficient memory
207// occupation (and smaller output file size) in case the different
208// signals have a variable number of values.
209//
1fbffa23 210// For more specific actions see ResetPosition(), ResetSignals(),
d0a8ef71 211// DeleteSignals(), ResetGain(), ResetOffset(), ResetLink(), ResetWaveform(),
212// DeleteWaveform() and DeleteCalibrations().
c72198f1 213//
959fbac5 214
fdadc78a 215 if (mode<0 || mode>1)
959fbac5 216 {
fdadc78a 217 cout << " *AliSignal::Reset* Invalid argument mode = " << mode << endl;
218 cout << " Default mode=0 will be used." << endl;
219 mode=0;
220 }
221
222 ResetPosition();
223 if (!mode)
224 {
225 ResetSignals();
226 }
227 else
228 {
229 DeleteSignals();
1fbffa23 230 DeleteCalibrations();
959fbac5 231 }
5f25234b 232
d0a8ef71 233 if (fLinks) fLinks->Reset();
965bd237 234 fDevice=0;
959fbac5 235}
236///////////////////////////////////////////////////////////////////////////
fdadc78a 237void AliSignal::ResetSignals(Int_t mode)
959fbac5 238{
fdadc78a 239// Reset various signal data according to user selection.
240//
241// mode = 0 Reset all signal values and their errors to 0.
242// 1 Reset only signal values
243// 2 Reset only signal errors
244//
245// The default when invoking ResetSignals() corresponds to mode=0.
c72198f1 246//
1fbffa23 247// Irrespective of the mode, the waveform histograms are reset.
959fbac5 248
fdadc78a 249 if (mode<0 || mode>2)
250 {
251 cout << " *AliSignal::ResetSignals* Invalid argument mode = " << mode << endl;
252 cout << " Default mode=0 will be used." << endl;
253 mode=0;
254 }
255
1fbffa23 256 if (fSignals && (mode==0 || mode==1))
959fbac5 257 {
1fbffa23 258 for (Int_t i=0; i<fSignals->GetSize(); i++)
dafe31a2 259 {
1fbffa23 260 fSignals->AddAt(0,i);
fdadc78a 261 }
262 }
263
1fbffa23 264 if (fDsignals && (mode==0 || mode==2))
fdadc78a 265 {
1fbffa23 266 for (Int_t j=0; j<fDsignals->GetSize(); j++)
fdadc78a 267 {
1fbffa23 268 fDsignals->AddAt(0,j);
dafe31a2 269 }
959fbac5 270 }
c72198f1 271
1fbffa23 272 ResetWaveform(0);
d88f97cc 273}
274///////////////////////////////////////////////////////////////////////////
fdadc78a 275void AliSignal::DeleteSignals(Int_t mode)
276{
277// Delete storage arrays of various signal data according to user selection.
278//
279// mode = 0 Delete arrays of both signal values and their errors.
280// 1 Delete only signal values array
281// 2 Delete only signal errors array
282//
283// The default when invoking DeleteSignals() corresponds to mode=0.
c72198f1 284//
1fbffa23 285// Irrespective of the mode, the waveform histograms are deleted.
fdadc78a 286
287 if (mode<0 || mode>2)
288 {
289 cout << " *AliSignal::DeleteSignals* Invalid argument mode = " << mode << endl;
290 cout << " Default mode=0 will be used." << endl;
291 mode=0;
292 }
293
1fbffa23 294 if (fSignals && (mode==0 || mode==1))
fdadc78a 295 {
1fbffa23 296 delete fSignals;
297 fSignals=0;
fdadc78a 298 }
299
1fbffa23 300 if (fDsignals && (mode==0 || mode==2))
fdadc78a 301 {
1fbffa23 302 delete fDsignals;
303 fDsignals=0;
fdadc78a 304 }
c72198f1 305
1fbffa23 306 DeleteWaveform(0);
fdadc78a 307}
308///////////////////////////////////////////////////////////////////////////
959fbac5 309void AliSignal::SetSignal(Double_t sig,Int_t j)
d88f97cc 310{
2cb7369d 311// Store signal value for the j-th (default j=1) slot.
1fbffa23 312// Note : The first signal slot is at j=1.
dafe31a2 313// In case the value of the index j exceeds the maximum number of reserved
fdadc78a 314// slots for signal values, the number of reserved slots for the
315// signal values is increased automatically.
959fbac5 316
1fbffa23 317 if (!fSignals)
959fbac5 318 {
1fbffa23 319 fSignals=new TArrayF(j);
fdadc78a 320 ResetSignals(1);
959fbac5 321 }
dafe31a2 322
1fbffa23 323 Int_t size=fSignals->GetSize();
dafe31a2 324
325 if (j>size)
959fbac5 326 {
1fbffa23 327 fSignals->Set(j);
959fbac5 328 }
dafe31a2 329
1fbffa23 330 fSignals->AddAt(float(sig),j-1);
d88f97cc 331}
332///////////////////////////////////////////////////////////////////////////
2cb7369d 333void AliSignal::SetSignal(Double_t sig,TString name)
334{
335// Store signal value for the name-specified slot.
336//
337// This procedure involves a slot-index search based on the specified name
338// at each invokation. This may become slow in case many slots have been
339// defined and/or when this procedure is invoked many times.
340// In such cases it is preferable to use indexed addressing in the user code
341// either directly or via a few invokations of GetSlotIndex().
342
343 Int_t j=GetSlotIndex(name);
344 if (j>0) SetSignal(sig,j);
345}
346///////////////////////////////////////////////////////////////////////////
959fbac5 347void AliSignal::AddSignal(Double_t sig,Int_t j)
348{
2cb7369d 349// Add value to the signal of the j-th (default j=1) slot.
1fbffa23 350// Note : The first signal slot is at j=1.
dafe31a2 351// In case the value of the index j exceeds the maximum number of reserved
fdadc78a 352// slots for signal values, the number of reserved slots for the
353// signal values is increased automatically.
959fbac5 354
1fbffa23 355 if (!fSignals)
959fbac5 356 {
1fbffa23 357 fSignals=new TArrayF(j);
fdadc78a 358 ResetSignals(1);
959fbac5 359 }
dafe31a2 360
1fbffa23 361 Int_t size=fSignals->GetSize();
dafe31a2 362
363 if (j>size)
959fbac5 364 {
1fbffa23 365 fSignals->Set(j);
959fbac5 366 }
dafe31a2 367
1fbffa23 368 Float_t sum=(fSignals->At(j-1))+sig;
369 fSignals->AddAt(sum,j-1);
959fbac5 370}
371///////////////////////////////////////////////////////////////////////////
2cb7369d 372void AliSignal::AddSignal(Double_t sig,TString name)
373{
374// Add value to the signal of the name-specified slot.
375//
376// This procedure involves a slot-index search based on the specified name
377// at each invokation. This may become slow in case many slots have been
378// defined and/or when this procedure is invoked many times.
379// In such cases it is preferable to use indexed addressing in the user code
380// either directly or via a few invokations of GetSlotIndex().
381
382 Int_t j=GetSlotIndex(name);
383 if (j>0) AddSignal(sig,j);
384}
385///////////////////////////////////////////////////////////////////////////
261c0caf 386Float_t AliSignal::GetSignal(Int_t j,Int_t mode) const
959fbac5 387{
2cb7369d 388// Provide signal value of the j-th (default j=1) slot.
1fbffa23 389// Note : The first signal slot is at j=1.
fdadc78a 390// In case no signal is present or the argument j is invalid, 0 is returned.
1fbffa23 391// The parameter "mode" allows for automatic gain etc... correction of the signal.
392//
393// mode = 0 : Just the j-th signal is returned.
394// 1 : The j-th signal is corrected for the gain, offset, dead flag etc...
395// In case the gain value was not set, gain=1 will be assumed.
396// In case the gain value was 0, a signal value of 0 is returned.
397// In case the offset value was not set, offset=0 will be assumed.
398// In case the j-th slot was marked dead, 0 is returned.
399//
400// The corrected signal (sigc) is determined as follows :
401//
402// sigc=(signal/gain)-offset
403//
404// The default is mode=0.
405
fdadc78a 406 Float_t sig=0;
1fbffa23 407 Float_t gain=1;
408 Float_t offset=0;
409 if (fSignals)
959fbac5 410 {
1fbffa23 411 if (j>0 && j<=(fSignals->GetSize()))
fdadc78a 412 {
1fbffa23 413 sig=fSignals->At(j-1);
414
415 if (mode==0) return sig;
416
417 // Correct the signal for the gain, offset, dead flag etc...
418 if (GetDeadValue(j)) return 0;
419
420 if (GetGainFlag(j)) gain=GetGain(j);
421 if (GetOffsetFlag(j)) offset=GetOffset(j);
422
423 if (fabs(gain)>0.)
424 {
425 sig=(sig/gain)-offset;
426 }
427 else
428 {
429 sig=0;
430 }
fdadc78a 431 }
432 else
433 {
434 cout << " *AliSignal::GetSignal* Index j = " << j << " invalid." << endl;
435 }
959fbac5 436 }
fdadc78a 437 return sig;
959fbac5 438}
439///////////////////////////////////////////////////////////////////////////
2cb7369d 440Float_t AliSignal::GetSignal(TString name,Int_t mode) const
441{
442// Provide signal value of the name-specified slot.
443// In case no signal is present, 0 is returned.
444// The parameter "mode" allows for automatic gain etc... correction of the signal.
445//
446// mode = 0 : Just the j-th signal is returned.
447// 1 : The j-th signal is corrected for the gain, offset, dead flag etc...
448// In case the gain value was not set, gain=1 will be assumed.
449// In case the gain value was 0, a signal value of 0 is returned.
450// In case the offset value was not set, offset=0 will be assumed.
451// In case the j-th slot was marked dead, 0 is returned.
452//
453// The corrected signal (sigc) is determined as follows :
454//
455// sigc=(signal/gain)-offset
456//
457// The default is mode=0.
458//
459// This procedure involves a slot-index search based on the specified name
460// at each invokation. This may become slow in case many slots have been
461// defined and/or when this procedure is invoked many times.
462// In such cases it is preferable to use indexed addressing in the user code
463// either directly or via a few invokations of GetSlotIndex().
464
465 Int_t j=GetSlotIndex(name);
466 Float_t val=0;
467 if (j>0) val=GetSignal(j,mode);
468 return val;
469}
470///////////////////////////////////////////////////////////////////////////
959fbac5 471void AliSignal::SetSignalError(Double_t dsig,Int_t j)
472{
2cb7369d 473// Store error on the signal for the j-th (default j=1) slot.
1fbffa23 474// Note : The first signal slot is at j=1.
dafe31a2 475// In case the value of the index j exceeds the maximum number of reserved
fdadc78a 476// slots for signal error values, the number of reserved slots for the
477// signal errors is increased automatically.
959fbac5 478
1fbffa23 479 if (!fDsignals)
959fbac5 480 {
1fbffa23 481 fDsignals=new TArrayF(j);
fdadc78a 482 ResetSignals(2);
959fbac5 483 }
dafe31a2 484
1fbffa23 485 Int_t size=fDsignals->GetSize();
dafe31a2 486
487 if (j>size)
959fbac5 488 {
1fbffa23 489 fDsignals->Set(j);
959fbac5 490 }
dafe31a2 491
1fbffa23 492 fDsignals->AddAt(float(dsig),j-1);
959fbac5 493}
494///////////////////////////////////////////////////////////////////////////
2cb7369d 495void AliSignal::SetSignalError(Double_t dsig,TString name)
496{
497// Store error on the signal for the name-specified slot.
498//
499// This procedure involves a slot-index search based on the specified name
500// at each invokation. This may become slow in case many slots have been
501// defined and/or when this procedure is invoked many times.
502// In such cases it is preferable to use indexed addressing in the user code
503// either directly or via a few invokations of GetSlotIndex().
504
505 Int_t j=GetSlotIndex(name);
506 if (j>0) SetSignalError(dsig,j);
507}
508///////////////////////////////////////////////////////////////////////////
261c0caf 509Float_t AliSignal::GetSignalError(Int_t j) const
959fbac5 510{
2cb7369d 511// Provide error on the signal of the j-th (default j=1) slot.
1fbffa23 512// Note : The first signal slot is at j=1.
fdadc78a 513// In case no signal is present or the argument j is invalid, 0 is returned.
514 Float_t err=0;
1fbffa23 515 if (fDsignals)
959fbac5 516 {
1fbffa23 517 if (j>0 && j<=(fDsignals->GetSize()))
fdadc78a 518 {
1fbffa23 519 err=fDsignals->At(j-1);
fdadc78a 520 }
521 else
522 {
523 cout << " *AliSignal::GetSignalError* Index j = " << j << " invalid." << endl;
524 }
959fbac5 525 }
fdadc78a 526 return err;
959fbac5 527}
528///////////////////////////////////////////////////////////////////////////
2cb7369d 529Float_t AliSignal::GetSignalError(TString name) const
530{
531// Provide error on the signal of the name-specified slot.
532//
533// This procedure involves a slot-index search based on the specified name
534// at each invokation. This may become slow in case many slots have been
535// defined and/or when this procedure is invoked many times.
536// In such cases it is preferable to use indexed addressing in the user code
537// either directly or via a few invokations of GetSlotIndex().
538
539 Int_t j=GetSlotIndex(name);
540 Float_t val=0;
541 if (j>0) val=GetSignalError(j);
542 return val;
543}
544///////////////////////////////////////////////////////////////////////////
261c0caf 545void AliSignal::Data(TString f) const
1c01b4f8 546{
547// Provide all signal information within the coordinate frame f.
548
5f25234b 549 const char* name=GetName();
550 const char* title=GetTitle();
551
4f368c8c 552 cout << " *" << ClassName() << "::Data* Id :" << GetUniqueID();
5f25234b 553 if (strlen(name)) cout << " Name : " << name;
554 if (strlen(title)) cout << " Title : " << title;
555 cout << endl;
d0a8ef71 556 cout << " Position";
1c01b4f8 557 Ali3Vector::Data(f);
965bd237 558 if (fDevice)
559 {
560 const char* devname=fDevice->GetName();
561 const char* devtitle=fDevice->GetTitle();
562 cout << " Owned by device : " << fDevice->ClassName();
563 if (strlen(devname)) cout << " Name : " << devname;
564 if (strlen(devtitle)) cout << " Title : " << devtitle;
565 cout << endl;
566 }
1c01b4f8 567
6a8254a0 568 // Provide an overview of the stored waveforms
569 ListWaveform(-1);
570
571 // Provide an overview of all the data and attribute slots
1c01b4f8 572 List(-1);
573}
574///////////////////////////////////////////////////////////////////////////
261c0caf 575void AliSignal::List(Int_t j) const
959fbac5 576{
1c01b4f8 577// Provide signal information for the j-th slot.
1fbffa23 578// The first slot is at j=1.
579// In case j=0 (default) the data of all slots will be listed.
1c01b4f8 580// In case j=-1 the data of all slots will be listed, but the header
581// information will be suppressed.
1fbffa23 582
1c01b4f8 583 if (j<-1)
1fbffa23 584 {
1c01b4f8 585 cout << " *AliSignal::List* Invalid argument j = " << j << endl;
1fbffa23 586 return;
587 }
588
5f25234b 589 if (j != -1)
590 {
591 const char* name=GetName();
592 const char* title=GetTitle();
593
6a8254a0 594 cout << " *" << ClassName() << "::Data* Id :" << GetUniqueID();
5f25234b 595 if (strlen(name)) cout << " Name : " << name;
596 if (strlen(title)) cout << " Title : " << title;
597 cout << endl;
6a8254a0 598 if (fDevice)
599 {
600 const char* devname=fDevice->GetName();
601 const char* devtitle=fDevice->GetTitle();
602 cout << " Owned by device : " << fDevice->ClassName();
603 if (strlen(devname)) cout << " Name : " << devname;
604 if (strlen(devtitle)) cout << " Title : " << devtitle;
605 cout << endl;
606 }
5f25234b 607 }
fdadc78a 608
609 Int_t nvalues=GetNvalues();
610 Int_t nerrors=GetNerrors();
d0a8ef71 611 Int_t nlinkslots=0;
612 if (fLinks) nlinkslots=fLinks->GetMaxColumn();
1fbffa23 613 Int_t n=nvalues;
614 if (nerrors>n) n=nerrors;
d0a8ef71 615 if (nlinkslots>n) n=nlinkslots;
5f25234b 616
617 TObject* obj=0;
d0a8ef71 618 Int_t nrefs=0;
619 TArrayI posarr;
620 Int_t pos;
fdadc78a 621
1c01b4f8 622 if (j<=0)
959fbac5 623 {
1fbffa23 624 for (Int_t i=1; i<=n; i++)
959fbac5 625 {
d0a8ef71 626 cout << " Slot : " << i;
627 if (i<=nvalues) cout << " Signal value : " << GetSignal(i);
1fbffa23 628 if (i<=nerrors) cout << " error : " << GetSignalError(i);
1c01b4f8 629 AliAttrib::List(i);
1fbffa23 630 cout << endl;
d0a8ef71 631 obj=0;
632 nrefs=GetIndices(obj,i,posarr);
633 for (Int_t k=0; k<nrefs; k++)
5f25234b 634 {
d0a8ef71 635 pos=posarr.At(k);
636 obj=GetLink(i,pos);
637 if (obj)
03b59bc9 638 {
d0a8ef71 639 cout << " Link at position " << pos << " to : " << obj->ClassName();
640 if (obj->InheritsFrom("TNamed"))
641 {
642 const char* lname=obj->GetName();
643 const char* ltitle=obj->GetTitle();
644 if (strlen(lname)) cout << " Name : " << lname;
645 if (strlen(ltitle)) cout << " Title : " << ltitle;
646 }
647 cout << endl;
03b59bc9 648 }
5f25234b 649 }
1fbffa23 650 }
651 }
652 else
653 {
654 if (j<=n)
655 {
d0a8ef71 656 cout << " Slot : " << j;
657 if (j<=nvalues) cout << " Signal value : " << GetSignal(j);
1fbffa23 658 if (j<=nerrors) cout << " error : " << GetSignalError(j);
1c01b4f8 659 AliAttrib::List(j);
fdadc78a 660 cout << endl;
d0a8ef71 661 obj=0;
662 nrefs=GetIndices(obj,j,posarr);
663 for (Int_t kj=0; kj<nrefs; kj++)
5f25234b 664 {
d0a8ef71 665 pos=posarr.At(kj);
666 obj=GetLink(j,pos);
667 if (obj)
03b59bc9 668 {
d0a8ef71 669 cout << " Link at position " << pos << " to : " << obj->ClassName();
670 if (obj->InheritsFrom("TNamed"))
671 {
672 const char* lnamej=obj->GetName();
673 const char* ltitlej=obj->GetTitle();
674 if (strlen(lnamej)) cout << " Name : " << lnamej;
675 if (strlen(ltitlej)) cout << " Title : " << ltitlej;
676 }
677 cout << endl;
03b59bc9 678 }
5f25234b 679 }
959fbac5 680 }
681 }
682}
683///////////////////////////////////////////////////////////////////////////
2cb7369d 684void AliSignal::List(TString name) const
685{
686// Provide signal information for the name-specified slot.
687//
688// This procedure involves a slot-index search based on the specified name
689// at each invokation. This may become slow in case many slots have been
690// defined and/or when this procedure is invoked many times.
691// In such cases it is preferable to use indexed addressing in the user code
692// either directly or via a few invokations of GetSlotIndex().
693
694 Int_t j=GetSlotIndex(name);
695 if (j>0) List(j);
696}
697///////////////////////////////////////////////////////////////////////////
6a8254a0 698void AliSignal::ListWaveform(Int_t j) const
699{
700// Provide information for the j-th waveform.
701// The first waveform is at j=1.
702// In case j=0 (default) the info of all waveforms will be listed.
703// In case j=-1 the info of all waveforms will be listed, but the header
704// information will be suppressed.
705
706 if (j<-1)
707 {
708 cout << " *AliSignal::ListWaveform* Invalid argument j = " << j << endl;
709 return;
710 }
711
712 if (j != -1)
713 {
714 const char* name=GetName();
715 const char* title=GetTitle();
716
717 cout << " *" << ClassName() << "::Data* Id :" << GetUniqueID();
718 if (strlen(name)) cout << " Name : " << name;
719 if (strlen(title)) cout << " Title : " << title;
720 cout << endl;
721 if (fDevice)
722 {
723 const char* devname=fDevice->GetName();
724 const char* devtitle=fDevice->GetTitle();
725 cout << " Owned by device : " << fDevice->ClassName();
726 if (strlen(devname)) cout << " Name : " << devname;
727 if (strlen(devtitle)) cout << " Title : " << devtitle;
728 cout << endl;
729 }
730 }
731
732 Int_t n=GetNwaveforms();
733 TObject* obj=0;
734
735 if (j<=0)
736 {
737 for (Int_t i=1; i<=n; i++)
738 {
739 obj=GetWaveform(i);
740 if (obj)
741 {
742 const char* wfname=obj->GetName();
743 const char* wftitle=obj->GetTitle();
744 cout << " Waveform " << i << " : " << obj->ClassName();
745 if (strlen(wfname)) cout << " Name : " << wfname;
746 if (strlen(wftitle)) cout << " Title : " << wftitle;
747 cout << endl;
748 }
749 }
750 }
751 else
752 {
753 if (j<=n)
754 {
755 obj=GetWaveform(j);
756 if (obj)
757 {
758 const char* wfnamej=obj->GetName();
759 const char* wftitlej=obj->GetTitle();
760 cout << " Waveform " << j << " : " << obj->ClassName();
761 if (strlen(wfnamej)) cout << " Name : " << wfnamej;
762 if (strlen(wftitlej)) cout << " Title : " << wftitlej;
763 cout << endl;
764 }
765 }
766 }
767}
768///////////////////////////////////////////////////////////////////////////
261c0caf 769Int_t AliSignal::GetNvalues() const
8e8e6c7f 770{
771// Provide the number of values for this signal.
dafe31a2 772 Int_t n=0;
1fbffa23 773 if (fSignals) n=fSignals->GetSize();
fdadc78a 774 return n;
775}
776///////////////////////////////////////////////////////////////////////////
261c0caf 777Int_t AliSignal::GetNerrors() const
fdadc78a 778{
779// Provide the number specified errors on the values for this signal.
780 Int_t n=0;
1fbffa23 781 if (fDsignals) n=fDsignals->GetSize();
dafe31a2 782 return n;
8e8e6c7f 783}
784///////////////////////////////////////////////////////////////////////////
261c0caf 785Int_t AliSignal::GetNwaveforms() const
c72198f1 786{
a80c27d9 787// Provide the number of specified waveforms for this signal.
788// Actually the return value is the highest index of the stored waveforms.
789// This allows an index dependent meaning of waveform info (e.g. waveforms
790// with various gain values).
791// So, when all waveforms are stored in consequetive positions (e.g. 1,2,3),
792// this memberfunction returns 3, being both the highest filled position
793// and the actual number of waveforms.
794// In case only waveforms are stored at positions 1,2,5,7 this memberfunction
795// returns a value 7 whereas only 4 actual waveforms are present.
796// This implies that when looping over the various waveform slots, one
797// always has to check whether the returned pointer value is non-zero
798// (which is a good practice anyhow).
799 Int_t n=-1;
800 if (fWaveforms) n=fWaveforms->GetLast();
801 return (n+1);
c72198f1 802}
803///////////////////////////////////////////////////////////////////////////
261c0caf 804TH1F* AliSignal::GetWaveform(Int_t j) const
c72198f1 805{
6a8254a0 806// Provide pointer to the j-th waveform histogram.
1fbffa23 807 TH1F* waveform=0;
808 if (j <= GetNwaveforms()) waveform=(TH1F*)fWaveforms->At(j-1);
809 return waveform;
810}
811///////////////////////////////////////////////////////////////////////////
2cb7369d 812TH1F* AliSignal::GetWaveform(TString name) const
813{
6a8254a0 814// Provide pointer to the waveform histogram with the specified name.
815// In case no match is found, zero is returned.
816 Int_t n=GetNwaveforms();
817 TString str;
818 for (Int_t i=1; i<=n; i++)
819 {
820 TH1F* waveform=GetWaveform(i);
821 if (waveform)
822 {
823 str=waveform->GetName();
824 if (str == name) return waveform;
825 }
826 }
827 return 0; // No match found
828}
829///////////////////////////////////////////////////////////////////////////
830Int_t AliSignal::GetWaveformIndex(TString name) const
831{
832// Provide index to the waveform histogram with the specified name.
833// In case no match is found, zero is returned.
834 Int_t n=GetNwaveforms();
835 TString str;
836 for (Int_t i=1; i<=n; i++)
837 {
838 TH1F* waveform=GetWaveform(i);
839 if (waveform)
840 {
841 str=waveform->GetName();
842 if (str == name) return i;
843 }
844 }
845 return 0; // No match found
2cb7369d 846}
847///////////////////////////////////////////////////////////////////////////
1fbffa23 848void AliSignal::SetWaveform(TH1F* waveform,Int_t j)
849{
6a8254a0 850// Set the 1D waveform histogram for the j-th waveform.
1fbffa23 851//
852// Notes :
6a8254a0 853// The first waveform position at j=1.
1fbffa23 854// j=1 is the default value.
855//
856// In case the value of the index j exceeds the maximum number of reserved
6a8254a0 857// positions for the waveforms, the number of reserved positions for the waveforms
1fbffa23 858// is increased automatically.
c72198f1 859//
1fbffa23 860// In case the histo pointer argument has the same value as the current waveform
c72198f1 861// histogram pointer value, no action is taken since the user has already
862// modified the actual histogram.
863//
1fbffa23 864// In case the histo pointer argument is zero, the current waveform histogram
c72198f1 865// is deleted and the pointer set to zero.
866//
867// In all other cases the current waveform histogram is deleted and a new
868// copy of the input histogram is created which becomes the current waveform
869// histogram.
870
6a8254a0 871 if (j<1) return;
872
1fbffa23 873 if (!fWaveforms)
874 {
875 fWaveforms=new TObjArray(j);
876 fWaveforms->SetOwner();
877 }
878
879 if (j > fWaveforms->GetSize()) fWaveforms->Expand(j);
880
881 TH1F* hcur=(TH1F*)fWaveforms->At(j-1);
882 if (waveform != hcur)
c72198f1 883 {
1fbffa23 884 if (hcur)
c72198f1 885 {
1fbffa23 886 fWaveforms->Remove(hcur);
887 delete hcur;
888 hcur=0;
889 }
890 if (waveform)
891 {
892 hcur=new TH1F(*waveform);
893 fWaveforms->AddAt(hcur,j-1);
c72198f1 894 }
c72198f1 895 }
896}
897///////////////////////////////////////////////////////////////////////////
1fbffa23 898void AliSignal::ResetWaveform(Int_t j)
899{
6a8254a0 900// Reset the histogram of the j-th (default j=1) waveform.
1fbffa23 901// This memberfunction invokes TH1F::Reset() for the corresponding waveform(s).
902// To actually delete the histograms from memory, use DeleteWaveform().
6a8254a0 903// Notes : The first position is at j=1.
1fbffa23 904// j=0 ==> All waveforms will be reset.
905
906 if (!fWaveforms) return;
907
908 Int_t size=fWaveforms->GetSize();
909
910 if ((j>=0) && (j<=size))
911 {
912 if (j)
913 {
914 TH1F* hwave=(TH1F*)fWaveforms->At(j-1);
915 if (hwave) hwave->Reset();
916 }
917 else
918 {
919 for (Int_t i=0; i<size; i++)
920 {
921 TH1F* hwave=(TH1F*)fWaveforms->At(i);
922 if (hwave) hwave->Reset();
923 }
924 }
925 }
926 else
927 {
928 cout << " *AliSignal::ResetWaveform* Index j = " << j << " invalid." << endl;
929 return;
930 }
931}
932///////////////////////////////////////////////////////////////////////////
2cb7369d 933void AliSignal::ResetWaveform(TString name)
934{
6a8254a0 935// Reset the waveform with the specified name.
936 Int_t j=GetWaveformIndex(name);
2cb7369d 937 if (j>0) ResetWaveform(j);
938}
939///////////////////////////////////////////////////////////////////////////
1fbffa23 940void AliSignal::DeleteWaveform(Int_t j)
941{
6a8254a0 942// Delete the histogram of the j-th (default j=1) waveform.
943// Notes : The first position is at j=1.
1fbffa23 944// j=0 ==> All waveforms will be deleted.
945
946 if (!fWaveforms) return;
947
948 Int_t size=fWaveforms->GetSize();
949
950 if ((j>=0) && (j<=size))
951 {
952 if (j)
953 {
954 TH1F* hwave=(TH1F*)fWaveforms->At(j-1);
955 if (hwave)
956 {
957 fWaveforms->Remove(hwave);
958 delete hwave;
959 }
960 }
961 else
962 {
963 delete fWaveforms;
964 fWaveforms=0;
965 }
966 }
967 else
968 {
969 cout << " *AliSignal::DeleteWaveform* Index j = " << j << " invalid." << endl;
970 return;
971 }
972}
973///////////////////////////////////////////////////////////////////////////
2cb7369d 974void AliSignal::DeleteWaveform(TString name)
975{
6a8254a0 976// Delete the waveform with the specified name.
977 Int_t j=GetWaveformIndex(name);
2cb7369d 978 if (j>0) DeleteWaveform(j);
979}
980///////////////////////////////////////////////////////////////////////////
261c0caf 981Int_t AliSignal::GetNlinks(TObject* obj,Int_t j) const
5f25234b 982{
d0a8ef71 983// Provide the number of links to the specified object for the j-th slot.
984// If j=0 (default) all slots will be scanned for the specified object.
985// If obj=0 (default) all encountered objects for the specified slot will be counted.
986// So, invokation of the default GetNlinks() will return the total number of
987// all references to all sorts of stored objects.
988 if (j<0)
989 {
990 cout << " *AliSignal::GetNlinks* Index j = " << j << " invalid." << endl;
991 return 0;
992 }
993
5f25234b 994 Int_t n=0;
d0a8ef71 995 if (!j)
996 {
7a086578 997 if (fLinks) n=fLinks->GetNrefs(obj);
d0a8ef71 998 }
999 else
1000 {
1001 TArrayI posarr;
1002 n=GetIndices(obj,j,posarr);
1003 }
5f25234b 1004 return n;
1005}
1006///////////////////////////////////////////////////////////////////////////
2cb7369d 1007Int_t AliSignal::GetNlinks(TObject* obj,TString name) const
1008{
1009// Provide the number of links to the specified object for the name-spec. slot.
1010// If obj=0 all encountered objects for the specified slot will be counted.
1011//
1012// This procedure involves a slot-index search based on the specified name
1013// at each invokation. This may become slow in case many slots have been
1014// defined and/or when this procedure is invoked many times.
1015// In such cases it is preferable to use indexed addressing in the user code
1016// either directly or via a few invokations of GetSlotIndex().
1017
1018 Int_t j=GetSlotIndex(name);
1019 Int_t n=0;
1020 if (j>0) n=GetNlinks(obj,j);
1021 return n;
1022}
1023///////////////////////////////////////////////////////////////////////////
261c0caf 1024TObject* AliSignal::GetLink(Int_t j,Int_t k) const
5f25234b 1025{
d0a8ef71 1026// Provide pointer of the object linked to the j-th slot at position k.
1027
5f25234b 1028 TObject* obj=0;
d0a8ef71 1029 // Note : In the internal storage matrix slots=columns positions=rows
1030 if (fLinks) obj=fLinks->GetObject(k,j);
5f25234b 1031 return obj;
1032}
1033///////////////////////////////////////////////////////////////////////////
2cb7369d 1034TObject* AliSignal::GetLink(TString name,Int_t k) const
1035{
1036// Provide pointer of the object linked to the name-spec. slot at position k.
1037//
1038// This procedure involves a slot-index search based on the specified name
1039// at each invokation. This may become slow in case many slots have been
1040// defined and/or when this procedure is invoked many times.
1041// In such cases it is preferable to use indexed addressing in the user code
1042// either directly or via a few invokations of GetSlotIndex().
1043
1044 Int_t j=GetSlotIndex(name);
1045 TObject* obj=0;
1046 if (j>0) obj=GetLink(j,k);
1047 return obj;
1048}
1049///////////////////////////////////////////////////////////////////////////
d0a8ef71 1050void AliSignal::SetLink(TObject* obj,Int_t j,Int_t k)
5f25234b 1051{
d0a8ef71 1052// Introduce a link (=pointer) to an object for the j-th slot at position k.
5f25234b 1053// Only the pointer values are stored for (backward) reference, meaning
1054// that the objects of which the pointers are stored are NOT owned
1055// by the AliSignal object.
1056//
1057// Notes :
d0a8ef71 1058// The first slot is at j=1 and the first position is at k=1.
1059// j=1 and k=1 are the default values.
5f25234b 1060//
d0a8ef71 1061// If needed, the storage area for the links is increased automatically.
5f25234b 1062//
1063// In case the pointer argument is zero, indeed a value of zero will be
d0a8ef71 1064// stored at the specified position (k) for the specified slot (j).
5f25234b 1065//
1066// In principle any object derived from TObject can be referred to by this
1067// mechanism.
1068// However, this "linking back" facility was introduced to enable AliSignal slots
1069// to refer directly to the various AliTracks to which the AliSignal object itself
1070// is related (see AliTrack::AddSignal).
1071// Therefore, in case the input argument "obj" points to an AliTrack (or derived)
1072// object, the current signal is automatically related to this AliTrack
1073// (or derived) object.
1074//
1075// Please also have a look at the docs of the memberfunction ResetLink()
1076// to prevent the situation of stored pointers to non-existent object.
1077
d0a8ef71 1078 if (!fLinks && obj) fLinks=new AliObjMatrix();
5f25234b 1079
d0a8ef71 1080 if (!fLinks) return;
5f25234b 1081
d0a8ef71 1082 // Note : In the internal storage matrix slots=columns positions=rows
1083 fLinks->EnterObject(k,j,obj);
1084 if (obj)
5f25234b 1085 {
d0a8ef71 1086 if (obj->InheritsFrom("AliTrack"))
5f25234b 1087 {
d0a8ef71 1088 AliTrack* t=(AliTrack*)obj;
1089 t->AddSignal(*this);
5f25234b 1090 }
1091 }
1092}
1093///////////////////////////////////////////////////////////////////////////
2cb7369d 1094void AliSignal::SetLink(TObject* obj,TString name,Int_t k)
1095{
1096// Introduce a link (=pointer) to an object for the name-spec. slot at position k.
1097// Only the pointer values are stored for (backward) reference, meaning
1098// that the objects of which the pointers are stored are NOT owned
1099// by the AliSignal object.
1100//
1101// This procedure involves a slot-index search based on the specified name
1102// at each invokation. This may become slow in case many slots have been
1103// defined and/or when this procedure is invoked many times.
1104// In such cases it is preferable to use indexed addressing in the user code
1105// either directly or via a few invokations of GetSlotIndex().
1106
1107 Int_t j=GetSlotIndex(name);
1108 if (j>0) SetLink(obj,j,k);
1109}
1110///////////////////////////////////////////////////////////////////////////
d0a8ef71 1111void AliSignal::AddLink(TObject* obj,Int_t j)
1112{
1113// Introduce a link (=pointer) to an object for the j-th slot at the first
1114// free position.
1115// Only the pointer values are stored for (backward) reference, meaning
1116// that the objects of which the pointers are stored are NOT owned
1117// by the AliSignal object.
1118//
1119// Notes :
1120// The first slot is at j=1 and the first position is at k=1.
1121// j=1 is the default value.
1122//
1123// If needed, the storage area for the links is increased automatically.
1124//
1125// In case the pointer argument is zero, no link will be added.
1126//
1127// In principle any object derived from TObject can be referred to by this
1128// mechanism.
1129// However, this "linking back" facility was introduced to enable AliSignal slots
1130// to refer directly to the various AliTracks to which the AliSignal object itself
1131// is related (see AliTrack::AddSignal).
1132// Therefore, in case the input argument "obj" points to an AliTrack (or derived)
1133// object, the current signal is automatically related to this AliTrack
1134// (or derived) object.
1135//
1136// Please also have a look at the docs of the memberfunction ResetLink()
1137// to prevent the situation of stored pointers to non-existent object.
1138
1139 if (!obj || j<=0) return;
1140
1141 if (!fLinks) fLinks=new AliObjMatrix();
1142
1143 TObject* dum=0;
1144 Int_t n=GetNlinks(dum,j);
1145 Int_t pos=1;
1146 for (Int_t k=1; k<=n; k++)
1147 {
1148 dum=GetLink(j,k);
1149 if (!dum) break;
1150 pos++;
1151 }
1152
1153 SetLink(obj,j,pos);
1154}
1155///////////////////////////////////////////////////////////////////////////
2cb7369d 1156void AliSignal::AddLink(TObject* obj,TString name)
1157{
1158// Introduce a link (=pointer) to an object for the name-spec slot at the first
1159// free position.
1160// Only the pointer values are stored for (backward) reference, meaning
1161// that the objects of which the pointers are stored are NOT owned
1162// by the AliSignal object.
1163//
1164// This procedure involves a slot-index search based on the specified name
1165// at each invokation. This may become slow in case many slots have been
1166// defined and/or when this procedure is invoked many times.
1167// In such cases it is preferable to use indexed addressing in the user code
1168// either directly or via a few invokations of GetSlotIndex().
1169
1170 Int_t j=GetSlotIndex(name);
1171 if (j>0) AddLink(obj,j);
1172}
1173///////////////////////////////////////////////////////////////////////////
d0a8ef71 1174void AliSignal::ResetLink(Int_t j,Int_t k)
5f25234b 1175{
d0a8ef71 1176// Reset the link of the j-th slot at position k.
1177//
1178// Notes :
1179// The first slot is at j=1 and the first position is at k=1.
1180// j=1 and k=1 are the default values.
1181//
1182// This memberfunction is intended to reset only 1 specified link location.
1183// For extended functionality, please refer to the memberfuction ResetLinks().
5f25234b 1184//
1185// In general the user should take care of properly clearing the corresponding
1186// pointer here when the referred object is deleted.
1187// However, this "linking back" facility was introduced to enable AliSignal slots
1188// to refer directly to the various AliTracks to which the AliSignal object itself
1189// is related (see AliTrack::AddSignal).
1190// As such, the AliTrack destructor already takes care of clearing the corresponding
1191// links from the various AliSignal slots for all the AliSignal objects that were
1192// related to that AliTrack.
1193// So, in case the link introduced via SetLink() is the pointer of an AliTrack object,
1194// the user doesn't have to worry about clearing the corresponding AliTrack link from
1195// the AliSignal object when the corresponding AliTrack object is deleted.
1196
d0a8ef71 1197 // Note : In the internal storage matrix slots=columns positions=rows
1198 if (fLinks) fLinks->RemoveObject(k,j);
5f25234b 1199}
1200///////////////////////////////////////////////////////////////////////////
2cb7369d 1201void AliSignal::ResetLink(TString name,Int_t k)
1202{
1203// Reset the link of the name-specified slot at position k.
1204//
1205// This memberfunction is intended to reset only 1 specified link location.
1206// For extended functionality, please refer to the memberfuction ResetLinks().
1207//
1208// This procedure involves a slot-index search based on the specified name
1209// at each invokation. This may become slow in case many slots have been
1210// defined and/or when this procedure is invoked many times.
1211// In such cases it is preferable to use indexed addressing in the user code
1212// either directly or via a few invokations of GetSlotIndex().
1213
1214 Int_t j=GetSlotIndex(name);
1215 if (j>0) ResetLink(j,k);
1216}
1217///////////////////////////////////////////////////////////////////////////
d0a8ef71 1218void AliSignal::ResetLinks(TObject* obj,Int_t j,Int_t k)
5f25234b 1219{
d0a8ef71 1220// Reset single or multiple link(s) according to user specified selections.
1221//
1222// A link is only reset if the stored reference matches the argument "obj".
1223// In case obj=0 no check on the matching of the stored reference is performed
1224// and the stored link is always reset in accordance with the other
1225// selection criteria.
1226//
1227// In case the slot argument "j" is specified, only the links from that
1228// specified slot will be deleted.
1229// In case j=0 (default) no checking on the slot index is performed.
1230//
1231// In case the position argument "k" is specified, only the links from that
1232// specified position will be deleted.
1233// In case k=0 (default) no checking on the position index is performed.
1234//
1235// So, invokation of ResetLinks(obj) will remove all references to the
1236// object "obj" from the total AliSignal, whereas ResetLinks(obj,j)
1237// will remove all references to the object "obj" only from slot "j".
1238//
1239// Notes :
1240// -------
1241// The first slot is indicated as j=1, whereas the first position is at k=1.
1242//
1243// Invokation of ResetLinks(0,row,col) is equivalent to invoking the
1244// memberfunction ResetLink(row,col).
1245// Invoking the latter directly is slightly faster.
1246//
1247// Invokation of ResetLinks(0) will reset all stored references in this AliSignal.
5f25234b 1248//
1249// In general the user should take care of properly clearing the corresponding
1250// pointer here when the referred object is deleted.
1251// However, this "linking back" facility was introduced to enable AliSignal slots
1252// to refer directly to the various AliTracks to which the AliSignal object itself
1253// is related (see AliTrack::AddSignal).
1254// As such, the AliTrack destructor already takes care of clearing the corresponding
1255// links from the various AliSignal slots for all the AliSignal objects that were
1256// related to that AliTrack.
1257// So, in case the link introduced via SetLink() is the pointer of an AliTrack object,
1258// the user doesn't have to worry about clearing the corresponding AliTrack link from
1259// the AliSignal object when the corresponding AliTrack object is deleted.
1260
d0a8ef71 1261 if (!fLinks) return;
5f25234b 1262
d0a8ef71 1263 if (!obj && !j && !k)
5f25234b 1264 {
d0a8ef71 1265 fLinks->Reset();
5f25234b 1266 }
d0a8ef71 1267 else
1268 {
1269 // Note : In the internal storage matrix slots=columns positions=rows
1270 fLinks->RemoveObjects(obj,k,j);
1271 }
1272}
1273///////////////////////////////////////////////////////////////////////////
2cb7369d 1274void AliSignal::ResetLinks(TObject* obj,TString name,Int_t k)
1275{
1276// Reset single or multiple link(s) according to user specified selections.
1277//
1278// A link is only reset if the stored reference matches the argument "obj".
1279// In case obj=0 no check on the matching of the stored reference is performed
1280// and the stored link is always reset in accordance with the other
1281// selection criteria.
1282//
1283// In case the position argument "k" is specified, only the links from that
1284// specified position will be deleted.
1285// In case k=0 (default) no checking on the position index is performed.
1286//
1287// This procedure involves a slot-index search based on the specified name
1288// at each invokation. This may become slow in case many slots have been
1289// defined and/or when this procedure is invoked many times.
1290// In such cases it is preferable to use indexed addressing in the user code
1291// either directly or via a few invokations of GetSlotIndex().
1292
1293 Int_t j=GetSlotIndex(name);
1294 if (j>0) ResetLinks(obj,j,k);
1295}
1296///////////////////////////////////////////////////////////////////////////
261c0caf 1297Int_t AliSignal::GetIndices(TObject* obj,TArrayI& js,TArrayI& ks) const
d0a8ef71 1298{
1299// Provide the slot and position indices of all the storage locations
1300// of the specified object.
1301// The slot (j) and pos. (k) indices are returned in the two separate TArrayI arrays
1302// from which the (j,k) pairs can be obtained from the corresponding
1303// array indices like (j,k)=(js.At(i),ks.At(i)).
1304// The integer return argument represents the number of (j,k) pairs which
1305// were encountered for the specified object.
1306//
1307// If obj=0 no object selection is performed and all (j,k) indices
1308// of the stored references for all objects are returned.
1309//
1310// Notes :
1311// -------
1312// As usual the convention is that slot and position numbering starts at 1.
1313//
1314// This memberfunction always resets the two TArrayI arrays at the start.
1315//
1316// This memberfunction can only be used to obtain the (j,k) indices
1317// of the object as stored via the SetLink() or AddLink() memberfunction.
1318// This means that in case the user has entered a TObjArray as object
1319// (to increase the dimension of the resulting structure), the (j,k)
1320// indices of that TObjArray are obtained and NOT the indices of the
1321// actual objects contained in that TObjArray structure.
1322//
1323 Int_t nrefs=0;
1324 js.Reset();
1325 ks.Reset();
1326 // Note : In the internal storage matrix slots=columns positions=rows
1327 if (fLinks) nrefs=fLinks->GetIndices(obj,ks,js);
1328 return nrefs;
1329}
1330///////////////////////////////////////////////////////////////////////////
261c0caf 1331Int_t AliSignal::GetIndices(TObject* obj,Int_t j,TArrayI& ks) const
d0a8ef71 1332{
1333// Provide the position indices of all the storage locations of the
1334// specified object in the j-th slot of this AliSignal.
1335// The position indices are returned in the TArrayI array.
1336// The integer return argument represents the number of storage locations which
1337// were encountered for the specified object in the j-th slot.
1338//
1339// If obj=0 no object selection is performed and all position indices
1340// of the stored references for all objects of the j-th slot are returned.
1341//
1342// If j=0 all slots will be scanned and all position indices matching the
1343// object selection are returned.
1344// Note that in this case multiple appearances of the same position index
1345// will only be recorded once in the returned TArrayI array.
1346//
1347// Notes :
1348// -------
1349// As usual the convention is that slot and position numbering starts at 1.
1350//
1351// This memberfunction always resets the TArrayI array at the start.
1352//
1353// This memberfunction can only be used to obtain the position indices
1354// of the object as stored via the SetLink() or AddLink() memberfunction.
1355// This means that in case the user has entered a TObjArray as object
1356// (to increase the dimension of the resulting structure), the position
1357// indices of that TObjArray are obtained and NOT the indices of the
1358// actual objects contained in that TObjArray structure.
1359//
1360 Int_t nrefs=0;
1361 ks.Reset();
1362 // Note : In the internal storage matrix slots=columns positions=rows
1363 if (fLinks) nrefs=fLinks->GetIndices(obj,ks,j);
1364 return nrefs;
1365}
1366///////////////////////////////////////////////////////////////////////////
2cb7369d 1367Int_t AliSignal::GetIndices(TObject* obj,TString name,TArrayI& ks) const
1368{
1369// Provide the position indices of all the storage locations of the
1370// specified object in the name-specified slot of this AliSignal.
1371// The position indices are returned in the TArrayI array.
1372// The integer return argument represents the number of storage locations which
1373// were encountered for the specified object in the j-th slot.
1374//
1375// If obj=0 no object selection is performed and all position indices
1376// of the stored references for all objects of the j-th slot are returned.
1377//
1378// This procedure involves a slot-index search based on the specified name
1379// at each invokation. This may become slow in case many slots have been
1380// defined and/or when this procedure is invoked many times.
1381// In such cases it is preferable to use indexed addressing in the user code
1382// either directly or via a few invokations of GetSlotIndex().
1383
1384 Int_t j=GetSlotIndex(name);
1385 Int_t n=0;
1386 if (j>0) n=GetIndices(obj,j,ks);
1387 return n;
1388}
1389///////////////////////////////////////////////////////////////////////////
261c0caf 1390Int_t AliSignal::GetIndices(TObject* obj,TArrayI& js,Int_t k) const
d0a8ef71 1391{
1392// Provide the slot indices of all the storage locations of the
1393// specified object for the k-th position in this AliSignal.
1394// The slot indices are returned in the TArrayI array.
1395// The integer return argument represents the number of storage locations which
1396// were encountered for the specified object in the k-th position.
1397//
1398// If obj=0 no object selection is performed and all slot indices
1399// of the stored references for all objects in the k-th position are returned.
1400//
1401// If k=0 all positions will be scanned and all slot indices matching the
1402// object selection are returned.
1403// Note that in this case multiple appearances of the same slot index
1404// will only be recorded once in the returned TArrayI array.
1405//
1406// Notes :
1407// -------
1408// As usual the convention is that slot and position numbering starts at 1.
1409//
1410// This memberfunction always resets the TArrayI array at the start.
1411//
1412// This memberfunction can only be used to obtain the slot indices
1413// of the object as stored via the SetLink() or AddLink() memberfunction.
1414// This means that in case the user has entered a TObjArray as object
1415// (to increase the dimension of the resulting structure), the slot
1416// indices of that TObjArray are obtained and NOT the indices of the
1417// actual objects contained in that TObjArray structure.
1418//
1419 Int_t nrefs=0;
1420 js.Reset();
1421 // Note : In the internal storage matrix slots=columns positions=rows
1422 if (fLinks) nrefs=fLinks->GetIndices(obj,k,js);
1423 return nrefs;
1424}
1425///////////////////////////////////////////////////////////////////////////
1426void AliSignal::SetSwapMode(Int_t swap)
1427{
1428// Set swapmode flag for the internal link storage.
1429// In case for the stored links the maximum slot number differs considerably
1430// from the maximum position number, it might be more efficient
1431// (w.r.t. memory usage and/or output file size) to internally store the
1432// link reference matrix with the rows and colums swapped.
1433// This swapping is only related with the internal storage and as such
1434// is completely hidden for the user.
1435// At invokation of this memberfunction the default argument is swap=1.
1436//
1437// Note : The swap mode can only be set as long as no links are
1438// stored in the AliSignal (i.e. a new instance of AliSignal
1439// or after invokation of the Reset() or ResetLinks() function).
1440
1441 if (!fLinks) fLinks=new AliObjMatrix();
1442 fLinks->SetSwapMode(swap);
1443}
1444///////////////////////////////////////////////////////////////////////////
261c0caf 1445Int_t AliSignal::GetSwapMode() const
d0a8ef71 1446{
1447// Provide swapmode flag of the link storage.
1448 Int_t swap=0;
1449 if (fLinks) swap=fLinks->GetSwapMode();
1450 return swap;
5f25234b 1451}
1452///////////////////////////////////////////////////////////////////////////
965bd237 1453void AliSignal::SetDevice(TObject* dev)
1454{
1455// Store the pointer to the device which owns this AliSignal object.
1456// This memberfunction is meant for internal use in AliDevice.
1457 fDevice=dev;
1458}
1459///////////////////////////////////////////////////////////////////////////
1460AliDevice* AliSignal::GetDevice() const
1461{
1462// Provide the pointer to the device which owns this AliSignal object.
1463 return (AliDevice*)fDevice;
1464}
1465///////////////////////////////////////////////////////////////////////////
261c0caf 1466TObject* AliSignal::Clone(const char* name) const
c72198f1 1467{
1c01b4f8 1468// Make a deep copy of the current object and provide the pointer to the copy.
c72198f1 1469// This memberfunction enables automatic creation of new objects of the
1c01b4f8 1470// correct type depending on the object type, a feature which may be very useful
c72198f1 1471// for containers when adding objects in case the container owns the objects.
1472// This feature allows e.g. AliTrack to store either AliSignal objects or
1473// objects derived from AliSignal via the AddSignal memberfunction, provided
1c01b4f8 1474// these derived classes also have a proper Clone memberfunction.
c72198f1 1475
1c01b4f8 1476 AliSignal* sig=new AliSignal(*this);
1477 if (name)
1478 {
1479 if (strlen(name)) sig->SetName(name);
1480 }
c72198f1 1481 return sig;
1482}
1483///////////////////////////////////////////////////////////////////////////