]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RALICE/AliSignal.cxx
Replacing fabs by TMath::Abs
[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"
c72198f1 89#include "Riostream.h"
d88f97cc 90
91ClassImp(AliSignal) // Class implementation to enable ROOT I/O
92
1c01b4f8 93AliSignal::AliSignal() : TNamed(),AliPosition(),AliAttrib()
d88f97cc 94{
959fbac5 95// Creation of an AliSignal object and initialisation of parameters.
1fbffa23 96// Several signal values (with errors) can be stored in different slots.
fdadc78a 97// If needed, the storage for values (and errors) will be expanded automatically
98// when entering values and/or errors.
1fbffa23 99 fSignals=0;
100 fDsignals=0;
101 fWaveforms=0;
1c01b4f8 102 SetName("Unspecified");
d88f97cc 103}
104///////////////////////////////////////////////////////////////////////////
105AliSignal::~AliSignal()
106{
107// Destructor to delete dynamically allocated memory
1fbffa23 108 if (fSignals)
959fbac5 109 {
1fbffa23 110 delete fSignals;
111 fSignals=0;
959fbac5 112 }
1fbffa23 113 if (fDsignals)
959fbac5 114 {
1fbffa23 115 delete fDsignals;
116 fDsignals=0;
959fbac5 117 }
1fbffa23 118 if (fWaveforms)
c72198f1 119 {
1fbffa23 120 delete fWaveforms;
121 fWaveforms=0;
c72198f1 122 }
d88f97cc 123}
124///////////////////////////////////////////////////////////////////////////
1c01b4f8 125AliSignal::AliSignal(AliSignal& s) : TNamed(s),AliPosition(s),AliAttrib(s)
8e8e6c7f 126{
127// Copy constructor
1fbffa23 128 fSignals=0;
129 fDsignals=0;
1fbffa23 130 fWaveforms=0;
8e8e6c7f 131
1fbffa23 132 Int_t n=s.GetNvalues();
133 Double_t val;
134 for (Int_t i=1; i<=n; i++)
8e8e6c7f 135 {
1fbffa23 136 val=s.GetSignal(i);
137 SetSignal(val,i);
fdadc78a 138 }
139
1fbffa23 140 n=s.GetNerrors();
141 for (Int_t j=1; j<=n; j++)
fdadc78a 142 {
1fbffa23 143 val=s.GetSignalError(j);
144 SetSignalError(val,j);
c72198f1 145 }
146
1fbffa23 147 n=s.GetNwaveforms();
148 for (Int_t k=1; k<=n; k++)
149 {
150 TH1F* hist=s.GetWaveform(k);
151 if (hist) SetWaveform(hist,k);
152 }
8e8e6c7f 153}
154///////////////////////////////////////////////////////////////////////////
fdadc78a 155void AliSignal::Reset(Int_t mode)
d88f97cc 156{
959fbac5 157// Reset all signal and position values and errors to 0.
fdadc78a 158//
159// mode = 0 Reset position and all signal values and their errors to 0.
1fbffa23 160// The waveform histograms are reset, but the calibration
161// constants (i.e. gains and offsets) are kept.
fdadc78a 162// 1 Reset position and delete the signal and error storage arrays.
1fbffa23 163// Also the waveform histograms, gains and offset arrays are deleted.
fdadc78a 164//
165// The default when invoking Reset() corresponds to mode=0.
166//
167// The usage of mode=0 allows to re-use the allocated memory for new
168// signal (and error) values. This behaviour is preferable (i.e. faster)
1fbffa23 169// in case the various signals always contain the same number of values
170// and have the same calibration constants.
fdadc78a 171// The usage of mode=1 is slower, but allows a more efficient memory
172// occupation (and smaller output file size) in case the different
173// signals have a variable number of values.
174//
1fbffa23 175// For more specific actions see ResetPosition(), ResetSignals(),
176// DeleteSignals(), ResetGain(), ResetOffset() and DeleteCalibrations().
c72198f1 177//
959fbac5 178
fdadc78a 179 if (mode<0 || mode>1)
959fbac5 180 {
fdadc78a 181 cout << " *AliSignal::Reset* Invalid argument mode = " << mode << endl;
182 cout << " Default mode=0 will be used." << endl;
183 mode=0;
184 }
185
186 ResetPosition();
187 if (!mode)
188 {
189 ResetSignals();
190 }
191 else
192 {
193 DeleteSignals();
1fbffa23 194 DeleteCalibrations();
959fbac5 195 }
196}
197///////////////////////////////////////////////////////////////////////////
fdadc78a 198void AliSignal::ResetSignals(Int_t mode)
959fbac5 199{
fdadc78a 200// Reset various signal data according to user selection.
201//
202// mode = 0 Reset all signal values and their errors to 0.
203// 1 Reset only signal values
204// 2 Reset only signal errors
205//
206// The default when invoking ResetSignals() corresponds to mode=0.
c72198f1 207//
1fbffa23 208// Irrespective of the mode, the waveform histograms are reset.
959fbac5 209
fdadc78a 210 if (mode<0 || mode>2)
211 {
212 cout << " *AliSignal::ResetSignals* Invalid argument mode = " << mode << endl;
213 cout << " Default mode=0 will be used." << endl;
214 mode=0;
215 }
216
1fbffa23 217 if (fSignals && (mode==0 || mode==1))
959fbac5 218 {
1fbffa23 219 for (Int_t i=0; i<fSignals->GetSize(); i++)
dafe31a2 220 {
1fbffa23 221 fSignals->AddAt(0,i);
fdadc78a 222 }
223 }
224
1fbffa23 225 if (fDsignals && (mode==0 || mode==2))
fdadc78a 226 {
1fbffa23 227 for (Int_t j=0; j<fDsignals->GetSize(); j++)
fdadc78a 228 {
1fbffa23 229 fDsignals->AddAt(0,j);
dafe31a2 230 }
959fbac5 231 }
c72198f1 232
1fbffa23 233 ResetWaveform(0);
d88f97cc 234}
235///////////////////////////////////////////////////////////////////////////
fdadc78a 236void AliSignal::DeleteSignals(Int_t mode)
237{
238// Delete storage arrays of various signal data according to user selection.
239//
240// mode = 0 Delete arrays of both signal values and their errors.
241// 1 Delete only signal values array
242// 2 Delete only signal errors array
243//
244// The default when invoking DeleteSignals() corresponds to mode=0.
c72198f1 245//
1fbffa23 246// Irrespective of the mode, the waveform histograms are deleted.
fdadc78a 247
248 if (mode<0 || mode>2)
249 {
250 cout << " *AliSignal::DeleteSignals* Invalid argument mode = " << mode << endl;
251 cout << " Default mode=0 will be used." << endl;
252 mode=0;
253 }
254
1fbffa23 255 if (fSignals && (mode==0 || mode==1))
fdadc78a 256 {
1fbffa23 257 delete fSignals;
258 fSignals=0;
fdadc78a 259 }
260
1fbffa23 261 if (fDsignals && (mode==0 || mode==2))
fdadc78a 262 {
1fbffa23 263 delete fDsignals;
264 fDsignals=0;
fdadc78a 265 }
c72198f1 266
1fbffa23 267 DeleteWaveform(0);
fdadc78a 268}
269///////////////////////////////////////////////////////////////////////////
959fbac5 270void AliSignal::SetSignal(Double_t sig,Int_t j)
d88f97cc 271{
1fbffa23 272// Store value in the j-th (default j=1) signal slot.
273// Note : The first signal slot is at j=1.
dafe31a2 274// In case the value of the index j exceeds the maximum number of reserved
fdadc78a 275// slots for signal values, the number of reserved slots for the
276// signal values is increased automatically.
959fbac5 277
1fbffa23 278 if (!fSignals)
959fbac5 279 {
1fbffa23 280 fSignals=new TArrayF(j);
fdadc78a 281 ResetSignals(1);
959fbac5 282 }
dafe31a2 283
1fbffa23 284 Int_t size=fSignals->GetSize();
dafe31a2 285
286 if (j>size)
959fbac5 287 {
1fbffa23 288 fSignals->Set(j);
959fbac5 289 }
dafe31a2 290
1fbffa23 291 fSignals->AddAt(float(sig),j-1);
d88f97cc 292}
293///////////////////////////////////////////////////////////////////////////
959fbac5 294void AliSignal::AddSignal(Double_t sig,Int_t j)
295{
1fbffa23 296// Add value to the j-th (default j=1) signal slot.
297// Note : The first signal slot is at j=1.
dafe31a2 298// In case the value of the index j exceeds the maximum number of reserved
fdadc78a 299// slots for signal values, the number of reserved slots for the
300// signal values is increased automatically.
959fbac5 301
1fbffa23 302 if (!fSignals)
959fbac5 303 {
1fbffa23 304 fSignals=new TArrayF(j);
fdadc78a 305 ResetSignals(1);
959fbac5 306 }
dafe31a2 307
1fbffa23 308 Int_t size=fSignals->GetSize();
dafe31a2 309
310 if (j>size)
959fbac5 311 {
1fbffa23 312 fSignals->Set(j);
959fbac5 313 }
dafe31a2 314
1fbffa23 315 Float_t sum=(fSignals->At(j-1))+sig;
316 fSignals->AddAt(sum,j-1);
959fbac5 317}
318///////////////////////////////////////////////////////////////////////////
1fbffa23 319Float_t AliSignal::GetSignal(Int_t j,Int_t mode)
959fbac5 320{
1fbffa23 321// Provide value of the j-th (default j=1) signal slot.
322// Note : The first signal slot is at j=1.
fdadc78a 323// In case no signal is present or the argument j is invalid, 0 is returned.
1fbffa23 324// The parameter "mode" allows for automatic gain etc... correction of the signal.
325//
326// mode = 0 : Just the j-th signal is returned.
327// 1 : The j-th signal is corrected for the gain, offset, dead flag etc...
328// In case the gain value was not set, gain=1 will be assumed.
329// In case the gain value was 0, a signal value of 0 is returned.
330// In case the offset value was not set, offset=0 will be assumed.
331// In case the j-th slot was marked dead, 0 is returned.
332//
333// The corrected signal (sigc) is determined as follows :
334//
335// sigc=(signal/gain)-offset
336//
337// The default is mode=0.
338
fdadc78a 339 Float_t sig=0;
1fbffa23 340 Float_t gain=1;
341 Float_t offset=0;
342 if (fSignals)
959fbac5 343 {
1fbffa23 344 if (j>0 && j<=(fSignals->GetSize()))
fdadc78a 345 {
1fbffa23 346 sig=fSignals->At(j-1);
347
348 if (mode==0) return sig;
349
350 // Correct the signal for the gain, offset, dead flag etc...
351 if (GetDeadValue(j)) return 0;
352
353 if (GetGainFlag(j)) gain=GetGain(j);
354 if (GetOffsetFlag(j)) offset=GetOffset(j);
355
356 if (fabs(gain)>0.)
357 {
358 sig=(sig/gain)-offset;
359 }
360 else
361 {
362 sig=0;
363 }
fdadc78a 364 }
365 else
366 {
367 cout << " *AliSignal::GetSignal* Index j = " << j << " invalid." << endl;
368 }
959fbac5 369 }
fdadc78a 370 return sig;
959fbac5 371}
372///////////////////////////////////////////////////////////////////////////
373void AliSignal::SetSignalError(Double_t dsig,Int_t j)
374{
1fbffa23 375// Store error for the j-th (default j=1) signal slot.
376// Note : The first signal slot is at j=1.
dafe31a2 377// In case the value of the index j exceeds the maximum number of reserved
fdadc78a 378// slots for signal error values, the number of reserved slots for the
379// signal errors is increased automatically.
959fbac5 380
1fbffa23 381 if (!fDsignals)
959fbac5 382 {
1fbffa23 383 fDsignals=new TArrayF(j);
fdadc78a 384 ResetSignals(2);
959fbac5 385 }
dafe31a2 386
1fbffa23 387 Int_t size=fDsignals->GetSize();
dafe31a2 388
389 if (j>size)
959fbac5 390 {
1fbffa23 391 fDsignals->Set(j);
959fbac5 392 }
dafe31a2 393
1fbffa23 394 fDsignals->AddAt(float(dsig),j-1);
959fbac5 395}
396///////////////////////////////////////////////////////////////////////////
397Float_t AliSignal::GetSignalError(Int_t j)
398{
1fbffa23 399// Provide error of the j-th (default j=1) signal slot.
400// Note : The first signal slot is at j=1.
fdadc78a 401// In case no signal is present or the argument j is invalid, 0 is returned.
402 Float_t err=0;
1fbffa23 403 if (fDsignals)
959fbac5 404 {
1fbffa23 405 if (j>0 && j<=(fDsignals->GetSize()))
fdadc78a 406 {
1fbffa23 407 err=fDsignals->At(j-1);
fdadc78a 408 }
409 else
410 {
411 cout << " *AliSignal::GetSignalError* Index j = " << j << " invalid." << endl;
412 }
959fbac5 413 }
fdadc78a 414 return err;
959fbac5 415}
416///////////////////////////////////////////////////////////////////////////
1c01b4f8 417void AliSignal::Data(TString f)
418{
419// Provide all signal information within the coordinate frame f.
420
421 cout << " *" << ClassName() << "::Data* Signal of kind : " << GetName() << endl;
422 cout << " Position";
423 Ali3Vector::Data(f);
424
425 List(-1);
426}
427///////////////////////////////////////////////////////////////////////////
428void AliSignal::List(Int_t j)
959fbac5 429{
1c01b4f8 430// Provide signal information for the j-th slot.
1fbffa23 431// The first slot is at j=1.
432// In case j=0 (default) the data of all slots will be listed.
1c01b4f8 433// In case j=-1 the data of all slots will be listed, but the header
434// information will be suppressed.
1fbffa23 435
1c01b4f8 436 if (j<-1)
1fbffa23 437 {
1c01b4f8 438 cout << " *AliSignal::List* Invalid argument j = " << j << endl;
1fbffa23 439 return;
440 }
441
1c01b4f8 442 if (j != -1) cout << " *" << ClassName() << "::List* Signal of kind : " << GetName() << endl;
fdadc78a 443
444 Int_t nvalues=GetNvalues();
445 Int_t nerrors=GetNerrors();
1fbffa23 446 Int_t n=nvalues;
447 if (nerrors>n) n=nerrors;
fdadc78a 448
1c01b4f8 449 if (j<=0)
959fbac5 450 {
1fbffa23 451 for (Int_t i=1; i<=n; i++)
959fbac5 452 {
1fbffa23 453 cout << " Signal";
454 if (i<=nvalues) cout << " value : " << GetSignal(i);
455 if (i<=nerrors) cout << " error : " << GetSignalError(i);
1c01b4f8 456 AliAttrib::List(i);
1fbffa23 457 cout << endl;
458 }
459 }
460 else
461 {
462 if (j<=n)
463 {
464 cout << " Signal";
465 if (j<=nvalues) cout << " value : " << GetSignal(j);
466 if (j<=nerrors) cout << " error : " << GetSignalError(j);
1c01b4f8 467 AliAttrib::List(j);
fdadc78a 468 cout << endl;
959fbac5 469 }
470 }
471}
472///////////////////////////////////////////////////////////////////////////
8e8e6c7f 473Int_t AliSignal::GetNvalues()
474{
475// Provide the number of values for this signal.
dafe31a2 476 Int_t n=0;
1fbffa23 477 if (fSignals) n=fSignals->GetSize();
fdadc78a 478 return n;
479}
480///////////////////////////////////////////////////////////////////////////
481Int_t AliSignal::GetNerrors()
482{
483// Provide the number specified errors on the values for this signal.
484 Int_t n=0;
1fbffa23 485 if (fDsignals) n=fDsignals->GetSize();
dafe31a2 486 return n;
8e8e6c7f 487}
488///////////////////////////////////////////////////////////////////////////
1fbffa23 489Int_t AliSignal::GetNwaveforms()
c72198f1 490{
1fbffa23 491// Provide the number specified waveforms for this signal.
492 Int_t n=0;
493 if (fWaveforms) n=fWaveforms->GetSize();
494 return n;
c72198f1 495}
496///////////////////////////////////////////////////////////////////////////
1fbffa23 497TH1F* AliSignal::GetWaveform(Int_t j)
c72198f1 498{
1fbffa23 499// Provide pointer to the j-th waveform histogram.
500 TH1F* waveform=0;
501 if (j <= GetNwaveforms()) waveform=(TH1F*)fWaveforms->At(j-1);
502 return waveform;
503}
504///////////////////////////////////////////////////////////////////////////
505void AliSignal::SetWaveform(TH1F* waveform,Int_t j)
506{
507// Set the 1D waveform histogram corresponding to the j-th signal value.
508//
509// Notes :
510// The waveform of the first signal value is at j=1.
511// j=1 is the default value.
512//
513// In case the value of the index j exceeds the maximum number of reserved
514// slots for the waveforms, the number of reserved slots for the waveforms
515// is increased automatically.
c72198f1 516//
1fbffa23 517// In case the histo pointer argument has the same value as the current waveform
c72198f1 518// histogram pointer value, no action is taken since the user has already
519// modified the actual histogram.
520//
1fbffa23 521// In case the histo pointer argument is zero, the current waveform histogram
c72198f1 522// is deleted and the pointer set to zero.
523//
524// In all other cases the current waveform histogram is deleted and a new
525// copy of the input histogram is created which becomes the current waveform
526// histogram.
527
1fbffa23 528 if (!fWaveforms)
529 {
530 fWaveforms=new TObjArray(j);
531 fWaveforms->SetOwner();
532 }
533
534 if (j > fWaveforms->GetSize()) fWaveforms->Expand(j);
535
536 TH1F* hcur=(TH1F*)fWaveforms->At(j-1);
537 if (waveform != hcur)
c72198f1 538 {
1fbffa23 539 if (hcur)
c72198f1 540 {
1fbffa23 541 fWaveforms->Remove(hcur);
542 delete hcur;
543 hcur=0;
544 }
545 if (waveform)
546 {
547 hcur=new TH1F(*waveform);
548 fWaveforms->AddAt(hcur,j-1);
c72198f1 549 }
c72198f1 550 }
551}
552///////////////////////////////////////////////////////////////////////////
1fbffa23 553void AliSignal::ResetWaveform(Int_t j)
554{
555// Reset the waveform of the j-th (default j=1) signal value.
556// This memberfunction invokes TH1F::Reset() for the corresponding waveform(s).
557// To actually delete the histograms from memory, use DeleteWaveform().
558// Notes : The first signal value is at j=1.
559// j=0 ==> All waveforms will be reset.
560
561 if (!fWaveforms) return;
562
563 Int_t size=fWaveforms->GetSize();
564
565 if ((j>=0) && (j<=size))
566 {
567 if (j)
568 {
569 TH1F* hwave=(TH1F*)fWaveforms->At(j-1);
570 if (hwave) hwave->Reset();
571 }
572 else
573 {
574 for (Int_t i=0; i<size; i++)
575 {
576 TH1F* hwave=(TH1F*)fWaveforms->At(i);
577 if (hwave) hwave->Reset();
578 }
579 }
580 }
581 else
582 {
583 cout << " *AliSignal::ResetWaveform* Index j = " << j << " invalid." << endl;
584 return;
585 }
586}
587///////////////////////////////////////////////////////////////////////////
588void AliSignal::DeleteWaveform(Int_t j)
589{
590// Delete the waveform of the j-th (default j=1) signal value.
591// Notes : The first signal value is at j=1.
592// j=0 ==> All waveforms will be deleted.
593
594 if (!fWaveforms) return;
595
596 Int_t size=fWaveforms->GetSize();
597
598 if ((j>=0) && (j<=size))
599 {
600 if (j)
601 {
602 TH1F* hwave=(TH1F*)fWaveforms->At(j-1);
603 if (hwave)
604 {
605 fWaveforms->Remove(hwave);
606 delete hwave;
607 }
608 }
609 else
610 {
611 delete fWaveforms;
612 fWaveforms=0;
613 }
614 }
615 else
616 {
617 cout << " *AliSignal::DeleteWaveform* Index j = " << j << " invalid." << endl;
618 return;
619 }
620}
621///////////////////////////////////////////////////////////////////////////
1c01b4f8 622TObject* AliSignal::Clone(char* name)
c72198f1 623{
1c01b4f8 624// Make a deep copy of the current object and provide the pointer to the copy.
c72198f1 625// This memberfunction enables automatic creation of new objects of the
1c01b4f8 626// correct type depending on the object type, a feature which may be very useful
c72198f1 627// for containers when adding objects in case the container owns the objects.
628// This feature allows e.g. AliTrack to store either AliSignal objects or
629// objects derived from AliSignal via the AddSignal memberfunction, provided
1c01b4f8 630// these derived classes also have a proper Clone memberfunction.
c72198f1 631
1c01b4f8 632 AliSignal* sig=new AliSignal(*this);
633 if (name)
634 {
635 if (strlen(name)) sig->SetName(name);
636 }
c72198f1 637 return sig;
638}
639///////////////////////////////////////////////////////////////////////////