]> git.uio.no Git - u/mrichter/AliRoot.git/blob - RALICE/AliAttrib.cxx
Set the ToT bin width to the one actually used...
[u/mrichter/AliRoot.git] / RALICE / AliAttrib.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 // $Id$
17
18 ///////////////////////////////////////////////////////////////////////////
19 // Class AliAttrib
20 // Generic handling of detector signal (calibration) attributes.
21 // Normally this class is only used as a base class to provide the various
22 // attributes to the derived class. An example of this is AliSignal.
23 // However, one can of course also use this class on its own as shown
24 // in the simple example hereafter.
25 //
26 // Example :
27 // ---------
28 // AliAttrib a;
29 // a.SetSlotName("PMT amplitude in Volt");
30 // a.SetGain(250.7);
31 // a.SetSlotName("Time of flight in ns",2);
32 // a.SetOffset(-22.5,2);
33 // a.SetSlotName("PMT amplitude in ADC",3);
34 // a.SetGain(1340,3);
35 // a.SetSlotName("TDC",4);
36 // a.SetOffset(10.75,"TDC");
37 // a.SetEdgeOn(3);
38 // a.SetDead(1);
39 // a.List();
40 //
41 //--- Author: Nick van Eijndhoven 18-sep-2003 Utrecht University
42 //- Modified: NvE $Date$ Utrecht University
43 ///////////////////////////////////////////////////////////////////////////
44
45 #include "AliAttrib.h"
46 #include "Riostream.h"
47  
48 ClassImp(AliAttrib) // Class implementation to enable ROOT I/O
49  
50 AliAttrib::AliAttrib()
51 {
52 // Creation of an AliAttrib object and initialisation of parameters.
53 // Several values of the same type (e.g. gain) can be stored in different slots.
54 // If needed, the storage for values will be expanded automatically
55 // when entering values.
56  fGains=0;
57  fOffsets=0;
58  fCalflags=0;
59  fNames=0;
60  fCalfuncs=0;
61  fDecalfuncs=0;
62 }
63 ///////////////////////////////////////////////////////////////////////////
64 AliAttrib::~AliAttrib()
65 {
66 // Destructor to delete dynamically allocated memory
67  if (fGains)
68  {
69   delete fGains;
70   fGains=0;
71  }
72  if (fOffsets)
73  {
74   delete fOffsets;
75   fOffsets=0;
76  }
77  if (fCalflags)
78  {
79   delete fCalflags;
80   fCalflags=0;
81  }
82  if (fNames)
83  {
84   delete fNames;
85   fNames=0;
86  }
87  if (fCalfuncs)
88  {
89   delete fCalfuncs;
90   fCalfuncs=0;
91  }
92  if (fDecalfuncs)
93  {
94   delete fDecalfuncs;
95   fDecalfuncs=0;
96  }
97 }
98 ///////////////////////////////////////////////////////////////////////////
99 AliAttrib::AliAttrib(const AliAttrib& a)
100 {
101 // Copy constructor
102  fGains=0;
103  fOffsets=0;
104  fCalflags=0;
105  fNames=0;
106  fCalfuncs=0;
107  fDecalfuncs=0;
108
109  Int_t n=0;
110  Double_t val=0;
111
112  n=a.GetNgains();
113  for (Int_t ig=1; ig<=n; ig++)
114  {
115   val=a.GetGain(ig);
116   if (a.GetGainFlag(ig)) SetGain(val,ig);
117  }
118
119  n=a.GetNoffsets();
120  for (Int_t io=1; io<=n; io++)
121  {
122   val=a.GetOffset(io);
123   if (a.GetOffsetFlag(io)) SetOffset(val,io);
124  }
125
126  n=a.GetNcalflags();
127  for (Int_t ic=1; ic<=n; ic++)
128  {
129   SetEdgeValue(a.GetEdgeValue(ic),ic);
130   if (a.GetDeadValue(ic)) SetDead(ic);
131  }
132
133  n=a.GetNnames();
134  TString s;
135  for (Int_t in=1; in<=n; in++)
136  {
137   s=a.GetSlotName(in);
138   if (s!="") SetSlotName(s,in);
139  }
140
141  n=a.GetNcalfuncs();
142  for (Int_t icalf=1; icalf<=n; icalf++)
143  {
144   TF1* f=a.GetCalFunction(icalf);
145   if (f) SetCalFunction(f,icalf);
146  }
147
148  n=a.GetNdecalfuncs();
149  for (Int_t idecalf=1; idecalf<=n; idecalf++)
150  {
151   TF1* f=a.GetDecalFunction(idecalf);
152   if (f) SetDecalFunction(f,idecalf);
153  }
154 }
155 ///////////////////////////////////////////////////////////////////////////
156 Int_t AliAttrib::GetNgains() const
157 {
158 // Provide the number of specified gains for this attribute.
159
160  if (!fGains) return 0;
161
162  Int_t n=0;
163  for (Int_t i=1; i<=fGains->GetSize(); i++)
164  {
165   if (GetGainFlag(i)) n=i;
166  }
167
168  return n;
169 }
170 ///////////////////////////////////////////////////////////////////////////
171 Int_t AliAttrib::GetNoffsets() const
172 {
173 // Provide the number of specified offsets for this attribute.
174
175  if (!fOffsets) return 0;
176
177  Int_t n=0;
178  for (Int_t i=1; i<=fOffsets->GetSize(); i++)
179  {
180   if (GetOffsetFlag(i)) n=i;
181  }
182
183  return n;
184 }
185 ///////////////////////////////////////////////////////////////////////////
186 Int_t AliAttrib::GetNcalflags() const
187 {
188 // Provide the number of specified calib. flags for this attribute.
189
190  if (!fCalflags) return 0;
191
192  Int_t n=0;
193  for (Int_t i=1; i<=fCalflags->GetSize(); i++)
194  {
195   if (fCalflags->At(i-1)) n=i;
196  }
197
198  return n;
199 }
200 ///////////////////////////////////////////////////////////////////////////
201 Int_t AliAttrib::GetNnames() const
202 {
203 // Provide the maximum number of specified names for this attribute.
204
205  if (!fNames) return 0;
206
207  Int_t n=0;
208  for (Int_t i=1; i<=fNames->GetSize(); i++)
209  {
210   if (fNames->At(i-1)) n=i;
211  }
212
213  return n;
214 }
215 ///////////////////////////////////////////////////////////////////////////
216 void AliAttrib::SetGain(Double_t gain,Int_t j)
217 {
218 // Store gain value of the j-th (default j=1) attribute slot.
219 // Note : The first attribute slot is at j=1.
220 // In case the value of the index j exceeds the maximum number of reserved
221 // slots for gain values, the number of reserved slots for the gain
222 // values is increased automatically.
223
224  if (j<1) 
225  {
226   cout << " *AliAttrib::SetGain* Invalid argument j = " << j << endl;
227   return;
228  }
229
230  if (!fGains)
231  {
232   fGains=new TArrayF(j);
233  }
234
235  Int_t size=fGains->GetSize();
236
237  if (j>size)
238  {
239   fGains->Set(j);
240  }
241
242  fGains->AddAt(float(gain),j-1);
243
244  Int_t oflag=GetOffsetFlag(j);
245
246  SetCalFlags(1,oflag,j);
247 }
248 ///////////////////////////////////////////////////////////////////////////
249 void AliAttrib::SetGain(Double_t gain,TString name)
250 {
251 // Store gain value of the name-specified attribute slot.
252 //
253 // This procedure involves a slot-index search based on the specified name
254 // at each invokation. This may become slow in case many slots have been
255 // defined and/or when this procedure is invoked many times.
256 // In such cases it is preferable to use indexed addressing in the user code
257 // either directly or via a few invokations of GetSlotIndex().
258
259  Int_t j=GetSlotIndex(name);
260  if (j>0) SetGain(gain,j);
261 }
262 ///////////////////////////////////////////////////////////////////////////
263 void AliAttrib::SetOffset(Double_t off,Int_t j)
264 {
265 // Store offset value of the j-th (default j=1) attribute slot.
266 // Note : The first attribute slot is at j=1.
267 // In case the value of the index j exceeds the maximum number of reserved
268 // slots for offset values, the number of reserved slots for the offset
269 // values is increased automatically.
270
271  if (j<1) 
272  {
273   cout << " *AliAttrib::GetOffset* Invalid argument j = " << j << endl;
274   return;
275  }
276
277  if (!fOffsets)
278  {
279   fOffsets=new TArrayF(j);
280  }
281
282  Int_t size=fOffsets->GetSize();
283
284  if (j>size)
285  {
286   fOffsets->Set(j);
287  }
288
289  fOffsets->AddAt(float(off),j-1);
290
291  Int_t gflag=GetGainFlag(j);
292
293  SetCalFlags(gflag,1,j);
294 }
295 ///////////////////////////////////////////////////////////////////////////
296 void AliAttrib::SetOffset(Double_t off,TString name)
297 {
298 // Store offset value of the name-specified attribute slot.
299 //
300 // This procedure involves a slot-index search based on the specified name
301 // at each invokation. This may become slow in case many slots have been
302 // defined and/or when this procedure is invoked many times.
303 // In such cases it is preferable to use indexed addressing in the user code
304 // either directly or via a few invokations of GetSlotIndex().
305
306  Int_t j=GetSlotIndex(name);
307  if (j>0) SetOffset(off,j);
308 }
309 ///////////////////////////////////////////////////////////////////////////
310 void AliAttrib::SetCalFlags(Int_t gainflag,Int_t offsetflag,Int_t j)
311 {
312 // Store calibration flags of the j-th (default j=1) attribute slot.
313 // Note : The first attribute slot is at j=1.
314 // In case the value of the index j exceeds the maximum number of reserved
315 // slots for the calib. flags, the number of reserved slots for the calib.
316 // flags is increased automatically.
317 // The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
318
319  if (j<1) 
320  {
321   cout << " *AliAttrib::GetCalFlags* Invalid argument j = " << j << endl;
322   return;
323  }
324
325  if (!fCalflags)
326  {
327   fCalflags=new TArrayI(j);
328  }
329
330  Int_t size=fCalflags->GetSize();
331
332  if (j>size)
333  {
334   fCalflags->Set(j);
335  }
336
337  Int_t edge=GetEdgeValue(j);
338  Int_t dead=GetDeadValue(j);
339
340  Int_t word=1000*edge+100*dead+10*gainflag+offsetflag;
341  
342  fCalflags->AddAt(word,j-1);
343 }
344 ///////////////////////////////////////////////////////////////////////////
345 Int_t AliAttrib::GetGainFlag(Int_t j) const
346 {
347 // Provide gain flag of the j-th (default j=1) attribute slot.
348 //
349 // flag = 1 : Gain was set
350 //        0 : Gain was not set
351 //
352 // Note : The first attribute slot is at j=1.
353 // In case j is invalid, 0 is returned.
354
355  if (j<1) 
356  {
357   cout << " *AliAttrib::GetGainFlag* Invalid argument j = " << j << endl;
358   return 0;
359  }
360  Int_t gflag=0;
361  if (fCalflags)
362  {
363   if (j>0 && j<=(fCalflags->GetSize()))
364   {
365    Int_t word=fCalflags->At(j-1);
366    word=word%100;
367    gflag=word/10;
368   }
369  }
370  return gflag;
371 }
372 ///////////////////////////////////////////////////////////////////////////
373 Int_t AliAttrib::GetGainFlag(TString name) const
374 {
375 // Provide gain flag of the name-specified attribute slot.
376 //
377 // flag = 1 : Gain was set
378 //        0 : Gain was not set
379 //
380 //
381 // This procedure involves a slot-index search based on the specified name
382 // at each invokation. This may become slow in case many slots have been
383 // defined and/or when this procedure is invoked many times.
384 // In such cases it is preferable to use indexed addressing in the user code
385 // either directly or via a few invokations of GetSlotIndex().
386
387  Int_t j=GetSlotIndex(name);
388  Int_t flag=0;
389  if (j>0) flag=GetGainFlag(j);
390  return flag;
391 }
392 ///////////////////////////////////////////////////////////////////////////
393 Int_t AliAttrib::GetOffsetFlag(Int_t j) const
394 {
395 // Provide offset flag of the j-th (default j=1) attribute slot.
396 //
397 // flag = 1 : Offset was set
398 //        0 : Offset was not set
399 //
400 // Note : The first attribute slot is at j=1.
401 // In case j is invalid, 0 is returned.
402
403  if (j<1) 
404  {
405   cout << " *AliAttrib::GetOffsetFlag* Invalid argument j = " << j << endl;
406   return 0;
407  }
408
409  Int_t oflag=0;
410  if (fCalflags)
411  {
412   if (j>0 && j<=(fCalflags->GetSize()))
413   {
414    Int_t word=fCalflags->At(j-1);
415    oflag=word%10;
416   }
417  }
418  return oflag;
419 }
420 ///////////////////////////////////////////////////////////////////////////
421 Int_t AliAttrib::GetOffsetFlag(TString name) const
422 {
423 // Provide ofset flag of the name-specified attribute slot.
424 //
425 // flag = 1 : Offset was set
426 //        0 : Offset was not set
427 //
428 //
429 // This procedure involves a slot-index search based on the specified name
430 // at each invokation. This may become slow in case many slots have been
431 // defined and/or when this procedure is invoked many times.
432 // In such cases it is preferable to use indexed addressing in the user code
433 // either directly or via a few invokations of GetSlotIndex().
434
435  Int_t j=GetSlotIndex(name);
436  Int_t flag=0;
437  if (j>0) flag=GetOffsetFlag(j);
438  return flag;
439 }
440 ///////////////////////////////////////////////////////////////////////////
441 Int_t AliAttrib::GetCalWord(Int_t j) const
442 {
443 // Provide calib. word of the j-th (default j=1) attribute slot.
444 // The word value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
445 //
446 // Note : The first attribute slot is at j=1.
447 // In case j is invalid, 0 is returned.
448
449  if (j<1) 
450  {
451   cout << " *AliAttrib::GetCalWord* Invalid argument j = " << j << endl;
452   return 0;
453  }
454
455  Int_t word=0;
456  if (fCalflags)
457  {
458   if (j>0 && j<=(fCalflags->GetSize())) word=fCalflags->At(j-1);
459  }
460  return word;
461 }
462 ///////////////////////////////////////////////////////////////////////////
463 Int_t AliAttrib::GetCalWord(TString name) const
464 {
465 // Provide calib. word of the name-specified attribute slot.
466 // The word value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
467 //
468 // This procedure involves a slot-index search based on the specified name
469 // at each invokation. This may become slow in case many slots have been
470 // defined and/or when this procedure is invoked many times.
471 // In such cases it is preferable to use indexed addressing in the user code
472 // either directly or via a few invokations of GetSlotIndex().
473
474  Int_t j=GetSlotIndex(name);
475  Int_t word=0;
476  if (j>0) word=GetCalWord(j);
477  return word;
478 }
479 ///////////////////////////////////////////////////////////////////////////
480 Float_t AliAttrib::GetGain(Int_t j) const
481 {
482 // Provide gain value of the j-th (default j=1) attribute slot.
483 // The first attribute slot is at j=1.
484 // In case no gain value was set or the argument j is invalid, 0 is returned.
485 // Note : Use GetGainFlag(j) to check whether this gain was set or not.
486
487  if (j<1) 
488  {
489   cout << " *AliAttrib::GetGain* Invalid argument j = " << j << endl;
490   return 0;
491  }
492
493  Float_t gain=0;
494  if (fGains)
495  {
496   if (j>0 && j<=(fGains->GetSize()))
497   {
498    if (GetGainFlag(j)) gain=fGains->At(j-1);
499   }
500  }
501  return gain;
502 }
503 ///////////////////////////////////////////////////////////////////////////
504 Float_t AliAttrib::GetGain(TString name) const
505 {
506 // Provide gain value of the name-specified attribute slot.
507 //
508 // This procedure involves a slot-index search based on the specified name
509 // at each invokation. This may become slow in case many slots have been
510 // defined and/or when this procedure is invoked many times.
511 // In such cases it is preferable to use indexed addressing in the user code
512 // either directly or via a few invokations of GetSlotIndex().
513
514  Int_t j=GetSlotIndex(name);
515  Float_t gain=0;
516  if (j>0) gain=GetGain(j);
517  return gain;
518 }
519 ///////////////////////////////////////////////////////////////////////////
520 Float_t AliAttrib::GetOffset(Int_t j) const
521 {
522 // Provide offset value of the j-th (default j=1) attribute slot.
523 // The first attribute slot at j=1.
524 // In case no offset value was set or the argument j is invalid, 0 is returned.
525 // Note : Use GetOffsetFlag(j) to check whether this offset was set or not.
526
527  if (j<1) 
528  {
529   cout << " *AliAttrib::GetOffset* Invalid argument j = " << j << endl;
530   return 0;
531  }
532
533  Float_t offset=0;
534  if (fOffsets)
535  {
536   if (j>0 && j<=(fOffsets->GetSize()))
537   {
538    if (GetOffsetFlag(j)) offset=fOffsets->At(j-1);
539   }
540  }
541  return offset;
542 }
543 ///////////////////////////////////////////////////////////////////////////
544 Float_t AliAttrib::GetOffset(TString name) const
545 {
546 // Provide offset value of the name-specified attribute slot.
547 //
548 // This procedure involves a slot-index search based on the specified name
549 // at each invokation. This may become slow in case many slots have been
550 // defined and/or when this procedure is invoked many times.
551 // In such cases it is preferable to use indexed addressing in the user code
552 // either directly or via a few invokations of GetSlotIndex().
553
554  Int_t j=GetSlotIndex(name);
555  Float_t offset=0;
556  if (j>0) offset=GetOffset(j);
557  return offset;
558 }
559 ///////////////////////////////////////////////////////////////////////////
560 void AliAttrib::ResetGain(Int_t j)
561 {
562 // Reset the gain value of the j-th (default j=1) attribute slot.
563 // Notes : The first attribute slot is at j=1.
564 //         j=0 ==> All gain values will be reset.
565  
566  if (!fGains) return;
567
568  Int_t size=fGains->GetSize();
569
570  if ((j>=0) && (j<=size))
571  {
572   if (j)
573   {
574    fGains->AddAt(0,j-1);
575    Int_t oflag=GetOffsetFlag(j);
576    SetCalFlags(0,oflag,j);
577   }
578   else
579   {
580    for (Int_t i=0; i<size; i++)
581    {
582     fGains->AddAt(0,i);
583     Int_t oflag=GetOffsetFlag(i);
584     SetCalFlags(0,oflag,i);
585    }
586   }
587  }
588  else
589  {
590   cout << " *AliAttrib::ResetGain* Index j = " << j << " invalid." << endl;
591   return;
592  }
593 }
594 ///////////////////////////////////////////////////////////////////////////
595 void AliAttrib::ResetGain(TString name)
596 {
597 // Reset the gain value of the name-specified attribute slot.
598 //
599 // This procedure involves a slot-index search based on the specified name
600 // at each invokation. This may become slow in case many slots have been
601 // defined and/or when this procedure is invoked many times.
602 // In such cases it is preferable to use indexed addressing in the user code
603 // either directly or via a few invokations of GetSlotIndex().
604
605  Int_t j=GetSlotIndex(name);
606  if (j>0) ResetGain(j);
607 }
608 ///////////////////////////////////////////////////////////////////////////
609 void AliAttrib::ResetOffset(Int_t j)
610 {
611 // Reset the offset value of the j-th (default j=1) attribute slot.
612 // Notes : The first attribute slot is at j=1.
613 //         j=0 ==> All offset values will be reset.
614  
615  if (!fOffsets) return;
616
617  Int_t size=fOffsets->GetSize();
618
619  if ((j>=0) && (j<=size))
620  {
621   if (j)
622   {
623    fOffsets->AddAt(0,j-1);
624    Int_t gflag=GetGainFlag(j);
625    SetCalFlags(gflag,0,j);
626   }
627   else
628   {
629    for (Int_t i=0; i<size; i++)
630    {
631     fOffsets->AddAt(0,i);
632     Int_t gflag=GetGainFlag(i);
633     SetCalFlags(gflag,0,i);
634    }
635   }
636  }
637  else
638  {
639   cout << " *AliAttrib::ResetOffset* Index j = " << j << " invalid." << endl;
640   return;
641  }
642 }
643 ///////////////////////////////////////////////////////////////////////////
644 void AliAttrib::ResetOffset(TString name)
645 {
646 // Reset the offset value of the name-specified attribute slot.
647 //
648 // This procedure involves a slot-index search based on the specified name
649 // at each invokation. This may become slow in case many slots have been
650 // defined and/or when this procedure is invoked many times.
651 // In such cases it is preferable to use indexed addressing in the user code
652 // either directly or via a few invokations of GetSlotIndex().
653
654  Int_t j=GetSlotIndex(name);
655  if (j>0) ResetOffset(j);
656 }
657 ///////////////////////////////////////////////////////////////////////////
658 void AliAttrib::DeleteCalibrations(Int_t mode)
659 {
660 // User selected delete of all gains and/or offsets.
661 // mode = 0 : All attributes (names,gains,offsets,(de)calfuncs, edge and dead values) are deleted.
662 //        1 : Only the gains are deleted.
663 //        2 : Only the offsets are deleted.
664 //        3 : Gains, offsets and (de)calfuncs are deleted, but names, edge and dead values are kept.
665 //        4 : Only the calib. functions are deleted.
666 //        5 : Only the de-calib. functions are deleted.
667 //        6 : Only the calib. and de-calib. functions are deleted.
668 //
669 // The default when invoking DeleteCalibrations() corresponds to mode=0.
670
671  if (mode<0 || mode>6)
672  {
673   cout << " *AliAttrib::DeleteCalibrations* Unknown mode : " << mode << endl;
674   cout << " Default mode=0 will be used." << endl;
675   mode=0;
676  }
677
678  if (mode==0 || mode==3)
679  {
680   ResetGain(0);
681   if (fGains)
682   {
683    delete fGains;
684    fGains=0;
685   }
686   ResetOffset(0);
687   if (fOffsets)
688   {
689    delete fOffsets;
690    fOffsets=0;
691   }
692   if (fCalflags && mode==0)
693   {
694    delete fCalflags;
695    fCalflags=0;
696   }
697   if (fNames && mode==0)
698   {
699    delete fNames;
700    fNames=0;
701   }
702   if (fCalfuncs)
703   {
704    delete fCalfuncs;
705    fCalfuncs=0;
706   }
707   if (fDecalfuncs)
708   {
709    delete fDecalfuncs;
710    fDecalfuncs=0;
711   }
712   return;
713  }
714
715  if (mode==1)
716  {
717   ResetGain(0);
718   if (fGains)
719   {
720    delete fGains;
721    fGains=0;
722   }
723  }
724
725  if (mode==2)
726  {
727   ResetOffset(0);
728   if (fOffsets)
729   {
730    delete fOffsets;
731    fOffsets=0;
732   }
733  }
734
735  if (mode==4 || mode==6)
736  {
737   if (fCalfuncs)
738   {
739    delete fCalfuncs;
740    fCalfuncs=0;
741   }
742  }
743
744  if (mode==5 || mode==6)
745  {
746   if (fDecalfuncs)
747   {
748    delete fDecalfuncs;
749    fDecalfuncs=0;
750   }
751  }
752 }
753 ///////////////////////////////////////////////////////////////////////////
754 void AliAttrib::SetDead(Int_t j)
755 {
756 // Set the dead flag to 1 for the j-th (default j=1) attribute slot.
757 // Note : The first attribute slot is at j=1.
758 // In case the value of the index j exceeds the maximum number of reserved
759 // slots for the flags, the number of reserved slots for the flags
760 // is increased automatically.
761 // The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
762
763  if (j<1) 
764  {
765   cout << " *AliAttrib::SetDead* Invalid argument j = " << j << endl;
766   return;
767  }
768
769  if (!fCalflags)
770  {
771   fCalflags=new TArrayI(j);
772  }
773
774  Int_t size=fCalflags->GetSize();
775
776  if (j>size)
777  {
778   fCalflags->Set(j);
779  }
780
781  Int_t dead=1;
782  Int_t oflag=GetOffsetFlag(j);
783  Int_t gflag=GetGainFlag(j);
784  Int_t edge=GetEdgeValue(j);
785
786  Int_t word=1000*edge+100*dead+10*gflag+oflag;
787  
788  fCalflags->AddAt(word,j-1);
789 }
790 ///////////////////////////////////////////////////////////////////////////
791 void AliAttrib::SetDead(TString name)
792 {
793 // Set the dead flag to 1 for the name-specified attribute slot.
794 //
795 // This procedure involves a slot-index search based on the specified name
796 // at each invokation. This may become slow in case many slots have been
797 // defined and/or when this procedure is invoked many times.
798 // In such cases it is preferable to use indexed addressing in the user code
799 // either directly or via a few invokations of GetSlotIndex().
800
801  Int_t j=GetSlotIndex(name);
802  if (j>0) SetDead(j);
803 }
804 ///////////////////////////////////////////////////////////////////////////
805 void AliAttrib::SetAlive(Int_t j)
806 {
807 // Set the dead flag to 0 for the j-th (default j=1) attribute slot.
808 // Note : The first attribute slot is at j=1.
809 // In case the value of the index j exceeds the maximum number of reserved
810 // slots for the flags, no action is taken since by default the dead flag is 0.
811 // The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
812
813  if (j<1) 
814  {
815   cout << " *AliAttrib::SetAlive* Invalid argument j = " << j << endl;
816   return;
817  }
818
819  if (!fCalflags || j>fCalflags->GetSize()) return;
820
821  Int_t dead=0;
822  Int_t oflag=GetOffsetFlag(j);
823  Int_t gflag=GetGainFlag(j);
824  Int_t edge=GetEdgeValue(j);
825
826  Int_t word=1000*edge+100*dead+10*gflag+oflag;
827  
828  fCalflags->AddAt(word,j-1);
829 }
830 ///////////////////////////////////////////////////////////////////////////
831 void AliAttrib::SetAlive(TString name)
832 {
833 // Set the dead flag to 0 for the name-specified attribute slot.
834 //
835 // This procedure involves a slot-index search based on the specified name
836 // at each invokation. This may become slow in case many slots have been
837 // defined and/or when this procedure is invoked many times.
838 // In such cases it is preferable to use indexed addressing in the user code
839 // either directly or via a few invokations of GetSlotIndex().
840
841  Int_t j=GetSlotIndex(name);
842  if (j>0) SetAlive(j);
843 }
844 ///////////////////////////////////////////////////////////////////////////
845 void AliAttrib::SetEdgeOn(Int_t j)
846 {
847 // Set the edge value to 1 for the j-th (default j=1) attribute slot.
848 // Note : The first attribute slot is at j=1.
849 // In case the value of the index j exceeds the maximum number of reserved
850 // slots for the flags, the number of reserved slots for the flags
851 // is increased automatically.
852 // The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
853
854  if (j<1) 
855  {
856   cout << " *AliAttrib::SetEdgeOn* Invalid argument j = " << j << endl;
857   return;
858  }
859
860  SetEdgeValue(1,j);
861 }
862 ///////////////////////////////////////////////////////////////////////////
863 void AliAttrib::SetEdgeOn(TString name)
864 {
865 // Set the edge value to 1 for the name-specified attribute slot.
866 //
867 // This procedure involves a slot-index search based on the specified name
868 // at each invokation. This may become slow in case many slots have been
869 // defined and/or when this procedure is invoked many times.
870 // In such cases it is preferable to use indexed addressing in the user code
871 // either directly or via a few invokations of GetSlotIndex().
872
873  Int_t j=GetSlotIndex(name);
874  if (j>0) SetEdgeOn(j);
875 }
876 ///////////////////////////////////////////////////////////////////////////
877 void AliAttrib::SetEdgeOff(Int_t j)
878 {
879 // Set the edge value to 0 for the j-th (default j=1) attribute slot.
880 // Note : The first attribute slot is at j=1.
881 // In case the value of the index j exceeds the maximum number of reserved
882 // slots for the flags, no action is taken since by default the edge flag is 0.
883 // The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
884
885  if (j<1) 
886  {
887   cout << " *AliAttrib::SetEdgeOff* Invalid argument j = " << j << endl;
888   return;
889  }
890
891  if (!fCalflags || j>fCalflags->GetSize()) return;
892
893  SetEdgeValue(0,j);
894 }
895 ///////////////////////////////////////////////////////////////////////////
896 void AliAttrib::SetEdgeOff(TString name)
897 {
898 // Set the edge value to 0 for the name-specified attribute slot.
899 //
900 // This procedure involves a slot-index search based on the specified name
901 // at each invokation. This may become slow in case many slots have been
902 // defined and/or when this procedure is invoked many times.
903 // In such cases it is preferable to use indexed addressing in the user code
904 // either directly or via a few invokations of GetSlotIndex().
905
906  Int_t j=GetSlotIndex(name);
907  if (j>0) SetEdgeOff(j);
908 }
909 ///////////////////////////////////////////////////////////////////////////
910 void AliAttrib::SetEdgeValue(Int_t val,Int_t j)
911 {
912 // Set the edge value to "val" for the j-th (default j=1) attribute slot.
913 // Note : The first attribute slot is at j=1.
914 // In case the value of the index j exceeds the maximum number of reserved
915 // slots for the flags, the number of reserved slots for the flags
916 // is increased automatically.
917 // The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
918
919  if (j<1) 
920  {
921   cout << " *AliAttrib::SetEdgeValue* Invalid argument j = " << j << endl;
922   return;
923  }
924
925  if (!fCalflags)
926  {
927   fCalflags=new TArrayI(j);
928  }
929
930  Int_t size=fCalflags->GetSize();
931
932  if (j>size)
933  {
934   fCalflags->Set(j);
935  }
936
937  Int_t edge=val;
938  Int_t dead=GetDeadValue(j);
939  Int_t gflag=GetGainFlag(j);
940  Int_t oflag=GetOffsetFlag(j);
941
942  Int_t word=1000*edge+100*dead+10*gflag+oflag;
943  
944  fCalflags->AddAt(word,j-1);
945 }
946 ///////////////////////////////////////////////////////////////////////////
947 void AliAttrib::SetEdgeValue(Int_t val,TString name)
948 {
949 // Set the edge value to "val" for the name-specified attribute slot.
950 //
951 // This procedure involves a slot-index search based on the specified name
952 // at each invokation. This may become slow in case many slots have been
953 // defined and/or when this procedure is invoked many times.
954 // In such cases it is preferable to use indexed addressing in the user code
955 // either directly or via a few invokations of GetSlotIndex().
956
957  Int_t j=GetSlotIndex(name);
958  if (j>0) SetEdgeValue(val,j);
959 }
960 ///////////////////////////////////////////////////////////////////////////
961 void AliAttrib::IncreaseEdgeValue(Int_t j)
962 {
963 // Increase the edge value by 1 for the j-th (default j=1) attribute slot.
964 // Note : The first attribute slot is at j=1.
965 // In case the value of the index j exceeds the maximum number of reserved
966 // slots for the flags, the number of reserved slots for the flags
967 // is increased automatically.
968 // The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
969
970  if (j<1) 
971  {
972   cout << " *AliAttrib::IncreaseEdgeValue* Invalid argument j = " << j << endl;
973   return;
974  }
975
976  Int_t edge=GetEdgeValue();
977  SetEdgeValue(edge+1,j);
978 }
979 ///////////////////////////////////////////////////////////////////////////
980 void AliAttrib::IncreaseEdgeValue(TString name)
981 {
982 // Increase the edge value by 1 for the name-specified attribute slot.
983 //
984 // This procedure involves a slot-index search based on the specified name
985 // at each invokation. This may become slow in case many slots have been
986 // defined and/or when this procedure is invoked many times.
987 // In such cases it is preferable to use indexed addressing in the user code
988 // either directly or via a few invokations of GetSlotIndex().
989
990  Int_t j=GetSlotIndex(name);
991  if (j>0) IncreaseEdgeValue(j);
992 }
993 ///////////////////////////////////////////////////////////////////////////
994 void AliAttrib::DecreaseEdgeValue(Int_t j)
995 {
996 // Decrease the edge value by 1 for the j-th (default j=1) attribute slot.
997 // Note : The first attribute slot is at j=1.
998 // In case the value of the index j exceeds the maximum number of reserved
999 // slots for the flags, the number of reserved slots for the flags
1000 // is increased automatically.
1001 // The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
1002
1003  if (j<1) 
1004  {
1005   cout << " *AliAttrib::DecreaseEdgeValue* Invalid argument j = " << j << endl;
1006   return;
1007  }
1008
1009  Int_t edge=GetEdgeValue();
1010  SetEdgeValue(edge-1,j);
1011 }
1012 ///////////////////////////////////////////////////////////////////////////
1013 void AliAttrib::DecreaseEdgeValue(TString name)
1014 {
1015 // Decrease the edge value by 1 for the name-specified attribute slot.
1016 //
1017 // This procedure involves a slot-index search based on the specified name
1018 // at each invokation. This may become slow in case many slots have been
1019 // defined and/or when this procedure is invoked many times.
1020 // In such cases it is preferable to use indexed addressing in the user code
1021 // either directly or via a few invokations of GetSlotIndex().
1022
1023  Int_t j=GetSlotIndex(name);
1024  if (j>0) DecreaseEdgeValue(j);
1025 }
1026 ///////////////////////////////////////////////////////////////////////////
1027 Int_t AliAttrib::GetEdgeValue(Int_t j) const
1028 {
1029 // Provide edge value of the j-th (default j=1) attribute slot.
1030 // Note : The first attribute slot is at j=1.
1031 // In case j is invalid, 0 is returned.
1032
1033  if (j<1) 
1034  {
1035   cout << " *AliAttrib::GetEdgeValue* Invalid argument j = " << j << endl;
1036   return 0;
1037  }
1038
1039  Int_t edge=0;
1040  if (fCalflags)
1041  {
1042   if (j>0 && j<=(fCalflags->GetSize()))
1043   {
1044    Int_t word=fCalflags->At(j-1);
1045    edge=word/1000;
1046   }
1047  }
1048  return edge;
1049 }
1050 ///////////////////////////////////////////////////////////////////////////
1051 Int_t AliAttrib::GetEdgeValue(TString name) const
1052 {
1053 // Provide edge value of the name-specified attribute slot.
1054 //
1055 // This procedure involves a slot-index search based on the specified name
1056 // at each invokation. This may become slow in case many slots have been
1057 // defined and/or when this procedure is invoked many times.
1058 // In such cases it is preferable to use indexed addressing in the user code
1059 // either directly or via a few invokations of GetSlotIndex().
1060
1061  Int_t j=GetSlotIndex(name);
1062  Int_t val=0;
1063  if (j>0) val=GetEdgeValue(j);
1064  return val;
1065 }
1066 ///////////////////////////////////////////////////////////////////////////
1067 Int_t AliAttrib::GetDeadValue(Int_t j) const
1068 {
1069 // Provide dead value of the j-th (default j=1) attribute slot.
1070 // Note : The first attribute slot is at j=1.
1071 // In case j is invalid, 0 is returned.
1072
1073  if (j<1) 
1074  {
1075   cout << " *AliAttrib::GetDeadValue* Invalid argument j = " << j << endl;
1076   return 0;
1077  }
1078
1079  Int_t dead=0;
1080  if (fCalflags)
1081  {
1082   if (j>0 && j<=(fCalflags->GetSize()))
1083   {
1084    Int_t word=fCalflags->At(j-1);
1085    word=word%1000;
1086    dead=word/100;
1087   }
1088  }
1089  return dead;
1090 }
1091 ///////////////////////////////////////////////////////////////////////////
1092 Int_t AliAttrib::GetDeadValue(TString name) const
1093 {
1094 // Provide dead value of the name-specified attribute slot.
1095 //
1096 // This procedure involves a slot-index search based on the specified name
1097 // at each invokation. This may become slow in case many slots have been
1098 // defined and/or when this procedure is invoked many times.
1099 // In such cases it is preferable to use indexed addressing in the user code
1100 // either directly or via a few invokations of GetSlotIndex().
1101
1102  Int_t j=GetSlotIndex(name);
1103  Int_t val=0;
1104  if (j>0) val=GetDeadValue(j);
1105  return val;
1106 }
1107 ///////////////////////////////////////////////////////////////////////////
1108 Int_t AliAttrib::GetNslots() const
1109 {
1110 // Provide the number of existing slots.
1111
1112   Int_t n=GetNcalflags();
1113   Int_t nn=GetNnames();
1114   Int_t ncalf=GetNcalfuncs();
1115   Int_t ndecalf=GetNdecalfuncs();
1116   if (n<nn) n=nn;
1117   if (n<ncalf) n=ncalf;
1118   if (n<ndecalf) n=ndecalf;
1119
1120   return n;
1121 }
1122 ///////////////////////////////////////////////////////////////////////////
1123 void AliAttrib::AddNamedSlot(TString s)
1124 {
1125 // Add a new slot with the specified name.
1126 // In case a slot with the specified name already exists, no action is taken.
1127
1128  if (GetSlotIndex(s)) return;
1129
1130  Int_t n=GetNslots();
1131  SetSlotName(s,n+1);
1132 }
1133 ///////////////////////////////////////////////////////////////////////////
1134 void AliAttrib::SetSlotName(TString s,Int_t j)
1135 {
1136 // Set a user defined name for the j-th (default j=1) slot. 
1137 // Note : The first attribute slot is at j=1.
1138 // In case the value of the index j exceeds the maximum number of reserved
1139 // slots for the names, the number of reserved slots for the names
1140 // is increased automatically to the corresponding value.
1141
1142  if (j<1) 
1143  {
1144   cout << " *AliAttrib::SetSlotName* Invalid argument j = " << j << endl;
1145   return;
1146  }
1147
1148  if (!fNames)
1149  {
1150   fNames=new TObjArray(j);
1151   fNames->SetOwner();
1152  }
1153
1154  if (j>fNames->GetSize()) fNames->Expand(j);
1155
1156  TObjString* so=(TObjString*)fNames->At(j-1);
1157  if (!so)
1158  {
1159   so=new TObjString(s.Data());
1160   fNames->AddAt(so,j-1);
1161  }
1162  else
1163  {
1164   so->SetString(s);
1165  }
1166 }
1167 ///////////////////////////////////////////////////////////////////////////
1168 TString AliAttrib::GetSlotName(Int_t j) const
1169 {
1170 // Provide the user defined name for the j-th (default j=1) slot. 
1171 // Note : The first attribute slot is at j=1.
1172
1173  TString s="";
1174  if (j<1) 
1175  {
1176   cout << " *AliAttrib::GetSlotName* Invalid argument j = " << j << endl;
1177   return s;
1178  }
1179
1180  if (fNames)
1181  {
1182   if (j<=fNames->GetSize())
1183   {
1184    TObjString* so=(TObjString*)fNames->At(j-1);
1185    if (so) s=so->GetString();
1186   }
1187  }
1188  return s;
1189 }
1190 ///////////////////////////////////////////////////////////////////////////
1191 Int_t AliAttrib::GetSlotIndex(TString name) const
1192 {
1193 // Provide the slot index for the matching name.
1194 // If no matching name is found, 0 is returned.
1195 // Note : The first attribute slot is at j=1.
1196
1197  Int_t index=0;
1198
1199  if (fNames)
1200  {
1201   TString s;
1202   Int_t size=fNames->GetSize();
1203   for (Int_t i=0; i<size; i++)
1204   {
1205    TObjString* so=(TObjString*)fNames->At(i);
1206    if (so) s=so->GetString();
1207    if (s==name)
1208    {
1209     index=i+1;
1210     break;
1211    }
1212   }
1213  }
1214  return index;
1215 }
1216 ///////////////////////////////////////////////////////////////////////////
1217 void AliAttrib::List(Int_t j) const
1218 {
1219 // Provide attribute information for the j-th slot.
1220 // The first slot is at j=1.
1221 // In case j=0 (default) the data of all slots will be listed.
1222
1223  if (j<0) 
1224  {
1225   cout << " *AliAttrib::Data* Invalid argument j = " << j << endl;
1226   return;
1227  }
1228
1229  if (j>0)
1230  {
1231   if (GetGainFlag(j)) cout << " gain : " << GetGain(j);
1232   if (GetOffsetFlag(j)) cout << " offset : " << GetOffset(j);
1233   if (GetEdgeValue(j)) cout << " edge : " << GetEdgeValue(j);
1234   if (GetDeadValue(j)) cout << " dead : " << GetDeadValue(j);
1235   if (GetCalFunction(j)) cout << " *Fcalib*";
1236   if (GetDecalFunction(j)) cout << " *Fdecalib*";
1237   TString s=GetSlotName(j);
1238   if (s!="") cout << " name : " << s.Data();
1239  }
1240  else
1241  {
1242   Int_t ng=GetNgains();
1243   Int_t no=GetNoffsets();
1244   Int_t nf=0;
1245   if (fCalflags) nf=fCalflags->GetSize();
1246   Int_t nn=GetNnames();
1247   Int_t n=ng;
1248   if (n<no) n=no;
1249   if (n<nn) n=nn;
1250   if (n<nf) n=nf;
1251   Int_t printf=0;
1252   TString s;
1253   for (Int_t i=1; i<=n; i++)
1254   {
1255    printf=0;
1256    if (GetGainFlag(i))      {cout << " gain : " << GetGain(i); printf=1;}
1257    if (GetOffsetFlag(i))    {cout << " offset : " << GetOffset(i); printf=1;}
1258    if (GetEdgeValue(i))     {cout << " edge : " << GetEdgeValue(i); printf=1;}
1259    if (GetDeadValue(i))     {cout << " dead : " << GetDeadValue(i); printf=1;}
1260    if (GetCalFunction(i))   {cout << " *Fcalib*"; printf=1;}
1261    if (GetDecalFunction(i)) {cout << " *Fdecalib*"; printf=1;}
1262    s=GetSlotName(i);
1263    if (s!="") {cout << " name : " << s.Data(); printf=1;}
1264    if (printf) cout << endl;
1265   }
1266  }
1267
1268 ///////////////////////////////////////////////////////////////////////////
1269 void AliAttrib::List(TString name) const
1270 {
1271 // Provide attribute information for the name-specified slot.
1272 //
1273 // This procedure involves a slot-index search based on the specified name
1274 // at each invokation. This may become slow in case many slots have been
1275 // defined and/or when this procedure is invoked many times.
1276 // In such cases it is preferable to use indexed addressing in the user code
1277 // either directly or via a few invokations of GetSlotIndex().
1278
1279  Int_t j=GetSlotIndex(name);
1280  if (j>0) List(j);
1281 }
1282 ///////////////////////////////////////////////////////////////////////////
1283 void AliAttrib::Load(AliAttrib& a,Int_t j)
1284 {
1285 // Load attributes of the j-th slot of the input AliAttrib into this AliAttrib object.
1286 // 
1287 // Note : if j=0, then all attributes of all slots are loaded
1288 //
1289 // The default is j=0.
1290
1291  if (j<0) 
1292  {
1293   cout << " *AliAttrib::Load* Invalid argument j = " << j << endl;
1294   return;
1295  }
1296
1297  Int_t n=0;
1298
1299  if (j==0) // load attributes for all slots
1300  {
1301   n=a.GetNgains();
1302   for (Int_t ig=1; ig<=n; ig++)
1303   {
1304    if (a.GetGainFlag(ig))
1305    {
1306     SetGain(a.GetGain(ig),ig);
1307    }
1308    else
1309    {
1310     ResetGain(ig);
1311    }
1312   }
1313   n=a.GetNoffsets();
1314   for (Int_t io=1; io<=n; io++)
1315   {
1316    if (a.GetOffsetFlag(io))
1317    {
1318     SetOffset(a.GetOffset(io),io);
1319    }
1320    else
1321    {
1322     ResetOffset(io);
1323    }
1324   }
1325   n=a.GetNcalflags();
1326   for (Int_t ic=1; ic<=n; ic++)
1327   {
1328    SetEdgeValue(a.GetEdgeValue(ic),ic);
1329    if (a.GetDeadValue(ic))
1330    {
1331     SetDead(ic);
1332    }
1333    else
1334    {
1335     SetAlive(ic);
1336    }
1337   }
1338   n=a.GetNnames();
1339   TString s;
1340   for (Int_t in=1; in<=n; in++)
1341   {
1342    s=a.GetSlotName(in);
1343    SetSlotName(s,in);
1344   }
1345   n=a.GetNcalfuncs();
1346   for (Int_t icalf=1; icalf<=n; icalf++)
1347   {
1348    TF1* f=a.GetCalFunction(icalf);
1349    SetCalFunction(f,icalf);
1350   }
1351   n=a.GetNdecalfuncs();
1352   for (Int_t idecalf=1; idecalf<=n; idecalf++)
1353   {
1354    TF1* f=a.GetDecalFunction(idecalf);
1355    SetDecalFunction(f,idecalf);
1356   }
1357  }
1358  else // load attributes for specified j-th slot only
1359  {
1360   n=a.GetNgains();
1361   if (j<=n)
1362   {
1363    if (a.GetGainFlag(j))
1364    {
1365     SetGain(a.GetGain(j),j);
1366    }
1367    else
1368    {
1369     ResetGain(j);
1370    }
1371   }
1372   n=a.GetNoffsets();
1373   if (j<=n)
1374   {
1375    if (a.GetOffsetFlag(j))
1376    {
1377     SetOffset(a.GetOffset(j),j);
1378    }
1379    else
1380    {
1381     ResetOffset(j);
1382    } 
1383   }
1384   n=a.GetNcalflags();
1385   if (j<=n)
1386   {
1387    SetEdgeValue(a.GetEdgeValue(j),j);
1388    if (a.GetDeadValue(j))
1389    {
1390     SetDead(j);
1391    }
1392    else
1393    {
1394     SetAlive(j);
1395    }
1396   }
1397   n=a.GetNnames();
1398   TString s;
1399   if (j<=n)
1400   {
1401    s=a.GetSlotName(j);
1402    SetSlotName(s,j);
1403   }
1404   n=a.GetNcalfuncs();
1405   if (j<=n)
1406   {
1407    TF1* f=a.GetCalFunction(j);
1408    SetCalFunction(f,j);
1409   }
1410   n=a.GetNdecalfuncs();
1411   if (j<=n)
1412   {
1413    TF1* f=a.GetDecalFunction(j);
1414    SetDecalFunction(f,j);
1415   }
1416  }
1417 }
1418 ///////////////////////////////////////////////////////////////////////////
1419 void AliAttrib::Load(AliAttrib& a,TString name)
1420 {
1421 // Load attributes of the name-specified slot of the input AliAttrib into
1422 // this AliAttrib object.
1423 //
1424 // This procedure involves a slot-index search based on the specified name
1425 // at each invokation. This may become slow in case many slots have been
1426 // defined and/or when this procedure is invoked many times.
1427 // In such cases it is preferable to use indexed addressing in the user code
1428 // either directly or via a few invokations of GetSlotIndex().
1429
1430  Int_t j=GetSlotIndex(name);
1431  if (j>0) Load(a,j);
1432 }
1433 ///////////////////////////////////////////////////////////////////////////
1434 Int_t AliAttrib::GetNcalfuncs() const
1435 {
1436 // Provide the number of specified calib. functions for this attribute.
1437
1438  if (!fCalfuncs) return 0;
1439
1440  Int_t n=0;
1441  for (Int_t i=1; i<=fCalfuncs->GetSize(); i++)
1442  {
1443   if (fCalfuncs->At(i-1)) n=i;
1444  }
1445  return n;
1446 }
1447 ///////////////////////////////////////////////////////////////////////////
1448 Int_t AliAttrib::GetNdecalfuncs() const
1449 {
1450 // Provide the number of specified de-calib. functions for this attribute.
1451
1452  if (!fDecalfuncs) return 0;
1453
1454  Int_t n=0;
1455  for (Int_t i=1; i<=fDecalfuncs->GetSize(); i++)
1456  {
1457   if (fDecalfuncs->At(i-1)) n=i;
1458  }
1459  return n;
1460 }
1461 ///////////////////////////////////////////////////////////////////////////
1462 TF1* AliAttrib::GetCalFunction(Int_t j) const
1463 {
1464 // Provide pointer to the calib. function of the j-th (default j=1) slot.
1465 // Note : The first attribute slot is at j=1.
1466
1467  TF1* f=0;
1468  if (j>0 && j<=GetNcalfuncs()) f=(TF1*)fCalfuncs->At(j-1);
1469  return f;
1470 }
1471 ///////////////////////////////////////////////////////////////////////////
1472 TF1* AliAttrib::GetCalFunction(TString name) const
1473 {
1474 // Provide pointer to the calib. function of the name-specified slot.
1475 // In case no match is found, zero is returned.
1476
1477  TF1* f=0;
1478  Int_t j=GetSlotIndex(name);
1479  if (j>0) f=GetCalFunction(j);
1480  return f;
1481 }
1482 ///////////////////////////////////////////////////////////////////////////
1483 void AliAttrib::SetCalFunction(TF1* f,Int_t j)
1484 {
1485 // Set the calib. function of the j-th (default j=1) slot.
1486 // Note : The first attribute slot is at j=1.
1487 //
1488 // In case the value of the index j exceeds the maximum number of reserved
1489 // positions for the functions, the number of reserved positions for the functions
1490 // is increased automatically.
1491 //
1492 // In case the function pointer argument has the same value as the current function
1493 // pointer value, no action is taken since the user has already modified the actual
1494 // function.
1495 //
1496 // In case the function pointer argument is zero, the current function
1497 // is deleted and the pointer set to zero.
1498 //
1499 // In all other cases the current function is deleted and a new
1500 // copy of the input function is created which becomes the current function.
1501
1502  if (j<1) return;
1503
1504  if (!fCalfuncs)
1505  {
1506   fCalfuncs=new TObjArray(j);
1507   fCalfuncs->SetOwner();
1508  }
1509
1510  if (j > fCalfuncs->GetSize()) fCalfuncs->Expand(j);
1511
1512  TF1* fcur=(TF1*)fCalfuncs->At(j-1);
1513  if (f != fcur)
1514  {
1515   if (fcur)
1516   {
1517    fCalfuncs->Remove(fcur);
1518    delete fcur;
1519    fcur=0;
1520   }
1521   if (f)
1522   {
1523    fcur=new TF1(*f);
1524    fCalfuncs->AddAt(fcur,j-1);
1525   }
1526  } 
1527 }
1528 ///////////////////////////////////////////////////////////////////////////
1529 void AliAttrib::SetCalFunction(TF1* f,TString name)
1530 {
1531 // Set the calib. function of the name-specified slot.
1532 //
1533 // In case the function pointer argument has the same value as the current function
1534 // pointer value, no action is taken since the user has already modified the actual
1535 // function.
1536 //
1537 // In case the function pointer argument is zero, the current function
1538 // is deleted and the pointer set to zero.
1539 //
1540 // In all other cases the current function is deleted and a new
1541 // copy of the input function is created which becomes the current function.
1542
1543  Int_t j=GetSlotIndex(name);
1544  if (j>0) SetCalFunction(f,j);
1545 }
1546 ///////////////////////////////////////////////////////////////////////////
1547 TF1* AliAttrib::GetDecalFunction(Int_t j) const
1548 {
1549 // Provide pointer to the de-calib. function of the j-th (default j=1) slot.
1550 // Note : The first attribute slot is at j=1.
1551
1552  TF1* f=0;
1553  if (j>0 && j<=GetNdecalfuncs()) f=(TF1*)fDecalfuncs->At(j-1);
1554  return f;
1555 }
1556 ///////////////////////////////////////////////////////////////////////////
1557 TF1* AliAttrib::GetDecalFunction(TString name) const
1558 {
1559 // Provide pointer to the de-calib. function of the name-specified slot.
1560 // In case no match is found, zero is returned.
1561
1562  TF1* f=0;
1563  Int_t j=GetSlotIndex(name);
1564  if (j>0) f=GetDecalFunction(j);
1565  return f;
1566 }
1567 ///////////////////////////////////////////////////////////////////////////
1568 void AliAttrib::SetDecalFunction(TF1* f,Int_t j)
1569 {
1570 // Set the de-calib. function of the j-th (default j=1) slot.
1571 // Note : The first attribute slot is at j=1.
1572 //
1573 // In case the value of the index j exceeds the maximum number of reserved
1574 // positions for the functions, the number of reserved positions for the functions
1575 // is increased automatically.
1576 //
1577 // In case the function pointer argument has the same value as the current function
1578 // pointer value, no action is taken since the user has already modified the actual
1579 // function.
1580 //
1581 // In case the function pointer argument is zero, the current function
1582 // is deleted and the pointer set to zero.
1583 //
1584 // In all other cases the current function is deleted and a new
1585 // copy of the input function is created which becomes the current function.
1586
1587  if (j<1) return;
1588
1589  if (!fDecalfuncs)
1590  {
1591   fDecalfuncs=new TObjArray(j);
1592   fDecalfuncs->SetOwner();
1593  }
1594
1595  if (j > fDecalfuncs->GetSize()) fDecalfuncs->Expand(j);
1596
1597  TF1* fcur=(TF1*)fDecalfuncs->At(j-1);
1598  if (f != fcur)
1599  {
1600   if (fcur)
1601   {
1602    fDecalfuncs->Remove(fcur);
1603    delete fcur;
1604    fcur=0;
1605   }
1606   if (f)
1607   {
1608    fcur=new TF1(*f);
1609    fDecalfuncs->AddAt(fcur,j-1);
1610   }
1611  } 
1612 }
1613 ///////////////////////////////////////////////////////////////////////////
1614 void AliAttrib::SetDecalFunction(TF1* f,TString name)
1615 {
1616 // Set the de-calib. function of the name-specified slot.
1617 //
1618 // In case the function pointer argument has the same value as the current function
1619 // pointer value, no action is taken since the user has already modified the actual
1620 // function.
1621 //
1622 // In case the function pointer argument is zero, the current function
1623 // is deleted and the pointer set to zero.
1624 //
1625 // In all other cases the current function is deleted and a new
1626 // copy of the input function is created which becomes the current function.
1627
1628  Int_t j=GetSlotIndex(name);
1629  if (j>0) SetDecalFunction(f,j);
1630 }
1631 ///////////////////////////////////////////////////////////////////////////