NvE Some cosmetics in the output of AliSignal::List.
[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
7a5c405b 60// q.SetName("TOF hit");
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;
959fbac5 66// q.SetSignal(signal,1);
67// q.SetSignalError(error,1);
1fbffa23 68// q.SetOffset(offset,1);
959fbac5 69// signal=268.1; // e.g. ADC value of signal
70// error=3.75;
1fbffa23 71// gain=120.78;
959fbac5 72// q.SetSignal(signal,2);
73// q.SetSignalError(error,2);
1fbffa23 74// q.SetGain(gain,2);
959fbac5 75// signal=23.7; // e.g. corresponding dE/dx value
76// error=0.48;
1fbffa23 77// offset=0.2;
78// gain=150;
959fbac5 79// q.SetSignal(signal,3);
80// q.SetSignalError(error,3);
1fbffa23 81// q.SetOffset(offset,3);
82// q.SetGain(gain,3);
959fbac5 83//
84//--- Author: Nick van Eijndhoven 23-jan-1999 UU-SAP Utrecht
f531a546 85//- Modified: NvE $Date$ UU-SAP Utrecht
959fbac5 86///////////////////////////////////////////////////////////////////////////
87
d88f97cc 88#include "AliSignal.h"
5f25234b 89#include "AliTrack.h"
c72198f1 90#include "Riostream.h"
d88f97cc 91
92ClassImp(AliSignal) // Class implementation to enable ROOT I/O
93
1c01b4f8 94AliSignal::AliSignal() : TNamed(),AliPosition(),AliAttrib()
d88f97cc 95{
959fbac5 96// Creation of an AliSignal object and initialisation of parameters.
1fbffa23 97// Several signal values (with errors) can be stored in different slots.
fdadc78a 98// If needed, the storage for values (and errors) will be expanded automatically
99// when entering values and/or errors.
1fbffa23 100 fSignals=0;
101 fDsignals=0;
102 fWaveforms=0;
5f25234b 103 fLinks=0;
d88f97cc 104}
105///////////////////////////////////////////////////////////////////////////
106AliSignal::~AliSignal()
107{
108// Destructor to delete dynamically allocated memory
1fbffa23 109 if (fSignals)
959fbac5 110 {
1fbffa23 111 delete fSignals;
112 fSignals=0;
959fbac5 113 }
1fbffa23 114 if (fDsignals)
959fbac5 115 {
1fbffa23 116 delete fDsignals;
117 fDsignals=0;
959fbac5 118 }
1fbffa23 119 if (fWaveforms)
c72198f1 120 {
1fbffa23 121 delete fWaveforms;
122 fWaveforms=0;
c72198f1 123 }
5f25234b 124 if (fLinks)
125 {
126 delete fLinks;
127 fLinks=0;
128 }
d88f97cc 129}
130///////////////////////////////////////////////////////////////////////////
1c01b4f8 131AliSignal::AliSignal(AliSignal& s) : TNamed(s),AliPosition(s),AliAttrib(s)
8e8e6c7f 132{
133// Copy constructor
1fbffa23 134 fSignals=0;
135 fDsignals=0;
1fbffa23 136 fWaveforms=0;
5f25234b 137 fLinks=0;
8e8e6c7f 138
1fbffa23 139 Int_t n=s.GetNvalues();
140 Double_t val;
141 for (Int_t i=1; i<=n; i++)
8e8e6c7f 142 {
1fbffa23 143 val=s.GetSignal(i);
144 SetSignal(val,i);
fdadc78a 145 }
146
1fbffa23 147 n=s.GetNerrors();
148 for (Int_t j=1; j<=n; j++)
fdadc78a 149 {
1fbffa23 150 val=s.GetSignalError(j);
151 SetSignalError(val,j);
c72198f1 152 }
153
1fbffa23 154 n=s.GetNwaveforms();
155 for (Int_t k=1; k<=n; k++)
156 {
157 TH1F* hist=s.GetWaveform(k);
158 if (hist) SetWaveform(hist,k);
159 }
5f25234b 160
161 n=s.GetNlinks();
162 for (Int_t il=1; il<=n; il++)
163 {
164 TObject* obj=s.GetLink(il);
165 if (obj) SetLink(obj,il);
166 }
8e8e6c7f 167}
168///////////////////////////////////////////////////////////////////////////
fdadc78a 169void AliSignal::Reset(Int_t mode)
d88f97cc 170{
959fbac5 171// Reset all signal and position values and errors to 0.
fdadc78a 172//
173// mode = 0 Reset position and all signal values and their errors to 0.
1fbffa23 174// The waveform histograms are reset, but the calibration
175// constants (i.e. gains and offsets) are kept.
fdadc78a 176// 1 Reset position and delete the signal and error storage arrays.
1fbffa23 177// Also the waveform histograms, gains and offset arrays are deleted.
fdadc78a 178//
179// The default when invoking Reset() corresponds to mode=0.
180//
5f25234b 181// Note : In all cases the storage of the various links will be cleared
182// and the container itself will be deleted to recover the memory.
183//
fdadc78a 184// The usage of mode=0 allows to re-use the allocated memory for new
185// signal (and error) values. This behaviour is preferable (i.e. faster)
1fbffa23 186// in case the various signals always contain the same number of values
187// and have the same calibration constants.
fdadc78a 188// The usage of mode=1 is slower, but allows a more efficient memory
189// occupation (and smaller output file size) in case the different
190// signals have a variable number of values.
191//
1fbffa23 192// For more specific actions see ResetPosition(), ResetSignals(),
193// DeleteSignals(), ResetGain(), ResetOffset() and DeleteCalibrations().
c72198f1 194//
959fbac5 195
fdadc78a 196 if (mode<0 || mode>1)
959fbac5 197 {
fdadc78a 198 cout << " *AliSignal::Reset* Invalid argument mode = " << mode << endl;
199 cout << " Default mode=0 will be used." << endl;
200 mode=0;
201 }
202
203 ResetPosition();
204 if (!mode)
205 {
206 ResetSignals();
207 }
208 else
209 {
210 DeleteSignals();
1fbffa23 211 DeleteCalibrations();
959fbac5 212 }
5f25234b 213
214 if (fLinks)
215 {
216 delete fLinks;
217 fLinks=0;
218 }
959fbac5 219}
220///////////////////////////////////////////////////////////////////////////
fdadc78a 221void AliSignal::ResetSignals(Int_t mode)
959fbac5 222{
fdadc78a 223// Reset various signal data according to user selection.
224//
225// mode = 0 Reset all signal values and their errors to 0.
226// 1 Reset only signal values
227// 2 Reset only signal errors
228//
229// The default when invoking ResetSignals() corresponds to mode=0.
c72198f1 230//
1fbffa23 231// Irrespective of the mode, the waveform histograms are reset.
959fbac5 232
fdadc78a 233 if (mode<0 || mode>2)
234 {
235 cout << " *AliSignal::ResetSignals* Invalid argument mode = " << mode << endl;
236 cout << " Default mode=0 will be used." << endl;
237 mode=0;
238 }
239
1fbffa23 240 if (fSignals && (mode==0 || mode==1))
959fbac5 241 {
1fbffa23 242 for (Int_t i=0; i<fSignals->GetSize(); i++)
dafe31a2 243 {
1fbffa23 244 fSignals->AddAt(0,i);
fdadc78a 245 }
246 }
247
1fbffa23 248 if (fDsignals && (mode==0 || mode==2))
fdadc78a 249 {
1fbffa23 250 for (Int_t j=0; j<fDsignals->GetSize(); j++)
fdadc78a 251 {
1fbffa23 252 fDsignals->AddAt(0,j);
dafe31a2 253 }
959fbac5 254 }
c72198f1 255
1fbffa23 256 ResetWaveform(0);
d88f97cc 257}
258///////////////////////////////////////////////////////////////////////////
fdadc78a 259void AliSignal::DeleteSignals(Int_t mode)
260{
261// Delete storage arrays of various signal data according to user selection.
262//
263// mode = 0 Delete arrays of both signal values and their errors.
264// 1 Delete only signal values array
265// 2 Delete only signal errors array
266//
267// The default when invoking DeleteSignals() corresponds to mode=0.
c72198f1 268//
1fbffa23 269// Irrespective of the mode, the waveform histograms are deleted.
fdadc78a 270
271 if (mode<0 || mode>2)
272 {
273 cout << " *AliSignal::DeleteSignals* Invalid argument mode = " << mode << endl;
274 cout << " Default mode=0 will be used." << endl;
275 mode=0;
276 }
277
1fbffa23 278 if (fSignals && (mode==0 || mode==1))
fdadc78a 279 {
1fbffa23 280 delete fSignals;
281 fSignals=0;
fdadc78a 282 }
283
1fbffa23 284 if (fDsignals && (mode==0 || mode==2))
fdadc78a 285 {
1fbffa23 286 delete fDsignals;
287 fDsignals=0;
fdadc78a 288 }
c72198f1 289
1fbffa23 290 DeleteWaveform(0);
fdadc78a 291}
292///////////////////////////////////////////////////////////////////////////
959fbac5 293void AliSignal::SetSignal(Double_t sig,Int_t j)
d88f97cc 294{
1fbffa23 295// Store value in the j-th (default j=1) signal slot.
296// Note : The first signal slot is at j=1.
dafe31a2 297// In case the value of the index j exceeds the maximum number of reserved
fdadc78a 298// slots for signal values, the number of reserved slots for the
299// signal values is increased automatically.
959fbac5 300
1fbffa23 301 if (!fSignals)
959fbac5 302 {
1fbffa23 303 fSignals=new TArrayF(j);
fdadc78a 304 ResetSignals(1);
959fbac5 305 }
dafe31a2 306
1fbffa23 307 Int_t size=fSignals->GetSize();
dafe31a2 308
309 if (j>size)
959fbac5 310 {
1fbffa23 311 fSignals->Set(j);
959fbac5 312 }
dafe31a2 313
1fbffa23 314 fSignals->AddAt(float(sig),j-1);
d88f97cc 315}
316///////////////////////////////////////////////////////////////////////////
959fbac5 317void AliSignal::AddSignal(Double_t sig,Int_t j)
318{
1fbffa23 319// Add value to the j-th (default j=1) signal slot.
320// Note : The first signal slot is at j=1.
dafe31a2 321// In case the value of the index j exceeds the maximum number of reserved
fdadc78a 322// slots for signal values, the number of reserved slots for the
323// signal values is increased automatically.
959fbac5 324
1fbffa23 325 if (!fSignals)
959fbac5 326 {
1fbffa23 327 fSignals=new TArrayF(j);
fdadc78a 328 ResetSignals(1);
959fbac5 329 }
dafe31a2 330
1fbffa23 331 Int_t size=fSignals->GetSize();
dafe31a2 332
333 if (j>size)
959fbac5 334 {
1fbffa23 335 fSignals->Set(j);
959fbac5 336 }
dafe31a2 337
1fbffa23 338 Float_t sum=(fSignals->At(j-1))+sig;
339 fSignals->AddAt(sum,j-1);
959fbac5 340}
341///////////////////////////////////////////////////////////////////////////
1fbffa23 342Float_t AliSignal::GetSignal(Int_t j,Int_t mode)
959fbac5 343{
1fbffa23 344// Provide value of the j-th (default j=1) signal slot.
345// Note : The first signal slot is at j=1.
fdadc78a 346// In case no signal is present or the argument j is invalid, 0 is returned.
1fbffa23 347// The parameter "mode" allows for automatic gain etc... correction of the signal.
348//
349// mode = 0 : Just the j-th signal is returned.
350// 1 : The j-th signal is corrected for the gain, offset, dead flag etc...
351// In case the gain value was not set, gain=1 will be assumed.
352// In case the gain value was 0, a signal value of 0 is returned.
353// In case the offset value was not set, offset=0 will be assumed.
354// In case the j-th slot was marked dead, 0 is returned.
355//
356// The corrected signal (sigc) is determined as follows :
357//
358// sigc=(signal/gain)-offset
359//
360// The default is mode=0.
361
fdadc78a 362 Float_t sig=0;
1fbffa23 363 Float_t gain=1;
364 Float_t offset=0;
365 if (fSignals)
959fbac5 366 {
1fbffa23 367 if (j>0 && j<=(fSignals->GetSize()))
fdadc78a 368 {
1fbffa23 369 sig=fSignals->At(j-1);
370
371 if (mode==0) return sig;
372
373 // Correct the signal for the gain, offset, dead flag etc...
374 if (GetDeadValue(j)) return 0;
375
376 if (GetGainFlag(j)) gain=GetGain(j);
377 if (GetOffsetFlag(j)) offset=GetOffset(j);
378
379 if (fabs(gain)>0.)
380 {
381 sig=(sig/gain)-offset;
382 }
383 else
384 {
385 sig=0;
386 }
fdadc78a 387 }
388 else
389 {
390 cout << " *AliSignal::GetSignal* Index j = " << j << " invalid." << endl;
391 }
959fbac5 392 }
fdadc78a 393 return sig;
959fbac5 394}
395///////////////////////////////////////////////////////////////////////////
396void AliSignal::SetSignalError(Double_t dsig,Int_t j)
397{
1fbffa23 398// Store error for the j-th (default j=1) signal slot.
399// Note : The first signal slot is at j=1.
dafe31a2 400// In case the value of the index j exceeds the maximum number of reserved
fdadc78a 401// slots for signal error values, the number of reserved slots for the
402// signal errors is increased automatically.
959fbac5 403
1fbffa23 404 if (!fDsignals)
959fbac5 405 {
1fbffa23 406 fDsignals=new TArrayF(j);
fdadc78a 407 ResetSignals(2);
959fbac5 408 }
dafe31a2 409
1fbffa23 410 Int_t size=fDsignals->GetSize();
dafe31a2 411
412 if (j>size)
959fbac5 413 {
1fbffa23 414 fDsignals->Set(j);
959fbac5 415 }
dafe31a2 416
1fbffa23 417 fDsignals->AddAt(float(dsig),j-1);
959fbac5 418}
419///////////////////////////////////////////////////////////////////////////
420Float_t AliSignal::GetSignalError(Int_t j)
421{
1fbffa23 422// Provide error of the j-th (default j=1) signal slot.
423// Note : The first signal slot is at j=1.
fdadc78a 424// In case no signal is present or the argument j is invalid, 0 is returned.
425 Float_t err=0;
1fbffa23 426 if (fDsignals)
959fbac5 427 {
1fbffa23 428 if (j>0 && j<=(fDsignals->GetSize()))
fdadc78a 429 {
1fbffa23 430 err=fDsignals->At(j-1);
fdadc78a 431 }
432 else
433 {
434 cout << " *AliSignal::GetSignalError* Index j = " << j << " invalid." << endl;
435 }
959fbac5 436 }
fdadc78a 437 return err;
959fbac5 438}
439///////////////////////////////////////////////////////////////////////////
1c01b4f8 440void AliSignal::Data(TString f)
441{
442// Provide all signal information within the coordinate frame f.
443
5f25234b 444 const char* name=GetName();
445 const char* title=GetTitle();
446
447 cout << " *" << ClassName() << "::Data*";
448 if (strlen(name)) cout << " Name : " << name;
449 if (strlen(title)) cout << " Title : " << title;
450 cout << endl;
1c01b4f8 451 cout << " Position";
452 Ali3Vector::Data(f);
453
454 List(-1);
455}
456///////////////////////////////////////////////////////////////////////////
457void AliSignal::List(Int_t j)
959fbac5 458{
1c01b4f8 459// Provide signal information for the j-th slot.
1fbffa23 460// The first slot is at j=1.
461// In case j=0 (default) the data of all slots will be listed.
1c01b4f8 462// In case j=-1 the data of all slots will be listed, but the header
463// information will be suppressed.
1fbffa23 464
1c01b4f8 465 if (j<-1)
1fbffa23 466 {
1c01b4f8 467 cout << " *AliSignal::List* Invalid argument j = " << j << endl;
1fbffa23 468 return;
469 }
470
5f25234b 471 if (j != -1)
472 {
473 const char* name=GetName();
474 const char* title=GetTitle();
475
476 cout << " *" << ClassName() << "::Data*";
477 if (strlen(name)) cout << " Name : " << name;
478 if (strlen(title)) cout << " Title : " << title;
479 cout << endl;
480 }
fdadc78a 481
482 Int_t nvalues=GetNvalues();
483 Int_t nerrors=GetNerrors();
387a745b 484 Int_t nwforms=GetNwaveforms();
5f25234b 485 Int_t nlinks=GetNlinks();
1fbffa23 486 Int_t n=nvalues;
487 if (nerrors>n) n=nerrors;
387a745b 488 if (nwforms>n) n=nwforms;
5f25234b 489 if (nlinks>n) n=nlinks;
490
491 TObject* obj=0;
fdadc78a 492
1c01b4f8 493 if (j<=0)
959fbac5 494 {
1fbffa23 495 for (Int_t i=1; i<=n; i++)
959fbac5 496 {
1fbffa23 497 cout << " Signal";
498 if (i<=nvalues) cout << " value : " << GetSignal(i);
499 if (i<=nerrors) cout << " error : " << GetSignalError(i);
1c01b4f8 500 AliAttrib::List(i);
1fbffa23 501 cout << endl;
5f25234b 502 obj=GetWaveform(i);
503 if (obj)
504 {
505 const char* wfname=obj->GetName();
506 const char* wftitle=obj->GetTitle();
507 cout << " Waveform : " << obj->ClassName();
508 if (strlen(wfname)) cout << " Name : " << wfname;
509 if (strlen(wftitle)) cout << " Title : " << wftitle;
510 cout << endl;
511 }
512 obj=GetLink(i);
513 if (obj)
514 {
5f25234b 515 cout << " Link to : " << obj->ClassName();
03b59bc9 516 if (obj->InheritsFrom("TNamed"))
517 {
518 const char* lname=obj->GetName();
519 const char* ltitle=obj->GetTitle();
520 if (strlen(lname)) cout << " Name : " << lname;
521 if (strlen(ltitle)) cout << " Title : " << ltitle;
522 }
5f25234b 523 cout << endl;
524 }
1fbffa23 525 }
526 }
527 else
528 {
529 if (j<=n)
530 {
531 cout << " Signal";
532 if (j<=nvalues) cout << " value : " << GetSignal(j);
533 if (j<=nerrors) cout << " error : " << GetSignalError(j);
1c01b4f8 534 AliAttrib::List(j);
fdadc78a 535 cout << endl;
5f25234b 536 obj=GetWaveform(j);
537 if (obj)
538 {
539 const char* wfnamej=obj->GetName();
540 const char* wftitlej=obj->GetTitle();
541 cout << " Waveform : " << obj->ClassName();
542 if (strlen(wfnamej)) cout << " Name : " << wfnamej;
543 if (strlen(wftitlej)) cout << " Title : " << wftitlej;
544 cout << endl;
545 }
546 obj=GetLink(j);
547 if (obj)
548 {
5f25234b 549 cout << " Link to : " << obj->ClassName();
03b59bc9 550 if (obj->InheritsFrom("TNamed"))
551 {
552 const char* lnamej=obj->GetName();
553 const char* ltitlej=obj->GetTitle();
554 if (strlen(lnamej)) cout << " Name : " << lnamej;
555 if (strlen(ltitlej)) cout << " Title : " << ltitlej;
556 }
5f25234b 557 cout << endl;
558 }
959fbac5 559 }
560 }
561}
562///////////////////////////////////////////////////////////////////////////
8e8e6c7f 563Int_t AliSignal::GetNvalues()
564{
565// Provide the number of values for this signal.
dafe31a2 566 Int_t n=0;
1fbffa23 567 if (fSignals) n=fSignals->GetSize();
fdadc78a 568 return n;
569}
570///////////////////////////////////////////////////////////////////////////
571Int_t AliSignal::GetNerrors()
572{
573// Provide the number specified errors on the values for this signal.
574 Int_t n=0;
1fbffa23 575 if (fDsignals) n=fDsignals->GetSize();
dafe31a2 576 return n;
8e8e6c7f 577}
578///////////////////////////////////////////////////////////////////////////
1fbffa23 579Int_t AliSignal::GetNwaveforms()
c72198f1 580{
1fbffa23 581// Provide the number specified waveforms for this signal.
582 Int_t n=0;
583 if (fWaveforms) n=fWaveforms->GetSize();
584 return n;
c72198f1 585}
586///////////////////////////////////////////////////////////////////////////
1fbffa23 587TH1F* AliSignal::GetWaveform(Int_t j)
c72198f1 588{
1fbffa23 589// Provide pointer to the j-th waveform histogram.
590 TH1F* waveform=0;
591 if (j <= GetNwaveforms()) waveform=(TH1F*)fWaveforms->At(j-1);
592 return waveform;
593}
594///////////////////////////////////////////////////////////////////////////
595void AliSignal::SetWaveform(TH1F* waveform,Int_t j)
596{
597// Set the 1D waveform histogram corresponding to the j-th signal value.
598//
599// Notes :
600// The waveform of the first signal value is at j=1.
601// j=1 is the default value.
602//
603// In case the value of the index j exceeds the maximum number of reserved
604// slots for the waveforms, the number of reserved slots for the waveforms
605// is increased automatically.
c72198f1 606//
1fbffa23 607// In case the histo pointer argument has the same value as the current waveform
c72198f1 608// histogram pointer value, no action is taken since the user has already
609// modified the actual histogram.
610//
1fbffa23 611// In case the histo pointer argument is zero, the current waveform histogram
c72198f1 612// is deleted and the pointer set to zero.
613//
614// In all other cases the current waveform histogram is deleted and a new
615// copy of the input histogram is created which becomes the current waveform
616// histogram.
617
1fbffa23 618 if (!fWaveforms)
619 {
620 fWaveforms=new TObjArray(j);
621 fWaveforms->SetOwner();
622 }
623
624 if (j > fWaveforms->GetSize()) fWaveforms->Expand(j);
625
626 TH1F* hcur=(TH1F*)fWaveforms->At(j-1);
627 if (waveform != hcur)
c72198f1 628 {
1fbffa23 629 if (hcur)
c72198f1 630 {
1fbffa23 631 fWaveforms->Remove(hcur);
632 delete hcur;
633 hcur=0;
634 }
635 if (waveform)
636 {
637 hcur=new TH1F(*waveform);
638 fWaveforms->AddAt(hcur,j-1);
c72198f1 639 }
c72198f1 640 }
641}
642///////////////////////////////////////////////////////////////////////////
1fbffa23 643void AliSignal::ResetWaveform(Int_t j)
644{
645// Reset the waveform of the j-th (default j=1) signal value.
646// This memberfunction invokes TH1F::Reset() for the corresponding waveform(s).
647// To actually delete the histograms from memory, use DeleteWaveform().
648// Notes : The first signal value is at j=1.
649// j=0 ==> All waveforms will be reset.
650
651 if (!fWaveforms) return;
652
653 Int_t size=fWaveforms->GetSize();
654
655 if ((j>=0) && (j<=size))
656 {
657 if (j)
658 {
659 TH1F* hwave=(TH1F*)fWaveforms->At(j-1);
660 if (hwave) hwave->Reset();
661 }
662 else
663 {
664 for (Int_t i=0; i<size; i++)
665 {
666 TH1F* hwave=(TH1F*)fWaveforms->At(i);
667 if (hwave) hwave->Reset();
668 }
669 }
670 }
671 else
672 {
673 cout << " *AliSignal::ResetWaveform* Index j = " << j << " invalid." << endl;
674 return;
675 }
676}
677///////////////////////////////////////////////////////////////////////////
678void AliSignal::DeleteWaveform(Int_t j)
679{
680// Delete the waveform of the j-th (default j=1) signal value.
681// Notes : The first signal value is at j=1.
682// j=0 ==> All waveforms will be deleted.
683
684 if (!fWaveforms) return;
685
686 Int_t size=fWaveforms->GetSize();
687
688 if ((j>=0) && (j<=size))
689 {
690 if (j)
691 {
692 TH1F* hwave=(TH1F*)fWaveforms->At(j-1);
693 if (hwave)
694 {
695 fWaveforms->Remove(hwave);
696 delete hwave;
697 }
698 }
699 else
700 {
701 delete fWaveforms;
702 fWaveforms=0;
703 }
704 }
705 else
706 {
707 cout << " *AliSignal::DeleteWaveform* Index j = " << j << " invalid." << endl;
708 return;
709 }
710}
711///////////////////////////////////////////////////////////////////////////
5f25234b 712Int_t AliSignal::GetNlinks()
713{
714// Provide the highest slot number with a specified link for this signal.
715 Int_t n=0;
716 if (fLinks) n=fLinks->GetSize();
717 return n;
718}
719///////////////////////////////////////////////////////////////////////////
720TObject* AliSignal::GetLink(Int_t j)
721{
722// Provide pointer of the object linked to the j-th slot.
723 TObject* obj=0;
724 if (j <= GetNlinks()) obj=fLinks->At(j-1);
725 return obj;
726}
727///////////////////////////////////////////////////////////////////////////
728void AliSignal::SetLink(TObject* obj,Int_t j)
729{
730// Introduce a link (=pointer) to an object for the j-th slot.
731// Only the pointer values are stored for (backward) reference, meaning
732// that the objects of which the pointers are stored are NOT owned
733// by the AliSignal object.
734//
735// Notes :
736// The link of the first slot is at j=1.
737// j=1 is the default value.
738//
739// In case the value of the index j exceeds the maximum number of reserved
740// slots for the links, the number of reserved slots for the links
741// is increased automatically (unless the pointer argument is zero).
742//
743// In case the pointer argument is zero, indeed a value of zero will be
744// stored for the specified slot (unless j exceeds the current maximum).
745//
746// In principle any object derived from TObject can be referred to by this
747// mechanism.
748// However, this "linking back" facility was introduced to enable AliSignal slots
749// to refer directly to the various AliTracks to which the AliSignal object itself
750// is related (see AliTrack::AddSignal).
751// Therefore, in case the input argument "obj" points to an AliTrack (or derived)
752// object, the current signal is automatically related to this AliTrack
753// (or derived) object.
754//
755// Please also have a look at the docs of the memberfunction ResetLink()
756// to prevent the situation of stored pointers to non-existent object.
757
758 if (!fLinks && obj)
759 {
760 fLinks=new TObjArray(j);
761 }
762
763 if (j>fLinks->GetSize() && obj) fLinks->Expand(j);
764
765 if (j<=fLinks->GetSize())
766 {
767 fLinks->AddAt(obj,j-1);
768 if (obj)
769 {
770 if (obj->InheritsFrom("AliTrack"))
771 {
772 AliTrack* t=(AliTrack*)obj;
773 t->AddSignal(*this);
774 }
775 }
776 }
777}
778///////////////////////////////////////////////////////////////////////////
779void AliSignal::ResetLink(Int_t j)
780{
781// Reset the link of the j-th (default j=1) slot.
782// Notes : The first link position is at j=1.
783// j=0 ==> All links will be reset and the storage array deleted.
784//
785// In general the user should take care of properly clearing the corresponding
786// pointer here when the referred object is deleted.
787// However, this "linking back" facility was introduced to enable AliSignal slots
788// to refer directly to the various AliTracks to which the AliSignal object itself
789// is related (see AliTrack::AddSignal).
790// As such, the AliTrack destructor already takes care of clearing the corresponding
791// links from the various AliSignal slots for all the AliSignal objects that were
792// related to that AliTrack.
793// So, in case the link introduced via SetLink() is the pointer of an AliTrack object,
794// the user doesn't have to worry about clearing the corresponding AliTrack link from
795// the AliSignal object when the corresponding AliTrack object is deleted.
796
797 if (!fLinks || j<0) return;
798
799 TObject* obj=0;
800
801 if (j)
802 {
803 SetLink(obj,j);
804 }
805 else
806 {
807 delete fLinks;
808 fLinks=0;
809 }
810}
811///////////////////////////////////////////////////////////////////////////
812void AliSignal::ResetLink(TObject* obj)
813{
814// Reset the link of the all the slots referring to the specified object.
815//
816// In general the user should take care of properly clearing the corresponding
817// pointer here when the referred object is deleted.
818// However, this "linking back" facility was introduced to enable AliSignal slots
819// to refer directly to the various AliTracks to which the AliSignal object itself
820// is related (see AliTrack::AddSignal).
821// As such, the AliTrack destructor already takes care of clearing the corresponding
822// links from the various AliSignal slots for all the AliSignal objects that were
823// related to that AliTrack.
824// So, in case the link introduced via SetLink() is the pointer of an AliTrack object,
825// the user doesn't have to worry about clearing the corresponding AliTrack link from
826// the AliSignal object when the corresponding AliTrack object is deleted.
827
828 if (!fLinks || !obj) return;
829
830 Int_t nlinks=GetNlinks();
831 for (Int_t i=1; i<=nlinks; i++)
832 {
833 TObject* obj2=GetLink(i);
834 if (obj2==obj) ResetLink(i);
835 }
836}
837///////////////////////////////////////////////////////////////////////////
1c01b4f8 838TObject* AliSignal::Clone(char* name)
c72198f1 839{
1c01b4f8 840// Make a deep copy of the current object and provide the pointer to the copy.
c72198f1 841// This memberfunction enables automatic creation of new objects of the
1c01b4f8 842// correct type depending on the object type, a feature which may be very useful
c72198f1 843// for containers when adding objects in case the container owns the objects.
844// This feature allows e.g. AliTrack to store either AliSignal objects or
845// objects derived from AliSignal via the AddSignal memberfunction, provided
1c01b4f8 846// these derived classes also have a proper Clone memberfunction.
c72198f1 847
1c01b4f8 848 AliSignal* sig=new AliSignal(*this);
849 if (name)
850 {
851 if (strlen(name)) sig->SetName(name);
852 }
c72198f1 853 return sig;
854}
855///////////////////////////////////////////////////////////////////////////