05-aug-2005 NvE Typos fixed in AliAttrib::GetCalFunction and AliAttrib::GetDecalFunct...
[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  Int_t n=0;
160  if (fGains) n=fGains->GetSize();
161  return n;
162 }
163 ///////////////////////////////////////////////////////////////////////////
164 Int_t AliAttrib::GetNoffsets() const
165 {
166 // Provide the number of specified offsets for this attribute.
167  Int_t n=0;
168  if (fOffsets) n=fOffsets->GetSize();
169  return n;
170 }
171 ///////////////////////////////////////////////////////////////////////////
172 Int_t AliAttrib::GetNcalflags() const
173 {
174 // Provide the number of specified calib. flags for this attribute.
175  Int_t n=0;
176  if (fCalflags) n=fCalflags->GetSize();
177  return n;
178 }
179 ///////////////////////////////////////////////////////////////////////////
180 Int_t AliAttrib::GetNnames() const
181 {
182 // Provide the maximum number of specified names for this attribute.
183  Int_t n=0;
184  if (fNames) n=fNames->GetSize();
185  return n;
186 }
187 ///////////////////////////////////////////////////////////////////////////
188 void AliAttrib::SetGain(Double_t gain,Int_t j)
189 {
190 // Store gain value of the j-th (default j=1) attribute slot.
191 // Note : The first attribute slot is at j=1.
192 // In case the value of the index j exceeds the maximum number of reserved
193 // slots for gain values, the number of reserved slots for the gain
194 // values is increased automatically.
195
196  if (j<1) 
197  {
198   cout << " *AliAttrib::SetGain* Invalid argument j = " << j << endl;
199   return;
200  }
201
202  if (!fGains)
203  {
204   fGains=new TArrayF(j);
205  }
206
207  Int_t size=fGains->GetSize();
208
209  if (j>size)
210  {
211   fGains->Set(j);
212  }
213
214  fGains->AddAt(float(gain),j-1);
215
216  Int_t oflag=GetOffsetFlag(j);
217
218  SetCalFlags(1,oflag,j);
219 }
220 ///////////////////////////////////////////////////////////////////////////
221 void AliAttrib::SetGain(Double_t gain,TString name)
222 {
223 // Store gain value of the name-specified attribute slot.
224 //
225 // This procedure involves a slot-index search based on the specified name
226 // at each invokation. This may become slow in case many slots have been
227 // defined and/or when this procedure is invoked many times.
228 // In such cases it is preferable to use indexed addressing in the user code
229 // either directly or via a few invokations of GetSlotIndex().
230
231  Int_t j=GetSlotIndex(name);
232  if (j>0) SetGain(gain,j);
233 }
234 ///////////////////////////////////////////////////////////////////////////
235 void AliAttrib::SetOffset(Double_t off,Int_t j)
236 {
237 // Store offset value of the j-th (default j=1) attribute slot.
238 // Note : The first attribute slot is at j=1.
239 // In case the value of the index j exceeds the maximum number of reserved
240 // slots for offset values, the number of reserved slots for the offset
241 // values is increased automatically.
242
243  if (j<1) 
244  {
245   cout << " *AliAttrib::GetOffset* Invalid argument j = " << j << endl;
246   return;
247  }
248
249  if (!fOffsets)
250  {
251   fOffsets=new TArrayF(j);
252  }
253
254  Int_t size=fOffsets->GetSize();
255
256  if (j>size)
257  {
258   fOffsets->Set(j);
259  }
260
261  fOffsets->AddAt(float(off),j-1);
262
263  Int_t gflag=GetGainFlag(j);
264
265  SetCalFlags(gflag,1,j);
266 }
267 ///////////////////////////////////////////////////////////////////////////
268 void AliAttrib::SetOffset(Double_t off,TString name)
269 {
270 // Store offset value of the name-specified attribute slot.
271 //
272 // This procedure involves a slot-index search based on the specified name
273 // at each invokation. This may become slow in case many slots have been
274 // defined and/or when this procedure is invoked many times.
275 // In such cases it is preferable to use indexed addressing in the user code
276 // either directly or via a few invokations of GetSlotIndex().
277
278  Int_t j=GetSlotIndex(name);
279  if (j>0) SetOffset(off,j);
280 }
281 ///////////////////////////////////////////////////////////////////////////
282 void AliAttrib::SetCalFlags(Int_t gainflag,Int_t offsetflag,Int_t j)
283 {
284 // Store calibration flags of the j-th (default j=1) attribute slot.
285 // Note : The first attribute slot is at j=1.
286 // In case the value of the index j exceeds the maximum number of reserved
287 // slots for the calib. flags, the number of reserved slots for the calib.
288 // flags is increased automatically.
289 // The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
290
291  if (j<1) 
292  {
293   cout << " *AliAttrib::GetCalFlags* Invalid argument j = " << j << endl;
294   return;
295  }
296
297  if (!fCalflags)
298  {
299   fCalflags=new TArrayI(j);
300  }
301
302  Int_t size=fCalflags->GetSize();
303
304  if (j>size)
305  {
306   fCalflags->Set(j);
307  }
308
309  Int_t edge=GetEdgeValue(j);
310  Int_t dead=GetDeadValue(j);
311
312  Int_t word=1000*edge+100*dead+10*gainflag+offsetflag;
313  
314  fCalflags->AddAt(word,j-1);
315 }
316 ///////////////////////////////////////////////////////////////////////////
317 Int_t AliAttrib::GetGainFlag(Int_t j) const
318 {
319 // Provide gain flag of the j-th (default j=1) attribute slot.
320 //
321 // flag = 1 : Gain was set
322 //        0 : Gain was not set
323 //
324 // Note : The first attribute slot is at j=1.
325 // In case j is invalid, 0 is returned.
326
327  if (j<1) 
328  {
329   cout << " *AliAttrib::GetGainFlag* Invalid argument j = " << j << endl;
330   return 0;
331  }
332  Int_t gflag=0;
333  if (fCalflags)
334  {
335   if (j>0 && j<=(fCalflags->GetSize()))
336   {
337    Int_t word=fCalflags->At(j-1);
338    word=word%100;
339    gflag=word/10;
340   }
341  }
342  return gflag;
343 }
344 ///////////////////////////////////////////////////////////////////////////
345 Int_t AliAttrib::GetGainFlag(TString name) const
346 {
347 // Provide gain flag of the name-specified attribute slot.
348 //
349 // flag = 1 : Gain was set
350 //        0 : Gain was not set
351 //
352 //
353 // This procedure involves a slot-index search based on the specified name
354 // at each invokation. This may become slow in case many slots have been
355 // defined and/or when this procedure is invoked many times.
356 // In such cases it is preferable to use indexed addressing in the user code
357 // either directly or via a few invokations of GetSlotIndex().
358
359  Int_t j=GetSlotIndex(name);
360  Int_t flag=0;
361  if (j>0) flag=GetGainFlag(j);
362  return flag;
363 }
364 ///////////////////////////////////////////////////////////////////////////
365 Int_t AliAttrib::GetOffsetFlag(Int_t j) const
366 {
367 // Provide offset flag of the j-th (default j=1) attribute slot.
368 //
369 // flag = 1 : Offset was set
370 //        0 : Offset was not set
371 //
372 // Note : The first attribute slot is at j=1.
373 // In case j is invalid, 0 is returned.
374
375  if (j<1) 
376  {
377   cout << " *AliAttrib::GetOffsetFlag* Invalid argument j = " << j << endl;
378   return 0;
379  }
380
381  Int_t oflag=0;
382  if (fCalflags)
383  {
384   if (j>0 && j<=(fCalflags->GetSize()))
385   {
386    Int_t word=fCalflags->At(j-1);
387    oflag=word%10;
388   }
389  }
390  return oflag;
391 }
392 ///////////////////////////////////////////////////////////////////////////
393 Int_t AliAttrib::GetOffsetFlag(TString name) const
394 {
395 // Provide ofset flag of the name-specified attribute slot.
396 //
397 // flag = 1 : Offset was set
398 //        0 : Offset was not set
399 //
400 //
401 // This procedure involves a slot-index search based on the specified name
402 // at each invokation. This may become slow in case many slots have been
403 // defined and/or when this procedure is invoked many times.
404 // In such cases it is preferable to use indexed addressing in the user code
405 // either directly or via a few invokations of GetSlotIndex().
406
407  Int_t j=GetSlotIndex(name);
408  Int_t flag=0;
409  if (j>0) flag=GetOffsetFlag(j);
410  return flag;
411 }
412 ///////////////////////////////////////////////////////////////////////////
413 Float_t AliAttrib::GetGain(Int_t j) const
414 {
415 // Provide gain value of the j-th (default j=1) attribute slot.
416 // The first attribute slot is at j=1.
417 // In case no gain value was set or the argument j is invalid, 0 is returned.
418 // Note : Use GetGainFlag(j) to check whether this gain was set or not.
419
420  if (j<1) 
421  {
422   cout << " *AliAttrib::GetGain* Invalid argument j = " << j << endl;
423   return 0;
424  }
425
426  Float_t gain=0;
427  if (fGains)
428  {
429   if (j>0 && j<=(fGains->GetSize()))
430   {
431    if (GetGainFlag(j)) gain=fGains->At(j-1);
432   }
433  }
434  return gain;
435 }
436 ///////////////////////////////////////////////////////////////////////////
437 Float_t AliAttrib::GetGain(TString name) const
438 {
439 // Provide gain value of the name-specified attribute slot.
440 //
441 // This procedure involves a slot-index search based on the specified name
442 // at each invokation. This may become slow in case many slots have been
443 // defined and/or when this procedure is invoked many times.
444 // In such cases it is preferable to use indexed addressing in the user code
445 // either directly or via a few invokations of GetSlotIndex().
446
447  Int_t j=GetSlotIndex(name);
448  Float_t gain=0;
449  if (j>0) gain=GetGain(j);
450  return gain;
451 }
452 ///////////////////////////////////////////////////////////////////////////
453 Float_t AliAttrib::GetOffset(Int_t j) const
454 {
455 // Provide offset value of the j-th (default j=1) attribute slot.
456 // The first attribute slot at j=1.
457 // In case no offset value was set or the argument j is invalid, 0 is returned.
458 // Note : Use GetOffsetFlag(j) to check whether this offset was set or not.
459
460  if (j<1) 
461  {
462   cout << " *AliAttrib::GetOffset* Invalid argument j = " << j << endl;
463   return 0;
464  }
465
466  Float_t offset=0;
467  if (fOffsets)
468  {
469   if (j>0 && j<=(fOffsets->GetSize()))
470   {
471    if (GetOffsetFlag(j)) offset=fOffsets->At(j-1);
472   }
473  }
474  return offset;
475 }
476 ///////////////////////////////////////////////////////////////////////////
477 Float_t AliAttrib::GetOffset(TString name) const
478 {
479 // Provide offset value of the name-specified attribute slot.
480 //
481 // This procedure involves a slot-index search based on the specified name
482 // at each invokation. This may become slow in case many slots have been
483 // defined and/or when this procedure is invoked many times.
484 // In such cases it is preferable to use indexed addressing in the user code
485 // either directly or via a few invokations of GetSlotIndex().
486
487  Int_t j=GetSlotIndex(name);
488  Float_t offset=0;
489  if (j>0) offset=GetOffset(j);
490  return offset;
491 }
492 ///////////////////////////////////////////////////////////////////////////
493 void AliAttrib::ResetGain(Int_t j)
494 {
495 // Reset the gain value of the j-th (default j=1) attribute slot.
496 // Notes : The first attribute slot is at j=1.
497 //         j=0 ==> All gain values will be reset.
498  
499  if (!fGains) return;
500
501  Int_t size=fGains->GetSize();
502
503  if ((j>=0) && (j<=size))
504  {
505   if (j)
506   {
507    fGains->AddAt(0,j-1);
508    Int_t oflag=GetOffsetFlag(j);
509    SetCalFlags(0,oflag,j);
510   }
511   else
512   {
513    for (Int_t i=0; i<size; i++)
514    {
515     fGains->AddAt(0,i);
516     Int_t oflag=GetOffsetFlag(i);
517     SetCalFlags(0,oflag,i);
518    }
519   }
520  }
521  else
522  {
523   cout << " *AliAttrib::ResetGain* Index j = " << j << " invalid." << endl;
524   return;
525  }
526 }
527 ///////////////////////////////////////////////////////////////////////////
528 void AliAttrib::ResetGain(TString name)
529 {
530 // Reset the gain value of the name-specified attribute slot.
531 //
532 // This procedure involves a slot-index search based on the specified name
533 // at each invokation. This may become slow in case many slots have been
534 // defined and/or when this procedure is invoked many times.
535 // In such cases it is preferable to use indexed addressing in the user code
536 // either directly or via a few invokations of GetSlotIndex().
537
538  Int_t j=GetSlotIndex(name);
539  if (j>0) ResetGain(j);
540 }
541 ///////////////////////////////////////////////////////////////////////////
542 void AliAttrib::ResetOffset(Int_t j)
543 {
544 // Reset the offset value of the j-th (default j=1) attribute slot.
545 // Notes : The first attribute slot is at j=1.
546 //         j=0 ==> All offset values will be reset.
547  
548  if (!fOffsets) return;
549
550  Int_t size=fOffsets->GetSize();
551
552  if ((j>=0) && (j<=size))
553  {
554   if (j)
555   {
556    fOffsets->AddAt(0,j-1);
557    Int_t gflag=GetGainFlag(j);
558    SetCalFlags(gflag,0,j);
559   }
560   else
561   {
562    for (Int_t i=0; i<size; i++)
563    {
564     fOffsets->AddAt(0,i);
565     Int_t gflag=GetGainFlag(i);
566     SetCalFlags(gflag,0,i);
567    }
568   }
569  }
570  else
571  {
572   cout << " *AliAttrib::ResetOffset* Index j = " << j << " invalid." << endl;
573   return;
574  }
575 }
576 ///////////////////////////////////////////////////////////////////////////
577 void AliAttrib::ResetOffset(TString name)
578 {
579 // Reset the offset value of the name-specified attribute slot.
580 //
581 // This procedure involves a slot-index search based on the specified name
582 // at each invokation. This may become slow in case many slots have been
583 // defined and/or when this procedure is invoked many times.
584 // In such cases it is preferable to use indexed addressing in the user code
585 // either directly or via a few invokations of GetSlotIndex().
586
587  Int_t j=GetSlotIndex(name);
588  if (j>0) ResetOffset(j);
589 }
590 ///////////////////////////////////////////////////////////////////////////
591 void AliAttrib::DeleteCalibrations(Int_t mode)
592 {
593 // User selected delete of all gains and/or offsets.
594 // mode = 0 : All attributes (names,gains,offsets,(de)calfuncs, edge and dead values) are deleted.
595 //        1 : Only the gains are deleted.
596 //        2 : Only the offsets are deleted.
597 //        3 : Gains, offsets and (de)calfuncs are deleted, but names, edge and dead values are kept.
598 //        4 : Only the calib. functions are deleted.
599 //        5 : Only the de-calib. functions are deleted.
600 //        6 : Only the calib. and de-calib. functions are deleted.
601 //
602 // The default when invoking DeleteCalibrations() corresponds to mode=0.
603
604  if (mode<0 || mode>6)
605  {
606   cout << " *AliAttrib::DeleteCalibrations* Unknown mode : " << mode << endl;
607   cout << " Default mode=0 will be used." << endl;
608   mode=0;
609  }
610
611  if (mode==0 || mode==3)
612  {
613   ResetGain(0);
614   if (fGains)
615   {
616    delete fGains;
617    fGains=0;
618   }
619   ResetOffset(0);
620   if (fOffsets)
621   {
622    delete fOffsets;
623    fOffsets=0;
624   }
625   if (fCalflags && mode==0)
626   {
627    delete fCalflags;
628    fCalflags=0;
629   }
630   if (fNames && mode==0)
631   {
632    delete fNames;
633    fNames=0;
634   }
635   if (fCalfuncs)
636   {
637    delete fCalfuncs;
638    fCalfuncs=0;
639   }
640   if (fDecalfuncs)
641   {
642    delete fDecalfuncs;
643    fDecalfuncs=0;
644   }
645   return;
646  }
647
648  if (mode==1)
649  {
650   ResetGain(0);
651   if (fGains)
652   {
653    delete fGains;
654    fGains=0;
655   }
656  }
657
658  if (mode==2)
659  {
660   ResetOffset(0);
661   if (fOffsets)
662   {
663    delete fOffsets;
664    fOffsets=0;
665   }
666  }
667
668  if (mode==4 || mode==6)
669  {
670   if (fCalfuncs)
671   {
672    delete fCalfuncs;
673    fCalfuncs=0;
674   }
675  }
676
677  if (mode==5 || mode==6)
678  {
679   if (fDecalfuncs)
680   {
681    delete fDecalfuncs;
682    fDecalfuncs=0;
683   }
684  }
685 }
686 ///////////////////////////////////////////////////////////////////////////
687 void AliAttrib::SetDead(Int_t j)
688 {
689 // Set the dead flag to 1 for the j-th (default j=1) attribute slot.
690 // Note : The first attribute slot is at j=1.
691 // In case the value of the index j exceeds the maximum number of reserved
692 // slots for the flags, the number of reserved slots for the flags
693 // is increased automatically.
694 // The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
695
696  if (j<1) 
697  {
698   cout << " *AliAttrib::SetDead* Invalid argument j = " << j << endl;
699   return;
700  }
701
702  if (!fCalflags)
703  {
704   fCalflags=new TArrayI(j);
705  }
706
707  Int_t size=fCalflags->GetSize();
708
709  if (j>size)
710  {
711   fCalflags->Set(j);
712  }
713
714  Int_t dead=1;
715  Int_t oflag=GetOffsetFlag(j);
716  Int_t gflag=GetGainFlag(j);
717  Int_t edge=GetEdgeValue(j);
718
719  Int_t word=1000*edge+100*dead+10*gflag+oflag;
720  
721  fCalflags->AddAt(word,j-1);
722 }
723 ///////////////////////////////////////////////////////////////////////////
724 void AliAttrib::SetDead(TString name)
725 {
726 // Set the dead flag to 1 for the name-specified attribute slot.
727 //
728 // This procedure involves a slot-index search based on the specified name
729 // at each invokation. This may become slow in case many slots have been
730 // defined and/or when this procedure is invoked many times.
731 // In such cases it is preferable to use indexed addressing in the user code
732 // either directly or via a few invokations of GetSlotIndex().
733
734  Int_t j=GetSlotIndex(name);
735  if (j>0) SetDead(j);
736 }
737 ///////////////////////////////////////////////////////////////////////////
738 void AliAttrib::SetAlive(Int_t j)
739 {
740 // Set the dead flag to 0 for the j-th (default j=1) attribute slot.
741 // Note : The first attribute slot is at j=1.
742 // In case the value of the index j exceeds the maximum number of reserved
743 // slots for the flags, no action is taken since by default the dead flag is 0.
744 // The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
745
746  if (j<1) 
747  {
748   cout << " *AliAttrib::SetAlive* Invalid argument j = " << j << endl;
749   return;
750  }
751
752  if (!fCalflags || j>fCalflags->GetSize()) return;
753
754  Int_t dead=0;
755  Int_t oflag=GetOffsetFlag(j);
756  Int_t gflag=GetGainFlag(j);
757  Int_t edge=GetEdgeValue(j);
758
759  Int_t word=1000*edge+100*dead+10*gflag+oflag;
760  
761  fCalflags->AddAt(word,j-1);
762 }
763 ///////////////////////////////////////////////////////////////////////////
764 void AliAttrib::SetAlive(TString name)
765 {
766 // Set the dead flag to 0 for the name-specified attribute slot.
767 //
768 // This procedure involves a slot-index search based on the specified name
769 // at each invokation. This may become slow in case many slots have been
770 // defined and/or when this procedure is invoked many times.
771 // In such cases it is preferable to use indexed addressing in the user code
772 // either directly or via a few invokations of GetSlotIndex().
773
774  Int_t j=GetSlotIndex(name);
775  if (j>0) SetAlive(j);
776 }
777 ///////////////////////////////////////////////////////////////////////////
778 void AliAttrib::SetEdgeOn(Int_t j)
779 {
780 // Set the edge value to 1 for the j-th (default j=1) attribute slot.
781 // Note : The first attribute slot is at j=1.
782 // In case the value of the index j exceeds the maximum number of reserved
783 // slots for the flags, the number of reserved slots for the flags
784 // is increased automatically.
785 // The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
786
787  if (j<1) 
788  {
789   cout << " *AliAttrib::SetEdgeOn* Invalid argument j = " << j << endl;
790   return;
791  }
792
793  SetEdgeValue(1,j);
794 }
795 ///////////////////////////////////////////////////////////////////////////
796 void AliAttrib::SetEdgeOn(TString name)
797 {
798 // Set the edge value to 1 for the name-specified attribute slot.
799 //
800 // This procedure involves a slot-index search based on the specified name
801 // at each invokation. This may become slow in case many slots have been
802 // defined and/or when this procedure is invoked many times.
803 // In such cases it is preferable to use indexed addressing in the user code
804 // either directly or via a few invokations of GetSlotIndex().
805
806  Int_t j=GetSlotIndex(name);
807  if (j>0) SetEdgeOn(j);
808 }
809 ///////////////////////////////////////////////////////////////////////////
810 void AliAttrib::SetEdgeOff(Int_t j)
811 {
812 // Set the edge value to 0 for the j-th (default j=1) attribute slot.
813 // Note : The first attribute slot is at j=1.
814 // In case the value of the index j exceeds the maximum number of reserved
815 // slots for the flags, no action is taken since by default the edge flag is 0.
816 // The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
817
818  if (j<1) 
819  {
820   cout << " *AliAttrib::SetEdgeOff* Invalid argument j = " << j << endl;
821   return;
822  }
823
824  if (!fCalflags || j>fCalflags->GetSize()) return;
825
826  SetEdgeValue(0,j);
827 }
828 ///////////////////////////////////////////////////////////////////////////
829 void AliAttrib::SetEdgeOff(TString name)
830 {
831 // Set the edge value to 0 for the name-specified attribute slot.
832 //
833 // This procedure involves a slot-index search based on the specified name
834 // at each invokation. This may become slow in case many slots have been
835 // defined and/or when this procedure is invoked many times.
836 // In such cases it is preferable to use indexed addressing in the user code
837 // either directly or via a few invokations of GetSlotIndex().
838
839  Int_t j=GetSlotIndex(name);
840  if (j>0) SetEdgeOff(j);
841 }
842 ///////////////////////////////////////////////////////////////////////////
843 void AliAttrib::SetEdgeValue(Int_t val,Int_t j)
844 {
845 // Set the edge value to "val" for the j-th (default j=1) attribute slot.
846 // Note : The first attribute slot is at j=1.
847 // In case the value of the index j exceeds the maximum number of reserved
848 // slots for the flags, the number of reserved slots for the flags
849 // is increased automatically.
850 // The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
851
852  if (j<1) 
853  {
854   cout << " *AliAttrib::SetEdgeValue* Invalid argument j = " << j << endl;
855   return;
856  }
857
858  if (!fCalflags)
859  {
860   fCalflags=new TArrayI(j);
861  }
862
863  Int_t size=fCalflags->GetSize();
864
865  if (j>size)
866  {
867   fCalflags->Set(j);
868  }
869
870  Int_t edge=val;
871  Int_t dead=GetDeadValue(j);
872  Int_t gflag=GetGainFlag(j);
873  Int_t oflag=GetOffsetFlag(j);
874
875  Int_t word=1000*edge+100*dead+10*gflag+oflag;
876  
877  fCalflags->AddAt(word,j-1);
878 }
879 ///////////////////////////////////////////////////////////////////////////
880 void AliAttrib::SetEdgeValue(Int_t val,TString name)
881 {
882 // Set the edge value to "val" for the name-specified attribute slot.
883 //
884 // This procedure involves a slot-index search based on the specified name
885 // at each invokation. This may become slow in case many slots have been
886 // defined and/or when this procedure is invoked many times.
887 // In such cases it is preferable to use indexed addressing in the user code
888 // either directly or via a few invokations of GetSlotIndex().
889
890  Int_t j=GetSlotIndex(name);
891  if (j>0) SetEdgeValue(val,j);
892 }
893 ///////////////////////////////////////////////////////////////////////////
894 void AliAttrib::IncreaseEdgeValue(Int_t j)
895 {
896 // Increase the edge value by 1 for the j-th (default j=1) attribute slot.
897 // Note : The first attribute slot is at j=1.
898 // In case the value of the index j exceeds the maximum number of reserved
899 // slots for the flags, the number of reserved slots for the flags
900 // is increased automatically.
901 // The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
902
903  if (j<1) 
904  {
905   cout << " *AliAttrib::IncreaseEdgeValue* Invalid argument j = " << j << endl;
906   return;
907  }
908
909  Int_t edge=GetEdgeValue();
910  SetEdgeValue(edge+1,j);
911 }
912 ///////////////////////////////////////////////////////////////////////////
913 void AliAttrib::IncreaseEdgeValue(TString name)
914 {
915 // Increase the edge value by 1 for the name-specified attribute slot.
916 //
917 // This procedure involves a slot-index search based on the specified name
918 // at each invokation. This may become slow in case many slots have been
919 // defined and/or when this procedure is invoked many times.
920 // In such cases it is preferable to use indexed addressing in the user code
921 // either directly or via a few invokations of GetSlotIndex().
922
923  Int_t j=GetSlotIndex(name);
924  if (j>0) IncreaseEdgeValue(j);
925 }
926 ///////////////////////////////////////////////////////////////////////////
927 void AliAttrib::DecreaseEdgeValue(Int_t j)
928 {
929 // Decrease the edge value by 1 for the j-th (default j=1) attribute slot.
930 // Note : The first attribute slot is at j=1.
931 // In case the value of the index j exceeds the maximum number of reserved
932 // slots for the flags, the number of reserved slots for the flags
933 // is increased automatically.
934 // The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
935
936  if (j<1) 
937  {
938   cout << " *AliAttrib::DecreaseEdgeValue* Invalid argument j = " << j << endl;
939   return;
940  }
941
942  Int_t edge=GetEdgeValue();
943  SetEdgeValue(edge-1,j);
944 }
945 ///////////////////////////////////////////////////////////////////////////
946 void AliAttrib::DecreaseEdgeValue(TString name)
947 {
948 // Decrease the edge value by 1 for the name-specified attribute slot.
949 //
950 // This procedure involves a slot-index search based on the specified name
951 // at each invokation. This may become slow in case many slots have been
952 // defined and/or when this procedure is invoked many times.
953 // In such cases it is preferable to use indexed addressing in the user code
954 // either directly or via a few invokations of GetSlotIndex().
955
956  Int_t j=GetSlotIndex(name);
957  if (j>0) DecreaseEdgeValue(j);
958 }
959 ///////////////////////////////////////////////////////////////////////////
960 Int_t AliAttrib::GetEdgeValue(Int_t j) const
961 {
962 // Provide edge value of the j-th (default j=1) attribute slot.
963 // Note : The first attribute slot is at j=1.
964 // In case j is invalid, 0 is returned.
965
966  if (j<1) 
967  {
968   cout << " *AliAttrib::GetEdgeValue* Invalid argument j = " << j << endl;
969   return 0;
970  }
971
972  Int_t edge=0;
973  if (fCalflags)
974  {
975   if (j>0 && j<=(fCalflags->GetSize()))
976   {
977    Int_t word=fCalflags->At(j-1);
978    edge=word/1000;
979   }
980  }
981  return edge;
982 }
983 ///////////////////////////////////////////////////////////////////////////
984 Int_t AliAttrib::GetEdgeValue(TString name) const
985 {
986 // Provide edge value of the name-specified attribute slot.
987 //
988 // This procedure involves a slot-index search based on the specified name
989 // at each invokation. This may become slow in case many slots have been
990 // defined and/or when this procedure is invoked many times.
991 // In such cases it is preferable to use indexed addressing in the user code
992 // either directly or via a few invokations of GetSlotIndex().
993
994  Int_t j=GetSlotIndex(name);
995  Int_t val=0;
996  if (j>0) val=GetEdgeValue(j);
997  return val;
998 }
999 ///////////////////////////////////////////////////////////////////////////
1000 Int_t AliAttrib::GetDeadValue(Int_t j) const
1001 {
1002 // Provide dead value of the j-th (default j=1) attribute slot.
1003 // Note : The first attribute slot is at j=1.
1004 // In case j is invalid, 0 is returned.
1005
1006  if (j<1) 
1007  {
1008   cout << " *AliAttrib::GetDeadValue* Invalid argument j = " << j << endl;
1009   return 0;
1010  }
1011
1012  Int_t dead=0;
1013  if (fCalflags)
1014  {
1015   if (j>0 && j<=(fCalflags->GetSize()))
1016   {
1017    Int_t word=fCalflags->At(j-1);
1018    word=word%1000;
1019    dead=word/100;
1020   }
1021  }
1022  return dead;
1023 }
1024 ///////////////////////////////////////////////////////////////////////////
1025 Int_t AliAttrib::GetDeadValue(TString name) const
1026 {
1027 // Provide dead value of the name-specified attribute slot.
1028 //
1029 // This procedure involves a slot-index search based on the specified name
1030 // at each invokation. This may become slow in case many slots have been
1031 // defined and/or when this procedure is invoked many times.
1032 // In such cases it is preferable to use indexed addressing in the user code
1033 // either directly or via a few invokations of GetSlotIndex().
1034
1035  Int_t j=GetSlotIndex(name);
1036  Int_t val=0;
1037  if (j>0) val=GetDeadValue(j);
1038  return val;
1039 }
1040 ///////////////////////////////////////////////////////////////////////////
1041 void AliAttrib::SetSlotName(TString s,Int_t j)
1042 {
1043 // Set a user defined name for the j-th (default j=1) slot. 
1044 // Note : The first attribute slot is at j=1.
1045
1046  if (j<1) 
1047  {
1048   cout << " *AliAttrib::SetSlotName* Invalid argument j = " << j << endl;
1049   return;
1050  }
1051
1052  if (!fNames)
1053  {
1054   fNames=new TObjArray(j);
1055   fNames->SetOwner();
1056  }
1057
1058  if (j>fNames->GetSize()) fNames->Expand(j);
1059
1060  TObjString* so=(TObjString*)fNames->At(j-1);
1061  if (!so)
1062  {
1063   so=new TObjString(s.Data());
1064   fNames->AddAt(so,j-1);
1065  }
1066  else
1067  {
1068   so->SetString(s);
1069  }
1070 }
1071 ///////////////////////////////////////////////////////////////////////////
1072 TString AliAttrib::GetSlotName(Int_t j) const
1073 {
1074 // Provide the user defined name for the j-th (default j=1) slot. 
1075 // Note : The first attribute slot is at j=1.
1076
1077  TString s="";
1078  if (j<1) 
1079  {
1080   cout << " *AliAttrib::GetSlotName* Invalid argument j = " << j << endl;
1081   return s;
1082  }
1083
1084  if (fNames)
1085  {
1086   if (j<=fNames->GetSize())
1087   {
1088    TObjString* so=(TObjString*)fNames->At(j-1);
1089    if (so) s=so->GetString();
1090   }
1091  }
1092  return s;
1093 }
1094 ///////////////////////////////////////////////////////////////////////////
1095 Int_t AliAttrib::GetSlotIndex(TString name) const
1096 {
1097 // Provide the slot index for the matching name.
1098 // If no matching name is found, 0 is returned.
1099 // Note : The first attribute slot is at j=1.
1100
1101  Int_t index=0;
1102
1103  if (fNames)
1104  {
1105   TString s;
1106   Int_t size=fNames->GetSize();
1107   for (Int_t i=0; i<size; i++)
1108   {
1109    TObjString* so=(TObjString*)fNames->At(i);
1110    if (so) s=so->GetString();
1111    if (s==name)
1112    {
1113     index=i+1;
1114     break;
1115    }
1116   }
1117  }
1118  return index;
1119 }
1120 ///////////////////////////////////////////////////////////////////////////
1121 void AliAttrib::List(Int_t j) const
1122 {
1123 // Provide attribute information for the j-th slot.
1124 // The first slot is at j=1.
1125 // In case j=0 (default) the data of all slots will be listed.
1126
1127  if (j<0) 
1128  {
1129   cout << " *AliAttrib::Data* Invalid argument j = " << j << endl;
1130   return;
1131  }
1132
1133  if (j>0)
1134  {
1135   if (GetGainFlag(j)) cout << " gain : " << GetGain(j);
1136   if (GetOffsetFlag(j)) cout << " offset : " << GetOffset(j);
1137   if (GetEdgeValue(j)) cout << " edge : " << GetEdgeValue(j);
1138   if (GetDeadValue(j)) cout << " dead : " << GetDeadValue(j);
1139   if (GetCalFunction(j)) cout << " *Fcalib*";
1140   if (GetDecalFunction(j)) cout << " *Fdecalib*";
1141   TString s=GetSlotName(j);
1142   if (s!="") cout << " name : " << s.Data();
1143  }
1144  else
1145  {
1146   Int_t ng=GetNgains();
1147   Int_t no=GetNoffsets();
1148   Int_t nf=0;
1149   if (fCalflags) nf=fCalflags->GetSize();
1150   Int_t nn=GetNnames();
1151   Int_t n=ng;
1152   if (n<no) n=no;
1153   if (n<nn) n=nn;
1154   if (n<nf) n=nf;
1155   Int_t printf=0;
1156   TString s;
1157   for (Int_t i=1; i<=n; i++)
1158   {
1159    printf=0;
1160    if (GetGainFlag(i))      {cout << " gain : " << GetGain(i); printf=1;}
1161    if (GetOffsetFlag(i))    {cout << " offset : " << GetOffset(i); printf=1;}
1162    if (GetEdgeValue(i))     {cout << " edge : " << GetEdgeValue(i); printf=1;}
1163    if (GetDeadValue(i))     {cout << " dead : " << GetDeadValue(i); printf=1;}
1164    if (GetCalFunction(i))   {cout << " *Fcalib*"; printf=1;}
1165    if (GetDecalFunction(i)) {cout << " *Fdecalib*"; printf=1;}
1166    s=GetSlotName(i);
1167    if (s!="") {cout << " name : " << s.Data(); printf=1;}
1168    if (printf) cout << endl;
1169   }
1170  }
1171
1172 ///////////////////////////////////////////////////////////////////////////
1173 void AliAttrib::List(TString name) const
1174 {
1175 // Provide attribute information for the name-specified slot.
1176 //
1177 // This procedure involves a slot-index search based on the specified name
1178 // at each invokation. This may become slow in case many slots have been
1179 // defined and/or when this procedure is invoked many times.
1180 // In such cases it is preferable to use indexed addressing in the user code
1181 // either directly or via a few invokations of GetSlotIndex().
1182
1183  Int_t j=GetSlotIndex(name);
1184  if (j>0) List(j);
1185 }
1186 ///////////////////////////////////////////////////////////////////////////
1187 void AliAttrib::Load(AliAttrib& a,Int_t j)
1188 {
1189 // Load attributes of the j-th slot of the input AliAttrib into this AliAttrib object.
1190 // 
1191 // Note : if j=0, then all attributes of all slots are loaded
1192 //
1193 // The default is j=0.
1194
1195  if (j<0) 
1196  {
1197   cout << " *AliAttrib::Load* Invalid argument j = " << j << endl;
1198   return;
1199  }
1200
1201  Int_t n=0;
1202
1203  if (j==0) // load attributes for all slots
1204  {
1205   n=a.GetNgains();
1206   for (Int_t ig=1; ig<=n; ig++)
1207   {
1208    if (a.GetGainFlag(ig))
1209    {
1210     SetGain(a.GetGain(ig),ig);
1211    }
1212    else
1213    {
1214     ResetGain(ig);
1215    }
1216   }
1217   n=a.GetNoffsets();
1218   for (Int_t io=1; io<=n; io++)
1219   {
1220    if (a.GetOffsetFlag(io))
1221    {
1222     SetOffset(a.GetOffset(io),io);
1223    }
1224    else
1225    {
1226     ResetOffset(io);
1227    }
1228   }
1229   n=a.GetNcalflags();
1230   for (Int_t ic=1; ic<=n; ic++)
1231   {
1232    SetEdgeValue(a.GetEdgeValue(ic),ic);
1233    if (a.GetDeadValue(ic))
1234    {
1235     SetDead(ic);
1236    }
1237    else
1238    {
1239     SetAlive(ic);
1240    }
1241   }
1242   n=a.GetNnames();
1243   TString s;
1244   for (Int_t in=1; in<=n; in++)
1245   {
1246    s=a.GetSlotName(in);
1247    SetSlotName(s,in);
1248   }
1249   n=a.GetNcalfuncs();
1250   for (Int_t icalf=1; icalf<=n; icalf++)
1251   {
1252    TF1* f=a.GetCalFunction(icalf);
1253    SetCalFunction(f,icalf);
1254   }
1255   n=a.GetNdecalfuncs();
1256   for (Int_t idecalf=1; idecalf<=n; idecalf++)
1257   {
1258    TF1* f=a.GetDecalFunction(idecalf);
1259    SetDecalFunction(f,idecalf);
1260   }
1261  }
1262  else // load attributes for specified j-th slot only
1263  {
1264   n=a.GetNgains();
1265   if (j<=n)
1266   {
1267    if (a.GetGainFlag(j))
1268    {
1269     SetGain(a.GetGain(j),j);
1270    }
1271    else
1272    {
1273     ResetGain(j);
1274    }
1275   }
1276   n=a.GetNoffsets();
1277   if (j<=n)
1278   {
1279    if (a.GetOffsetFlag(j))
1280    {
1281     SetOffset(a.GetOffset(j),j);
1282    }
1283    else
1284    {
1285     ResetOffset(j);
1286    } 
1287   }
1288   n=a.GetNcalflags();
1289   if (j<=n)
1290   {
1291    SetEdgeValue(a.GetEdgeValue(j),j);
1292    if (a.GetDeadValue(j))
1293    {
1294     SetDead(j);
1295    }
1296    else
1297    {
1298     SetAlive(j);
1299    }
1300   }
1301   n=a.GetNnames();
1302   TString s;
1303   if (j<=n)
1304   {
1305    s=a.GetSlotName(j);
1306    SetSlotName(s,j);
1307   }
1308   n=a.GetNcalfuncs();
1309   if (j<=n)
1310   {
1311    TF1* f=a.GetCalFunction(j);
1312    SetCalFunction(f,j);
1313   }
1314   n=a.GetNdecalfuncs();
1315   if (j<=n)
1316   {
1317    TF1* f=a.GetDecalFunction(j);
1318    SetDecalFunction(f,j);
1319   }
1320  }
1321 }
1322 ///////////////////////////////////////////////////////////////////////////
1323 void AliAttrib::Load(AliAttrib& a,TString name)
1324 {
1325 // Load attributes of the name-specified slot of the input AliAttrib into
1326 // this AliAttrib object.
1327 //
1328 // This procedure involves a slot-index search based on the specified name
1329 // at each invokation. This may become slow in case many slots have been
1330 // defined and/or when this procedure is invoked many times.
1331 // In such cases it is preferable to use indexed addressing in the user code
1332 // either directly or via a few invokations of GetSlotIndex().
1333
1334  Int_t j=GetSlotIndex(name);
1335  if (j>0) Load(a,j);
1336 }
1337 ///////////////////////////////////////////////////////////////////////////
1338 Int_t AliAttrib::GetNcalfuncs() const
1339 {
1340 // Provide the number of specified calib. functions for this attribute.
1341
1342  Int_t n=0;
1343  if (fCalfuncs) n=fCalfuncs->GetSize();
1344  return n;
1345 }
1346 ///////////////////////////////////////////////////////////////////////////
1347 Int_t AliAttrib::GetNdecalfuncs() const
1348 {
1349 // Provide the number of specified de-calib. functions for this attribute.
1350
1351  Int_t n=0;
1352  if (fDecalfuncs) n=fDecalfuncs->GetSize();
1353  return n;
1354 }
1355 ///////////////////////////////////////////////////////////////////////////
1356 TF1* AliAttrib::GetCalFunction(Int_t j) const
1357 {
1358 // Provide pointer to the calib. function of the j-th (default j=1) slot.
1359 // Note : The first attribute slot is at j=1.
1360
1361  TF1* f=0;
1362  if (j>0 && j<=GetNcalfuncs()) f=(TF1*)fCalfuncs->At(j-1);
1363  return f;
1364 }
1365 ///////////////////////////////////////////////////////////////////////////
1366 TF1* AliAttrib::GetCalFunction(TString name) const
1367 {
1368 // Provide pointer to the calib. function of the name-specified slot.
1369 // In case no match is found, zero is returned.
1370
1371  TF1* f=0;
1372  Int_t j=GetSlotIndex(name);
1373  if (j>0) f=GetCalFunction(j);
1374  return f;
1375 }
1376 ///////////////////////////////////////////////////////////////////////////
1377 void AliAttrib::SetCalFunction(TF1* f,Int_t j)
1378 {
1379 // Set the calib. function of the j-th (default j=1) slot.
1380 // Note : The first attribute slot is at j=1.
1381 //
1382 // In case the value of the index j exceeds the maximum number of reserved
1383 // positions for the functions, the number of reserved positions for the functions
1384 // is increased automatically.
1385 //
1386 // In case the function pointer argument has the same value as the current function
1387 // pointer value, no action is taken since the user has already modified the actual
1388 // function.
1389 //
1390 // In case the function pointer argument is zero, the current function
1391 // is deleted and the pointer set to zero.
1392 //
1393 // In all other cases the current function is deleted and a new
1394 // copy of the input function is created which becomes the current function.
1395
1396  if (j<1) return;
1397
1398  if (!fCalfuncs)
1399  {
1400   fCalfuncs=new TObjArray(j);
1401   fCalfuncs->SetOwner();
1402  }
1403
1404  if (j > fCalfuncs->GetSize()) fCalfuncs->Expand(j);
1405
1406  TF1* fcur=(TF1*)fCalfuncs->At(j-1);
1407  if (f != fcur)
1408  {
1409   if (fcur)
1410   {
1411    fCalfuncs->Remove(fcur);
1412    delete fcur;
1413    fcur=0;
1414   }
1415   if (f)
1416   {
1417    fcur=new TF1(*f);
1418    fCalfuncs->AddAt(fcur,j-1);
1419   }
1420  } 
1421 }
1422 ///////////////////////////////////////////////////////////////////////////
1423 void AliAttrib::SetCalFunction(TF1* f,TString name)
1424 {
1425 // Set the calib. function of the name-specified slot.
1426 //
1427 // In case the function pointer argument has the same value as the current function
1428 // pointer value, no action is taken since the user has already modified the actual
1429 // function.
1430 //
1431 // In case the function pointer argument is zero, the current function
1432 // is deleted and the pointer set to zero.
1433 //
1434 // In all other cases the current function is deleted and a new
1435 // copy of the input function is created which becomes the current function.
1436
1437  Int_t j=GetSlotIndex(name);
1438  if (j>0) SetCalFunction(f,j);
1439 }
1440 ///////////////////////////////////////////////////////////////////////////
1441 TF1* AliAttrib::GetDecalFunction(Int_t j) const
1442 {
1443 // Provide pointer to the de-calib. function of the j-th (default j=1) slot.
1444 // Note : The first attribute slot is at j=1.
1445
1446  TF1* f=0;
1447  if (j>0 && j<=GetNdecalfuncs()) f=(TF1*)fDecalfuncs->At(j-1);
1448  return f;
1449 }
1450 ///////////////////////////////////////////////////////////////////////////
1451 TF1* AliAttrib::GetDecalFunction(TString name) const
1452 {
1453 // Provide pointer to the de-calib. function of the name-specified slot.
1454 // In case no match is found, zero is returned.
1455
1456  TF1* f=0;
1457  Int_t j=GetSlotIndex(name);
1458  if (j>0) f=GetDecalFunction(j);
1459  return f;
1460 }
1461 ///////////////////////////////////////////////////////////////////////////
1462 void AliAttrib::SetDecalFunction(TF1* f,Int_t j)
1463 {
1464 // Set the de-calib. function of the j-th (default j=1) slot.
1465 // Note : The first attribute slot is at j=1.
1466 //
1467 // In case the value of the index j exceeds the maximum number of reserved
1468 // positions for the functions, the number of reserved positions for the functions
1469 // is increased automatically.
1470 //
1471 // In case the function pointer argument has the same value as the current function
1472 // pointer value, no action is taken since the user has already modified the actual
1473 // function.
1474 //
1475 // In case the function pointer argument is zero, the current function
1476 // is deleted and the pointer set to zero.
1477 //
1478 // In all other cases the current function is deleted and a new
1479 // copy of the input function is created which becomes the current function.
1480
1481  if (j<1) return;
1482
1483  if (!fDecalfuncs)
1484  {
1485   fDecalfuncs=new TObjArray(j);
1486   fDecalfuncs->SetOwner();
1487  }
1488
1489  if (j > fDecalfuncs->GetSize()) fDecalfuncs->Expand(j);
1490
1491  TF1* fcur=(TF1*)fDecalfuncs->At(j-1);
1492  if (f != fcur)
1493  {
1494   if (fcur)
1495   {
1496    fDecalfuncs->Remove(fcur);
1497    delete fcur;
1498    fcur=0;
1499   }
1500   if (f)
1501   {
1502    fcur=new TF1(*f);
1503    fDecalfuncs->AddAt(fcur,j-1);
1504   }
1505  } 
1506 }
1507 ///////////////////////////////////////////////////////////////////////////
1508 void AliAttrib::SetDecalFunction(TF1* f,TString name)
1509 {
1510 // Set the de-calib. function of the name-specified slot.
1511 //
1512 // In case the function pointer argument has the same value as the current function
1513 // pointer value, no action is taken since the user has already modified the actual
1514 // function.
1515 //
1516 // In case the function pointer argument is zero, the current function
1517 // is deleted and the pointer set to zero.
1518 //
1519 // In all other cases the current function is deleted and a new
1520 // copy of the input function is created which becomes the current function.
1521
1522  Int_t j=GetSlotIndex(name);
1523  if (j>0) SetDecalFunction(f,j);
1524 }
1525 ///////////////////////////////////////////////////////////////////////////