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