]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RALICE/AliSignal.cxx
Coding Convention Violations
[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
d0a8ef71 161 TArrayI slotarr;
162 TArrayI posarr;
163 TObject* dum=0;
164 n=s.GetIndices(dum,slotarr,posarr);
165 Int_t slot,pos;
166 for (Int_t idx=0; idx<n; idx++)
5f25234b 167 {
d0a8ef71 168 slot=slotarr.At(idx);
169 pos=posarr.At(idx);
170 TObject* obj=s.GetLink(slot,pos);
171 if (obj) SetLink(obj,slot,pos);
5f25234b 172 }
8e8e6c7f 173}
174///////////////////////////////////////////////////////////////////////////
fdadc78a 175void AliSignal::Reset(Int_t mode)
d88f97cc 176{
959fbac5 177// Reset all signal and position values and errors to 0.
fdadc78a 178//
179// mode = 0 Reset position and all signal values and their errors to 0.
1fbffa23 180// The waveform histograms are reset, but the calibration
181// constants (i.e. gains and offsets) are kept.
fdadc78a 182// 1 Reset position and delete the signal and error storage arrays.
1fbffa23 183// Also the waveform histograms, gains and offset arrays are deleted.
fdadc78a 184//
185// The default when invoking Reset() corresponds to mode=0.
186//
d0a8ef71 187// Note : In all cases the storage of the various links will be reset.
5f25234b 188//
fdadc78a 189// The usage of mode=0 allows to re-use the allocated memory for new
190// signal (and error) values. This behaviour is preferable (i.e. faster)
1fbffa23 191// in case the various signals always contain the same number of values
192// and have the same calibration constants.
fdadc78a 193// The usage of mode=1 is slower, but allows a more efficient memory
194// occupation (and smaller output file size) in case the different
195// signals have a variable number of values.
196//
1fbffa23 197// For more specific actions see ResetPosition(), ResetSignals(),
d0a8ef71 198// DeleteSignals(), ResetGain(), ResetOffset(), ResetLink(), ResetWaveform(),
199// DeleteWaveform() and DeleteCalibrations().
c72198f1 200//
959fbac5 201
fdadc78a 202 if (mode<0 || mode>1)
959fbac5 203 {
fdadc78a 204 cout << " *AliSignal::Reset* Invalid argument mode = " << mode << endl;
205 cout << " Default mode=0 will be used." << endl;
206 mode=0;
207 }
208
209 ResetPosition();
210 if (!mode)
211 {
212 ResetSignals();
213 }
214 else
215 {
216 DeleteSignals();
1fbffa23 217 DeleteCalibrations();
959fbac5 218 }
5f25234b 219
d0a8ef71 220 if (fLinks) fLinks->Reset();
959fbac5 221}
222///////////////////////////////////////////////////////////////////////////
fdadc78a 223void AliSignal::ResetSignals(Int_t mode)
959fbac5 224{
fdadc78a 225// Reset various signal data according to user selection.
226//
227// mode = 0 Reset all signal values and their errors to 0.
228// 1 Reset only signal values
229// 2 Reset only signal errors
230//
231// The default when invoking ResetSignals() corresponds to mode=0.
c72198f1 232//
1fbffa23 233// Irrespective of the mode, the waveform histograms are reset.
959fbac5 234
fdadc78a 235 if (mode<0 || mode>2)
236 {
237 cout << " *AliSignal::ResetSignals* Invalid argument mode = " << mode << endl;
238 cout << " Default mode=0 will be used." << endl;
239 mode=0;
240 }
241
1fbffa23 242 if (fSignals && (mode==0 || mode==1))
959fbac5 243 {
1fbffa23 244 for (Int_t i=0; i<fSignals->GetSize(); i++)
dafe31a2 245 {
1fbffa23 246 fSignals->AddAt(0,i);
fdadc78a 247 }
248 }
249
1fbffa23 250 if (fDsignals && (mode==0 || mode==2))
fdadc78a 251 {
1fbffa23 252 for (Int_t j=0; j<fDsignals->GetSize(); j++)
fdadc78a 253 {
1fbffa23 254 fDsignals->AddAt(0,j);
dafe31a2 255 }
959fbac5 256 }
c72198f1 257
1fbffa23 258 ResetWaveform(0);
d88f97cc 259}
260///////////////////////////////////////////////////////////////////////////
fdadc78a 261void AliSignal::DeleteSignals(Int_t mode)
262{
263// Delete storage arrays of various signal data according to user selection.
264//
265// mode = 0 Delete arrays of both signal values and their errors.
266// 1 Delete only signal values array
267// 2 Delete only signal errors array
268//
269// The default when invoking DeleteSignals() corresponds to mode=0.
c72198f1 270//
1fbffa23 271// Irrespective of the mode, the waveform histograms are deleted.
fdadc78a 272
273 if (mode<0 || mode>2)
274 {
275 cout << " *AliSignal::DeleteSignals* Invalid argument mode = " << mode << endl;
276 cout << " Default mode=0 will be used." << endl;
277 mode=0;
278 }
279
1fbffa23 280 if (fSignals && (mode==0 || mode==1))
fdadc78a 281 {
1fbffa23 282 delete fSignals;
283 fSignals=0;
fdadc78a 284 }
285
1fbffa23 286 if (fDsignals && (mode==0 || mode==2))
fdadc78a 287 {
1fbffa23 288 delete fDsignals;
289 fDsignals=0;
fdadc78a 290 }
c72198f1 291
1fbffa23 292 DeleteWaveform(0);
fdadc78a 293}
294///////////////////////////////////////////////////////////////////////////
959fbac5 295void AliSignal::SetSignal(Double_t sig,Int_t j)
d88f97cc 296{
1fbffa23 297// Store value in the j-th (default j=1) signal slot.
298// Note : The first signal slot is at j=1.
dafe31a2 299// In case the value of the index j exceeds the maximum number of reserved
fdadc78a 300// slots for signal values, the number of reserved slots for the
301// signal values is increased automatically.
959fbac5 302
1fbffa23 303 if (!fSignals)
959fbac5 304 {
1fbffa23 305 fSignals=new TArrayF(j);
fdadc78a 306 ResetSignals(1);
959fbac5 307 }
dafe31a2 308
1fbffa23 309 Int_t size=fSignals->GetSize();
dafe31a2 310
311 if (j>size)
959fbac5 312 {
1fbffa23 313 fSignals->Set(j);
959fbac5 314 }
dafe31a2 315
1fbffa23 316 fSignals->AddAt(float(sig),j-1);
d88f97cc 317}
318///////////////////////////////////////////////////////////////////////////
959fbac5 319void AliSignal::AddSignal(Double_t sig,Int_t j)
320{
1fbffa23 321// Add value to the j-th (default j=1) signal slot.
322// Note : The first signal slot is at j=1.
dafe31a2 323// In case the value of the index j exceeds the maximum number of reserved
fdadc78a 324// slots for signal values, the number of reserved slots for the
325// signal values is increased automatically.
959fbac5 326
1fbffa23 327 if (!fSignals)
959fbac5 328 {
1fbffa23 329 fSignals=new TArrayF(j);
fdadc78a 330 ResetSignals(1);
959fbac5 331 }
dafe31a2 332
1fbffa23 333 Int_t size=fSignals->GetSize();
dafe31a2 334
335 if (j>size)
959fbac5 336 {
1fbffa23 337 fSignals->Set(j);
959fbac5 338 }
dafe31a2 339
1fbffa23 340 Float_t sum=(fSignals->At(j-1))+sig;
341 fSignals->AddAt(sum,j-1);
959fbac5 342}
343///////////////////////////////////////////////////////////////////////////
1fbffa23 344Float_t AliSignal::GetSignal(Int_t j,Int_t mode)
959fbac5 345{
1fbffa23 346// Provide value of the j-th (default j=1) signal slot.
347// Note : The first signal slot is at j=1.
fdadc78a 348// In case no signal is present or the argument j is invalid, 0 is returned.
1fbffa23 349// The parameter "mode" allows for automatic gain etc... correction of the signal.
350//
351// mode = 0 : Just the j-th signal is returned.
352// 1 : The j-th signal is corrected for the gain, offset, dead flag etc...
353// In case the gain value was not set, gain=1 will be assumed.
354// In case the gain value was 0, a signal value of 0 is returned.
355// In case the offset value was not set, offset=0 will be assumed.
356// In case the j-th slot was marked dead, 0 is returned.
357//
358// The corrected signal (sigc) is determined as follows :
359//
360// sigc=(signal/gain)-offset
361//
362// The default is mode=0.
363
fdadc78a 364 Float_t sig=0;
1fbffa23 365 Float_t gain=1;
366 Float_t offset=0;
367 if (fSignals)
959fbac5 368 {
1fbffa23 369 if (j>0 && j<=(fSignals->GetSize()))
fdadc78a 370 {
1fbffa23 371 sig=fSignals->At(j-1);
372
373 if (mode==0) return sig;
374
375 // Correct the signal for the gain, offset, dead flag etc...
376 if (GetDeadValue(j)) return 0;
377
378 if (GetGainFlag(j)) gain=GetGain(j);
379 if (GetOffsetFlag(j)) offset=GetOffset(j);
380
381 if (fabs(gain)>0.)
382 {
383 sig=(sig/gain)-offset;
384 }
385 else
386 {
387 sig=0;
388 }
fdadc78a 389 }
390 else
391 {
392 cout << " *AliSignal::GetSignal* Index j = " << j << " invalid." << endl;
393 }
959fbac5 394 }
fdadc78a 395 return sig;
959fbac5 396}
397///////////////////////////////////////////////////////////////////////////
398void AliSignal::SetSignalError(Double_t dsig,Int_t j)
399{
1fbffa23 400// Store error for the j-th (default j=1) signal slot.
401// Note : The first signal slot is at j=1.
dafe31a2 402// In case the value of the index j exceeds the maximum number of reserved
fdadc78a 403// slots for signal error values, the number of reserved slots for the
404// signal errors is increased automatically.
959fbac5 405
1fbffa23 406 if (!fDsignals)
959fbac5 407 {
1fbffa23 408 fDsignals=new TArrayF(j);
fdadc78a 409 ResetSignals(2);
959fbac5 410 }
dafe31a2 411
1fbffa23 412 Int_t size=fDsignals->GetSize();
dafe31a2 413
414 if (j>size)
959fbac5 415 {
1fbffa23 416 fDsignals->Set(j);
959fbac5 417 }
dafe31a2 418
1fbffa23 419 fDsignals->AddAt(float(dsig),j-1);
959fbac5 420}
421///////////////////////////////////////////////////////////////////////////
422Float_t AliSignal::GetSignalError(Int_t j)
423{
1fbffa23 424// Provide error of the j-th (default j=1) signal slot.
425// Note : The first signal slot is at j=1.
fdadc78a 426// In case no signal is present or the argument j is invalid, 0 is returned.
427 Float_t err=0;
1fbffa23 428 if (fDsignals)
959fbac5 429 {
1fbffa23 430 if (j>0 && j<=(fDsignals->GetSize()))
fdadc78a 431 {
1fbffa23 432 err=fDsignals->At(j-1);
fdadc78a 433 }
434 else
435 {
436 cout << " *AliSignal::GetSignalError* Index j = " << j << " invalid." << endl;
437 }
959fbac5 438 }
fdadc78a 439 return err;
959fbac5 440}
441///////////////////////////////////////////////////////////////////////////
1c01b4f8 442void AliSignal::Data(TString f)
443{
444// Provide all signal information within the coordinate frame f.
445
5f25234b 446 const char* name=GetName();
447 const char* title=GetTitle();
448
449 cout << " *" << ClassName() << "::Data*";
450 if (strlen(name)) cout << " Name : " << name;
451 if (strlen(title)) cout << " Title : " << title;
452 cout << endl;
d0a8ef71 453 cout << " Position";
1c01b4f8 454 Ali3Vector::Data(f);
455
456 List(-1);
457}
458///////////////////////////////////////////////////////////////////////////
459void AliSignal::List(Int_t j)
959fbac5 460{
1c01b4f8 461// Provide signal information for the j-th slot.
1fbffa23 462// The first slot is at j=1.
463// In case j=0 (default) the data of all slots will be listed.
1c01b4f8 464// In case j=-1 the data of all slots will be listed, but the header
465// information will be suppressed.
1fbffa23 466
1c01b4f8 467 if (j<-1)
1fbffa23 468 {
1c01b4f8 469 cout << " *AliSignal::List* Invalid argument j = " << j << endl;
1fbffa23 470 return;
471 }
472
5f25234b 473 if (j != -1)
474 {
475 const char* name=GetName();
476 const char* title=GetTitle();
477
478 cout << " *" << ClassName() << "::Data*";
479 if (strlen(name)) cout << " Name : " << name;
480 if (strlen(title)) cout << " Title : " << title;
481 cout << endl;
482 }
fdadc78a 483
484 Int_t nvalues=GetNvalues();
485 Int_t nerrors=GetNerrors();
387a745b 486 Int_t nwforms=GetNwaveforms();
d0a8ef71 487 Int_t nlinkslots=0;
488 if (fLinks) nlinkslots=fLinks->GetMaxColumn();
1fbffa23 489 Int_t n=nvalues;
490 if (nerrors>n) n=nerrors;
387a745b 491 if (nwforms>n) n=nwforms;
d0a8ef71 492 if (nlinkslots>n) n=nlinkslots;
5f25234b 493
494 TObject* obj=0;
d0a8ef71 495 Int_t nrefs=0;
496 TArrayI posarr;
497 Int_t pos;
fdadc78a 498
1c01b4f8 499 if (j<=0)
959fbac5 500 {
1fbffa23 501 for (Int_t i=1; i<=n; i++)
959fbac5 502 {
d0a8ef71 503 cout << " Slot : " << i;
504 if (i<=nvalues) cout << " Signal value : " << GetSignal(i);
1fbffa23 505 if (i<=nerrors) cout << " error : " << GetSignalError(i);
1c01b4f8 506 AliAttrib::List(i);
1fbffa23 507 cout << endl;
5f25234b 508 obj=GetWaveform(i);
509 if (obj)
510 {
511 const char* wfname=obj->GetName();
512 const char* wftitle=obj->GetTitle();
513 cout << " Waveform : " << obj->ClassName();
514 if (strlen(wfname)) cout << " Name : " << wfname;
515 if (strlen(wftitle)) cout << " Title : " << wftitle;
516 cout << endl;
517 }
d0a8ef71 518 obj=0;
519 nrefs=GetIndices(obj,i,posarr);
520 for (Int_t k=0; k<nrefs; k++)
5f25234b 521 {
d0a8ef71 522 pos=posarr.At(k);
523 obj=GetLink(i,pos);
524 if (obj)
03b59bc9 525 {
d0a8ef71 526 cout << " Link at position " << pos << " to : " << obj->ClassName();
527 if (obj->InheritsFrom("TNamed"))
528 {
529 const char* lname=obj->GetName();
530 const char* ltitle=obj->GetTitle();
531 if (strlen(lname)) cout << " Name : " << lname;
532 if (strlen(ltitle)) cout << " Title : " << ltitle;
533 }
534 cout << endl;
03b59bc9 535 }
5f25234b 536 }
1fbffa23 537 }
538 }
539 else
540 {
541 if (j<=n)
542 {
d0a8ef71 543 cout << " Slot : " << j;
544 if (j<=nvalues) cout << " Signal value : " << GetSignal(j);
1fbffa23 545 if (j<=nerrors) cout << " error : " << GetSignalError(j);
1c01b4f8 546 AliAttrib::List(j);
fdadc78a 547 cout << endl;
5f25234b 548 obj=GetWaveform(j);
549 if (obj)
550 {
551 const char* wfnamej=obj->GetName();
552 const char* wftitlej=obj->GetTitle();
553 cout << " Waveform : " << obj->ClassName();
554 if (strlen(wfnamej)) cout << " Name : " << wfnamej;
555 if (strlen(wftitlej)) cout << " Title : " << wftitlej;
556 cout << endl;
557 }
d0a8ef71 558 obj=0;
559 nrefs=GetIndices(obj,j,posarr);
560 for (Int_t kj=0; kj<nrefs; kj++)
5f25234b 561 {
d0a8ef71 562 pos=posarr.At(kj);
563 obj=GetLink(j,pos);
564 if (obj)
03b59bc9 565 {
d0a8ef71 566 cout << " Link at position " << pos << " to : " << obj->ClassName();
567 if (obj->InheritsFrom("TNamed"))
568 {
569 const char* lnamej=obj->GetName();
570 const char* ltitlej=obj->GetTitle();
571 if (strlen(lnamej)) cout << " Name : " << lnamej;
572 if (strlen(ltitlej)) cout << " Title : " << ltitlej;
573 }
574 cout << endl;
03b59bc9 575 }
5f25234b 576 }
959fbac5 577 }
578 }
579}
580///////////////////////////////////////////////////////////////////////////
8e8e6c7f 581Int_t AliSignal::GetNvalues()
582{
583// Provide the number of values for this signal.
dafe31a2 584 Int_t n=0;
1fbffa23 585 if (fSignals) n=fSignals->GetSize();
fdadc78a 586 return n;
587}
588///////////////////////////////////////////////////////////////////////////
589Int_t AliSignal::GetNerrors()
590{
591// Provide the number specified errors on the values for this signal.
592 Int_t n=0;
1fbffa23 593 if (fDsignals) n=fDsignals->GetSize();
dafe31a2 594 return n;
8e8e6c7f 595}
596///////////////////////////////////////////////////////////////////////////
1fbffa23 597Int_t AliSignal::GetNwaveforms()
c72198f1 598{
1fbffa23 599// Provide the number specified waveforms for this signal.
600 Int_t n=0;
601 if (fWaveforms) n=fWaveforms->GetSize();
602 return n;
c72198f1 603}
604///////////////////////////////////////////////////////////////////////////
1fbffa23 605TH1F* AliSignal::GetWaveform(Int_t j)
c72198f1 606{
1fbffa23 607// Provide pointer to the j-th waveform histogram.
608 TH1F* waveform=0;
609 if (j <= GetNwaveforms()) waveform=(TH1F*)fWaveforms->At(j-1);
610 return waveform;
611}
612///////////////////////////////////////////////////////////////////////////
613void AliSignal::SetWaveform(TH1F* waveform,Int_t j)
614{
615// Set the 1D waveform histogram corresponding to the j-th signal value.
616//
617// Notes :
618// The waveform of the first signal value is at j=1.
619// j=1 is the default value.
620//
621// In case the value of the index j exceeds the maximum number of reserved
622// slots for the waveforms, the number of reserved slots for the waveforms
623// is increased automatically.
c72198f1 624//
1fbffa23 625// In case the histo pointer argument has the same value as the current waveform
c72198f1 626// histogram pointer value, no action is taken since the user has already
627// modified the actual histogram.
628//
1fbffa23 629// In case the histo pointer argument is zero, the current waveform histogram
c72198f1 630// is deleted and the pointer set to zero.
631//
632// In all other cases the current waveform histogram is deleted and a new
633// copy of the input histogram is created which becomes the current waveform
634// histogram.
635
1fbffa23 636 if (!fWaveforms)
637 {
638 fWaveforms=new TObjArray(j);
639 fWaveforms->SetOwner();
640 }
641
642 if (j > fWaveforms->GetSize()) fWaveforms->Expand(j);
643
644 TH1F* hcur=(TH1F*)fWaveforms->At(j-1);
645 if (waveform != hcur)
c72198f1 646 {
1fbffa23 647 if (hcur)
c72198f1 648 {
1fbffa23 649 fWaveforms->Remove(hcur);
650 delete hcur;
651 hcur=0;
652 }
653 if (waveform)
654 {
655 hcur=new TH1F(*waveform);
656 fWaveforms->AddAt(hcur,j-1);
c72198f1 657 }
c72198f1 658 }
659}
660///////////////////////////////////////////////////////////////////////////
1fbffa23 661void AliSignal::ResetWaveform(Int_t j)
662{
663// Reset the waveform of the j-th (default j=1) signal value.
664// This memberfunction invokes TH1F::Reset() for the corresponding waveform(s).
665// To actually delete the histograms from memory, use DeleteWaveform().
666// Notes : The first signal value is at j=1.
667// j=0 ==> All waveforms will be reset.
668
669 if (!fWaveforms) return;
670
671 Int_t size=fWaveforms->GetSize();
672
673 if ((j>=0) && (j<=size))
674 {
675 if (j)
676 {
677 TH1F* hwave=(TH1F*)fWaveforms->At(j-1);
678 if (hwave) hwave->Reset();
679 }
680 else
681 {
682 for (Int_t i=0; i<size; i++)
683 {
684 TH1F* hwave=(TH1F*)fWaveforms->At(i);
685 if (hwave) hwave->Reset();
686 }
687 }
688 }
689 else
690 {
691 cout << " *AliSignal::ResetWaveform* Index j = " << j << " invalid." << endl;
692 return;
693 }
694}
695///////////////////////////////////////////////////////////////////////////
696void AliSignal::DeleteWaveform(Int_t j)
697{
698// Delete the waveform of the j-th (default j=1) signal value.
699// Notes : The first signal value is at j=1.
700// j=0 ==> All waveforms will be deleted.
701
702 if (!fWaveforms) return;
703
704 Int_t size=fWaveforms->GetSize();
705
706 if ((j>=0) && (j<=size))
707 {
708 if (j)
709 {
710 TH1F* hwave=(TH1F*)fWaveforms->At(j-1);
711 if (hwave)
712 {
713 fWaveforms->Remove(hwave);
714 delete hwave;
715 }
716 }
717 else
718 {
719 delete fWaveforms;
720 fWaveforms=0;
721 }
722 }
723 else
724 {
725 cout << " *AliSignal::DeleteWaveform* Index j = " << j << " invalid." << endl;
726 return;
727 }
728}
729///////////////////////////////////////////////////////////////////////////
d0a8ef71 730Int_t AliSignal::GetNlinks(TObject* obj,Int_t j)
5f25234b 731{
d0a8ef71 732// Provide the number of links to the specified object for the j-th slot.
733// If j=0 (default) all slots will be scanned for the specified object.
734// If obj=0 (default) all encountered objects for the specified slot will be counted.
735// So, invokation of the default GetNlinks() will return the total number of
736// all references to all sorts of stored objects.
737 if (j<0)
738 {
739 cout << " *AliSignal::GetNlinks* Index j = " << j << " invalid." << endl;
740 return 0;
741 }
742
5f25234b 743 Int_t n=0;
d0a8ef71 744 if (!j)
745 {
746 n=fLinks->GetNrefs(obj);
747 }
748 else
749 {
750 TArrayI posarr;
751 n=GetIndices(obj,j,posarr);
752 }
5f25234b 753 return n;
754}
755///////////////////////////////////////////////////////////////////////////
d0a8ef71 756TObject* AliSignal::GetLink(Int_t j,Int_t k)
5f25234b 757{
d0a8ef71 758// Provide pointer of the object linked to the j-th slot at position k.
759
5f25234b 760 TObject* obj=0;
d0a8ef71 761 // Note : In the internal storage matrix slots=columns positions=rows
762 if (fLinks) obj=fLinks->GetObject(k,j);
5f25234b 763 return obj;
764}
765///////////////////////////////////////////////////////////////////////////
d0a8ef71 766void AliSignal::SetLink(TObject* obj,Int_t j,Int_t k)
5f25234b 767{
d0a8ef71 768// Introduce a link (=pointer) to an object for the j-th slot at position k.
5f25234b 769// Only the pointer values are stored for (backward) reference, meaning
770// that the objects of which the pointers are stored are NOT owned
771// by the AliSignal object.
772//
773// Notes :
d0a8ef71 774// The first slot is at j=1 and the first position is at k=1.
775// j=1 and k=1 are the default values.
5f25234b 776//
d0a8ef71 777// If needed, the storage area for the links is increased automatically.
5f25234b 778//
779// In case the pointer argument is zero, indeed a value of zero will be
d0a8ef71 780// stored at the specified position (k) for the specified slot (j).
5f25234b 781//
782// In principle any object derived from TObject can be referred to by this
783// mechanism.
784// However, this "linking back" facility was introduced to enable AliSignal slots
785// to refer directly to the various AliTracks to which the AliSignal object itself
786// is related (see AliTrack::AddSignal).
787// Therefore, in case the input argument "obj" points to an AliTrack (or derived)
788// object, the current signal is automatically related to this AliTrack
789// (or derived) object.
790//
791// Please also have a look at the docs of the memberfunction ResetLink()
792// to prevent the situation of stored pointers to non-existent object.
793
d0a8ef71 794 if (!fLinks && obj) fLinks=new AliObjMatrix();
5f25234b 795
d0a8ef71 796 if (!fLinks) return;
5f25234b 797
d0a8ef71 798 // Note : In the internal storage matrix slots=columns positions=rows
799 fLinks->EnterObject(k,j,obj);
800 if (obj)
5f25234b 801 {
d0a8ef71 802 if (obj->InheritsFrom("AliTrack"))
5f25234b 803 {
d0a8ef71 804 AliTrack* t=(AliTrack*)obj;
805 t->AddSignal(*this);
5f25234b 806 }
807 }
808}
809///////////////////////////////////////////////////////////////////////////
d0a8ef71 810void AliSignal::AddLink(TObject* obj,Int_t j)
811{
812// Introduce a link (=pointer) to an object for the j-th slot at the first
813// free position.
814// Only the pointer values are stored for (backward) reference, meaning
815// that the objects of which the pointers are stored are NOT owned
816// by the AliSignal object.
817//
818// Notes :
819// The first slot is at j=1 and the first position is at k=1.
820// j=1 is the default value.
821//
822// If needed, the storage area for the links is increased automatically.
823//
824// In case the pointer argument is zero, no link will be added.
825//
826// In principle any object derived from TObject can be referred to by this
827// mechanism.
828// However, this "linking back" facility was introduced to enable AliSignal slots
829// to refer directly to the various AliTracks to which the AliSignal object itself
830// is related (see AliTrack::AddSignal).
831// Therefore, in case the input argument "obj" points to an AliTrack (or derived)
832// object, the current signal is automatically related to this AliTrack
833// (or derived) object.
834//
835// Please also have a look at the docs of the memberfunction ResetLink()
836// to prevent the situation of stored pointers to non-existent object.
837
838 if (!obj || j<=0) return;
839
840 if (!fLinks) fLinks=new AliObjMatrix();
841
842 TObject* dum=0;
843 Int_t n=GetNlinks(dum,j);
844 Int_t pos=1;
845 for (Int_t k=1; k<=n; k++)
846 {
847 dum=GetLink(j,k);
848 if (!dum) break;
849 pos++;
850 }
851
852 SetLink(obj,j,pos);
853}
854///////////////////////////////////////////////////////////////////////////
855void AliSignal::ResetLink(Int_t j,Int_t k)
5f25234b 856{
d0a8ef71 857// Reset the link of the j-th slot at position k.
858//
859// Notes :
860// The first slot is at j=1 and the first position is at k=1.
861// j=1 and k=1 are the default values.
862//
863// This memberfunction is intended to reset only 1 specified link location.
864// For extended functionality, please refer to the memberfuction ResetLinks().
5f25234b 865//
866// In general the user should take care of properly clearing the corresponding
867// pointer here when the referred object is deleted.
868// However, this "linking back" facility was introduced to enable AliSignal slots
869// to refer directly to the various AliTracks to which the AliSignal object itself
870// is related (see AliTrack::AddSignal).
871// As such, the AliTrack destructor already takes care of clearing the corresponding
872// links from the various AliSignal slots for all the AliSignal objects that were
873// related to that AliTrack.
874// So, in case the link introduced via SetLink() is the pointer of an AliTrack object,
875// the user doesn't have to worry about clearing the corresponding AliTrack link from
876// the AliSignal object when the corresponding AliTrack object is deleted.
877
d0a8ef71 878 // Note : In the internal storage matrix slots=columns positions=rows
879 if (fLinks) fLinks->RemoveObject(k,j);
5f25234b 880}
881///////////////////////////////////////////////////////////////////////////
d0a8ef71 882void AliSignal::ResetLinks(TObject* obj,Int_t j,Int_t k)
5f25234b 883{
d0a8ef71 884// Reset single or multiple link(s) according to user specified selections.
885//
886// A link is only reset if the stored reference matches the argument "obj".
887// In case obj=0 no check on the matching of the stored reference is performed
888// and the stored link is always reset in accordance with the other
889// selection criteria.
890//
891// In case the slot argument "j" is specified, only the links from that
892// specified slot will be deleted.
893// In case j=0 (default) no checking on the slot index is performed.
894//
895// In case the position argument "k" is specified, only the links from that
896// specified position will be deleted.
897// In case k=0 (default) no checking on the position index is performed.
898//
899// So, invokation of ResetLinks(obj) will remove all references to the
900// object "obj" from the total AliSignal, whereas ResetLinks(obj,j)
901// will remove all references to the object "obj" only from slot "j".
902//
903// Notes :
904// -------
905// The first slot is indicated as j=1, whereas the first position is at k=1.
906//
907// Invokation of ResetLinks(0,row,col) is equivalent to invoking the
908// memberfunction ResetLink(row,col).
909// Invoking the latter directly is slightly faster.
910//
911// Invokation of ResetLinks(0) will reset all stored references in this AliSignal.
5f25234b 912//
913// In general the user should take care of properly clearing the corresponding
914// pointer here when the referred object is deleted.
915// However, this "linking back" facility was introduced to enable AliSignal slots
916// to refer directly to the various AliTracks to which the AliSignal object itself
917// is related (see AliTrack::AddSignal).
918// As such, the AliTrack destructor already takes care of clearing the corresponding
919// links from the various AliSignal slots for all the AliSignal objects that were
920// related to that AliTrack.
921// So, in case the link introduced via SetLink() is the pointer of an AliTrack object,
922// the user doesn't have to worry about clearing the corresponding AliTrack link from
923// the AliSignal object when the corresponding AliTrack object is deleted.
924
d0a8ef71 925 if (!fLinks) return;
5f25234b 926
d0a8ef71 927 if (!obj && !j && !k)
5f25234b 928 {
d0a8ef71 929 fLinks->Reset();
5f25234b 930 }
d0a8ef71 931 else
932 {
933 // Note : In the internal storage matrix slots=columns positions=rows
934 fLinks->RemoveObjects(obj,k,j);
935 }
936}
937///////////////////////////////////////////////////////////////////////////
938Int_t AliSignal::GetIndices(TObject* obj,TArrayI& js,TArrayI& ks)
939{
940// Provide the slot and position indices of all the storage locations
941// of the specified object.
942// The slot (j) and pos. (k) indices are returned in the two separate TArrayI arrays
943// from which the (j,k) pairs can be obtained from the corresponding
944// array indices like (j,k)=(js.At(i),ks.At(i)).
945// The integer return argument represents the number of (j,k) pairs which
946// were encountered for the specified object.
947//
948// If obj=0 no object selection is performed and all (j,k) indices
949// of the stored references for all objects are returned.
950//
951// Notes :
952// -------
953// As usual the convention is that slot and position numbering starts at 1.
954//
955// This memberfunction always resets the two TArrayI arrays at the start.
956//
957// This memberfunction can only be used to obtain the (j,k) indices
958// of the object as stored via the SetLink() or AddLink() memberfunction.
959// This means that in case the user has entered a TObjArray as object
960// (to increase the dimension of the resulting structure), the (j,k)
961// indices of that TObjArray are obtained and NOT the indices of the
962// actual objects contained in that TObjArray structure.
963//
964 Int_t nrefs=0;
965 js.Reset();
966 ks.Reset();
967 // Note : In the internal storage matrix slots=columns positions=rows
968 if (fLinks) nrefs=fLinks->GetIndices(obj,ks,js);
969 return nrefs;
970}
971///////////////////////////////////////////////////////////////////////////
972Int_t AliSignal::GetIndices(TObject* obj,Int_t j,TArrayI& ks)
973{
974// Provide the position indices of all the storage locations of the
975// specified object in the j-th slot of this AliSignal.
976// The position indices are returned in the TArrayI array.
977// The integer return argument represents the number of storage locations which
978// were encountered for the specified object in the j-th slot.
979//
980// If obj=0 no object selection is performed and all position indices
981// of the stored references for all objects of the j-th slot are returned.
982//
983// If j=0 all slots will be scanned and all position indices matching the
984// object selection are returned.
985// Note that in this case multiple appearances of the same position index
986// will only be recorded once in the returned TArrayI array.
987//
988// Notes :
989// -------
990// As usual the convention is that slot and position numbering starts at 1.
991//
992// This memberfunction always resets the TArrayI array at the start.
993//
994// This memberfunction can only be used to obtain the position indices
995// of the object as stored via the SetLink() or AddLink() memberfunction.
996// This means that in case the user has entered a TObjArray as object
997// (to increase the dimension of the resulting structure), the position
998// indices of that TObjArray are obtained and NOT the indices of the
999// actual objects contained in that TObjArray structure.
1000//
1001 Int_t nrefs=0;
1002 ks.Reset();
1003 // Note : In the internal storage matrix slots=columns positions=rows
1004 if (fLinks) nrefs=fLinks->GetIndices(obj,ks,j);
1005 return nrefs;
1006}
1007///////////////////////////////////////////////////////////////////////////
1008Int_t AliSignal::GetIndices(TObject* obj,TArrayI& js,Int_t k)
1009{
1010// Provide the slot indices of all the storage locations of the
1011// specified object for the k-th position in this AliSignal.
1012// The slot indices are returned in the TArrayI array.
1013// The integer return argument represents the number of storage locations which
1014// were encountered for the specified object in the k-th position.
1015//
1016// If obj=0 no object selection is performed and all slot indices
1017// of the stored references for all objects in the k-th position are returned.
1018//
1019// If k=0 all positions will be scanned and all slot indices matching the
1020// object selection are returned.
1021// Note that in this case multiple appearances of the same slot index
1022// will only be recorded once in the returned TArrayI array.
1023//
1024// Notes :
1025// -------
1026// As usual the convention is that slot and position numbering starts at 1.
1027//
1028// This memberfunction always resets the TArrayI array at the start.
1029//
1030// This memberfunction can only be used to obtain the slot indices
1031// of the object as stored via the SetLink() or AddLink() memberfunction.
1032// This means that in case the user has entered a TObjArray as object
1033// (to increase the dimension of the resulting structure), the slot
1034// indices of that TObjArray are obtained and NOT the indices of the
1035// actual objects contained in that TObjArray structure.
1036//
1037 Int_t nrefs=0;
1038 js.Reset();
1039 // Note : In the internal storage matrix slots=columns positions=rows
1040 if (fLinks) nrefs=fLinks->GetIndices(obj,k,js);
1041 return nrefs;
1042}
1043///////////////////////////////////////////////////////////////////////////
1044void AliSignal::SetSwapMode(Int_t swap)
1045{
1046// Set swapmode flag for the internal link storage.
1047// In case for the stored links the maximum slot number differs considerably
1048// from the maximum position number, it might be more efficient
1049// (w.r.t. memory usage and/or output file size) to internally store the
1050// link reference matrix with the rows and colums swapped.
1051// This swapping is only related with the internal storage and as such
1052// is completely hidden for the user.
1053// At invokation of this memberfunction the default argument is swap=1.
1054//
1055// Note : The swap mode can only be set as long as no links are
1056// stored in the AliSignal (i.e. a new instance of AliSignal
1057// or after invokation of the Reset() or ResetLinks() function).
1058
1059 if (!fLinks) fLinks=new AliObjMatrix();
1060 fLinks->SetSwapMode(swap);
1061}
1062///////////////////////////////////////////////////////////////////////////
1063Int_t AliSignal::GetSwapMode()
1064{
1065// Provide swapmode flag of the link storage.
1066 Int_t swap=0;
1067 if (fLinks) swap=fLinks->GetSwapMode();
1068 return swap;
5f25234b 1069}
1070///////////////////////////////////////////////////////////////////////////
8e8eae84 1071TObject* AliSignal::Clone(const char* name)
c72198f1 1072{
1c01b4f8 1073// Make a deep copy of the current object and provide the pointer to the copy.
c72198f1 1074// This memberfunction enables automatic creation of new objects of the
1c01b4f8 1075// correct type depending on the object type, a feature which may be very useful
c72198f1 1076// for containers when adding objects in case the container owns the objects.
1077// This feature allows e.g. AliTrack to store either AliSignal objects or
1078// objects derived from AliSignal via the AddSignal memberfunction, provided
1c01b4f8 1079// these derived classes also have a proper Clone memberfunction.
c72198f1 1080
1c01b4f8 1081 AliSignal* sig=new AliSignal(*this);
1082 if (name)
1083 {
1084 if (strlen(name)) sig->SetName(name);
1085 }
c72198f1 1086 return sig;
1087}
1088///////////////////////////////////////////////////////////////////////////