Put 0.1 as minimal value of the gas gain (Raphaelle)
[u/mrichter/AliRoot.git] / TRD / AliTRDptrgParam.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 //                                                                        
20 //  Parameters for Pre-Trigger Simulation                                 
21 //                                                                        
22 //  Author: F. Reidt (Felix.Reidt@cern.ch)                                
23 //               
24 //  This class controls the parameters used by the pretrigger simulation.
25 //  A configuration file ca be loaded by calling LoadConfigurationFromFile()
26 //  The generation of look up tables is also done in this class and has to
27 //  be done only once after a configuration file was loaded.
28 //  If no configuration file was loaded, the standard
29 //  configuration in LoadStandardConfiguration() would be used.
30 //                                                        
31 ////////////////////////////////////////////////////////////////////////////
32 #include "TArrayI.h"
33 #include "TObjString.h"
34 #include "TString.h"
35
36 #include <fstream>
37
38 #include "AliLog.h"
39
40 #include "AliTRDptrgParam.h"
41
42 ClassImp(AliTRDptrgParam)
43
44 AliTRDptrgParam *AliTRDptrgParam::fgInstance = 0;
45
46
47 //______________________________________________________________________________
48 AliTRDptrgParam::AliTRDptrgParam()
49   : TObject(),
50     fTLMUInputStretch(0),
51     fTLMUcmatrices(0x0),
52     fTLMUmultiplicity(0x0), 
53     fTLMUoutput(0x0),
54     fFEBT0Thresholds(0x0),
55     fFEBT0Multiplicities(0x0),
56     fFEBT0LUTs(0x0),
57     fFEBV0Thresholds(0x0),
58     fFEBV0Multiplicities(0x0),
59     fFEBV0LUTs(0x0),
60     fCBLUTs(0x0),
61     fPTmasks(AliTRDptrgPTmasks())
62 {
63   // ctor
64   
65   // initialize coincidence matrices
66   this->fTLMUcmatrices = new UInt_t*[3];
67   for (UInt_t iMatrix = 0; iMatrix < 3; iMatrix++) {
68     this->fTLMUcmatrices[iMatrix] = new UInt_t[18];
69     for (UInt_t iSlice = 0; iSlice < 18; iSlice++) {
70       this->fTLMUcmatrices[iMatrix][iSlice] = 0;
71     }
72   }
73   
74   // initialize multiplicity slices
75   this->fTLMUmultiplicity = new UInt_t*[9];
76   for (UInt_t iSlice = 0; iSlice < 9; iSlice++) {
77     this->fTLMUmultiplicity[iSlice] = new UInt_t[2];
78     this->fTLMUmultiplicity[iSlice][0] = 577; // disabled
79     this->fTLMUmultiplicity[iSlice][1] = 0;
80   }
81   
82   // initialize output muxer
83   this->fTLMUoutput = new Int_t*[8];
84   for (UInt_t iBit = 0; iBit < 8; iBit++) {
85     this->fTLMUoutput[iBit] = new Int_t[2];
86     this->fTLMUoutput[iBit][0] = -1; // cmatrix disabled
87     this->fTLMUoutput[iBit][1] = -1; // multslice disabled
88   }
89   
90   // initialize T0 FEB thresholds
91   this->fFEBT0Thresholds = new UInt_t*[2];
92   this->fFEBT0Thresholds[0] = new UInt_t[12];
93   this->fFEBT0Thresholds[1] = new UInt_t[12];
94   for (Int_t iChan = 0; iChan < 12; iChan++) {
95     this->fFEBT0Thresholds[0][iChan] = 4294967295U; 
96     this->fFEBT0Thresholds[1][iChan] = 4294967295U;
97     // writing 2^32-1 disables the input because all used adcs have 
98     // less than 32 bits
99   }
100   
101   // initialize T0 Multiplicity
102   this->fFEBT0Multiplicities = new UInt_t**[2];
103   this->fFEBT0Multiplicities[0] = new UInt_t*[2];
104   this->fFEBT0Multiplicities[1] = new UInt_t*[2];
105   this->fFEBT0Multiplicities[0][0] = new UInt_t[2];
106   this->fFEBT0Multiplicities[0][1] = new UInt_t[2];
107   this->fFEBT0Multiplicities[1][0] = new UInt_t[2];
108   this->fFEBT0Multiplicities[1][1] = new UInt_t[2];
109   this->fFEBT0Multiplicities[0][0][0] = 4294967295U;
110   this->fFEBT0Multiplicities[0][0][1] = 4294967295U;
111   this->fFEBT0Multiplicities[0][1][0] = 4294967295U;
112   this->fFEBT0Multiplicities[0][1][1] = 4294967295U;
113   this->fFEBT0Multiplicities[1][0][0] = 4294967295U;
114   this->fFEBT0Multiplicities[1][0][1] = 4294967295U;
115   this->fFEBT0Multiplicities[1][1][0] = 4294967295U;
116   this->fFEBT0Multiplicities[1][1][1] = 4294967295U;
117   // writing 2^32-1 disables the input because all used adcs have 
118   // less than 32 bits
119
120   // initialize T0 LUTs
121   // this->fFEBT0LUTs = 0x0; (done in member initialization list)
122   // further initialization is done in AliTRDptrgParam::GenerateLUTs()
123   
124
125   // initialize V0 FEB Thresholds
126   this->fFEBV0Thresholds = new UInt_t**[2];
127   for (UInt_t iPosition = 0; iPosition < 2; iPosition++) {
128     this->fFEBV0Thresholds[iPosition] = new UInt_t*[4];
129     for (UInt_t iCard = 0; iCard < 4; iCard++) {
130       this->fFEBV0Thresholds[iPosition][iCard] = new UInt_t[8];
131       for (UInt_t iChannel = 0; iChannel < 8; iChannel++) {
132         this->fFEBV0Thresholds[iPosition][iCard][iChannel] = 4294967295U;
133       }
134     }
135   }
136  
137   // initialize V0 Multiplicities
138   this->fFEBV0Multiplicities = new UInt_t***[2];
139   for (UInt_t iPosition = 0; iPosition < 2; iPosition++) {
140     this->fFEBV0Multiplicities[iPosition] = new UInt_t**[4];
141     for (UInt_t iCard = 0; iCard < 4; iCard++) {
142       this->fFEBV0Multiplicities[iPosition][iCard] = new UInt_t*[2];
143       for (UInt_t iLUT = 0; iLUT < 2; iLUT++) {
144         this->fFEBV0Multiplicities[iPosition][iCard][iLUT] = new UInt_t[2];
145         this->fFEBV0Multiplicities[iPosition][iCard][iLUT][0] = 4294967295U;
146         this->fFEBV0Multiplicities[iPosition][iCard][iLUT][1] = 0x0;      
147       }
148     }
149   }
150   
151   // initialize V0 LUTs
152   //  this->fFEBV0LUTs = 0x0; (done in member initialization list)
153   // further initialization is done in AliTRDptrgParam::GenerateLUTs()
154
155   // initialize CB LUTs
156   // this->fCBLUTs = 0x0; (done in member initialization list)
157   // further initialization is done in AliTRDptrgParam::GenerateLUTs()
158
159   this->LoadStandardConfiguration(); // load standard configuration
160 }
161
162 //______________________________________________________________________________
163 AliTRDptrgParam::~AliTRDptrgParam() 
164 {
165   // dtor
166   
167   // delete coincidence matrices
168   if (this->fTLMUcmatrices != 0x0) {
169     for (UInt_t iMatrix = 0; iMatrix < 3; iMatrix++) {
170       if (this->fTLMUcmatrices[iMatrix] != 0x0) {
171         delete[] this->fTLMUcmatrices[iMatrix];
172         this->fTLMUcmatrices[iMatrix] = 0x0;
173       }
174     }
175     delete[] this->fTLMUcmatrices;
176     this->fTLMUcmatrices = 0x0;
177   }
178   
179   // delete multiplicity slices
180   if (this->fTLMUmultiplicity != 0x0) {
181     for (UInt_t iSlice = 0; iSlice < 9; iSlice++) {
182       if (this->fTLMUmultiplicity[iSlice] != 0x0) {
183         delete[] this->fTLMUmultiplicity[iSlice];
184         this->fTLMUmultiplicity[iSlice] = 0x0;
185       }
186     }
187     delete[] this->fTLMUmultiplicity;
188     this->fTLMUmultiplicity = 0x0;
189   }
190
191   // delete output mux
192   if (this->fTLMUoutput != 0x0) {
193     for (UInt_t iBit = 0; iBit < 8; iBit++) {
194       if (this->fTLMUoutput[iBit] != 0x0) {
195         delete[] this->fTLMUoutput[iBit];
196         this->fTLMUoutput[iBit] = 0x0;
197       }
198     }
199     delete[] this->fTLMUoutput;
200     this->fTLMUoutput = 0x0;
201   }
202
203   // delete T0 FEB thresholds
204   if (this->fFEBT0Thresholds != 0x0) {
205     if (this->fFEBT0Thresholds[0] != 0x0) {
206       delete[] this->fFEBT0Thresholds[0];
207       this->fFEBT0Thresholds[0] = 0x0;
208     }
209     if (this->fFEBT0Thresholds[1] != 0x0) {
210       delete[] this->fFEBT0Thresholds[1];
211       this->fFEBT0Thresholds[1] = 0x0;
212     }
213     delete[] this->fFEBT0Thresholds;
214     this->fFEBT0Thresholds = 0x0;
215   }
216  
217   // delete T0 multiplicities
218   if (this->fFEBT0Multiplicities != 0x0) {
219     for (UInt_t iPosition = 0; iPosition < 2; iPosition++) {
220       if (this->fFEBT0Multiplicities[iPosition] != 0x0) {
221         for (UInt_t iLUT = 0; iLUT < 2; iLUT++) {
222           if (this->fFEBT0Multiplicities[iPosition][iLUT] != 0x0) {
223             delete[] this->fFEBT0Multiplicities[iPosition][iLUT];
224             this->fFEBT0Multiplicities[iPosition][iLUT] = 0x0;
225           }
226         }
227         delete[] this->fFEBT0Multiplicities[iPosition];
228         this->fFEBT0Multiplicities[iPosition] = 0x0;
229       }
230     }
231     delete[] this->fFEBT0Multiplicities;
232     this->fFEBT0Multiplicities = 0x0;
233   }  
234
235   // delete T0 LUTs
236   if (this->fFEBT0LUTs != 0x0) {
237     for (UInt_t iPosition = 0; iPosition < 2; iPosition++) {
238       if (this->fFEBT0LUTs[iPosition] != 0x0) {
239         for (UInt_t iLUT = 0; iLUT < 2; iLUT++) {
240           if (this->fFEBT0LUTs[iPosition][iLUT] != 0x0) {
241             delete[] this->fFEBT0LUTs[iPosition][iLUT];
242             this->fFEBT0LUTs[iPosition][iLUT] = 0x0;
243           }
244         }
245         delete[] this->fFEBT0LUTs[iPosition];
246         this->fFEBT0LUTs[iPosition] = 0x0;
247       }
248     }
249     delete[] this->fFEBT0LUTs;
250     this->fFEBT0LUTs = 0x0;
251   }  
252
253   // delete V0 FEB thresholds
254   if (this->fFEBV0Thresholds != 0x0) {
255     for (UInt_t iPosition = 0; iPosition < 2; iPosition++) {
256       if (this->fFEBV0Thresholds[iPosition] != 0x0) {
257         for (UInt_t iCard = 0; iCard < 4; iCard++) {
258           if (this->fFEBV0Thresholds[iPosition][iCard] != 0x0) {
259             delete[] this->fFEBV0Thresholds[iPosition][iCard];
260             this->fFEBV0Thresholds[iPosition][iCard] = 0x0;
261           }
262         }
263         delete[] this->fFEBV0Thresholds[iPosition]; 
264         this->fFEBV0Thresholds[iPosition] = 0x0;
265       }
266     }
267     delete[] this->fFEBV0Thresholds;
268     this->fFEBV0Thresholds = 0x0;
269   }
270
271   // delete V0 multiplicities
272   if (this->fFEBV0Multiplicities != 0x0) {
273     for (UInt_t iPosition = 0; iPosition < 2; iPosition++) {
274       if (this->fFEBV0Multiplicities[iPosition] != 0x0) {
275         for (UInt_t iCard = 0; iCard < 4; iCard++) {
276           if (this->fFEBV0Multiplicities[iPosition][iCard] != 0x0) {
277             for (UInt_t iLUT = 0; iLUT < 2; iLUT++) {
278               if (this->fFEBV0Multiplicities[iPosition][iCard][iLUT] != 0x0) {
279                 delete[] this->fFEBV0Multiplicities[iPosition][iCard][iLUT];
280                 this->fFEBV0Multiplicities[iPosition][iCard][iLUT] = 0x0;
281               }
282             }
283             delete[] this->fFEBV0Multiplicities[iPosition][iCard];
284             this->fFEBV0Multiplicities[iPosition][iCard] = 0x0;
285           }
286         }
287         delete[] this->fFEBV0Multiplicities[iPosition]; 
288         this->fFEBV0Multiplicities[iPosition] = 0x0;
289       }
290     }
291     delete[] this->fFEBV0Multiplicities;
292     this->fFEBV0Multiplicities = 0x0;
293   } 
294
295   // delete V0 LUTs
296   if (this->fFEBV0LUTs != 0x0) {
297     for (UInt_t iPosition = 0; iPosition < 2; iPosition++) {
298       if (this->fFEBV0LUTs[iPosition] != 0x0) {
299         for (UInt_t iCard = 0; iCard < 4; iCard++) {
300           if (this->fFEBV0LUTs[iPosition][iCard] != 0x0) {
301             for (UInt_t iLUT = 0; iLUT < 2; iLUT++) {
302               if (this->fFEBV0LUTs[iPosition][iCard][iLUT] != 0x0) {
303                 delete[] this->fFEBV0LUTs[iPosition][iCard][iLUT];
304                 this->fFEBV0LUTs[iPosition][iCard][iLUT] = 0x0;
305               }
306             }
307             delete[] this->fFEBV0LUTs[iPosition][iCard];
308             this->fFEBV0LUTs[iPosition][iCard] = 0x0;
309           }
310         }
311         delete[] this->fFEBV0LUTs[iPosition]; 
312         this->fFEBV0LUTs[iPosition] = 0x0;
313       }
314     }
315     delete[] this->fFEBV0LUTs;
316     this->fFEBV0LUTs = 0x0;
317   } 
318
319   // delete CB LUTs
320   if (this->fCBLUTs != 0x0) {
321     for (UInt_t iCB = 0; iCB < 3; iCB++) {
322       if (this->fCBLUTs[iCB] != 0x0) {
323         for (UInt_t iLUT = 0; iLUT < 2; iLUT++) {
324           if (this->fCBLUTs[iCB][iLUT] != 0x0) {
325             delete[] this->fCBLUTs[iCB][iLUT];
326             this->fCBLUTs[iCB][iLUT] = 0x0;
327           }
328         }
329         if (iCB == kB) {
330           // CB-B has 3 LUTs!
331           if (this->fCBLUTs[iCB][2] != 0x0) {
332             delete[] this->fCBLUTs[iCB][2];
333             this->fCBLUTs[iCB][2] = 0x0;
334           }
335         }
336         delete[] this->fCBLUTs[iCB];
337         this->fCBLUTs[iCB] = 0x0;
338       }
339     }
340     delete[] this->fCBLUTs;
341     this->fCBLUTs = 0x0;
342   }  
343 }
344
345 //______________________________________________________________________________
346 Int_t AliTRDptrgParam::CheckVariables() const
347 {
348   // checks whether variables are deleted early enough
349  
350   // check coincidence matrices
351   if (this->fTLMUcmatrices != 0x0) {
352     for (UInt_t iMatrix = 0; iMatrix < 3; iMatrix++) {
353       if (this->fTLMUcmatrices[iMatrix] == 0x0) {
354         return -1;
355       }
356     }
357   }
358   else {
359     return -2;
360   }
361   
362   // check multiplicity slices
363   if (this->fTLMUmultiplicity != 0x0) {
364     for (UInt_t iSlice = 0; iSlice < 9; iSlice++) {
365       if (this->fTLMUmultiplicity[iSlice] == 0x0) {
366         return -3;
367       }
368     }
369   }
370   else {
371     return -4;
372   }
373
374   // check output mux
375   if (this->fTLMUoutput != 0x0) {
376     for (UInt_t iBit = 0; iBit < 8; iBit++) {
377       if (this->fTLMUoutput[iBit] == 0x0) {
378         return -5;
379       }
380     }
381   }
382   else {
383     return -6;
384   }
385
386   // check T0 FEB thresholds
387   if (this->fFEBT0Thresholds != 0x0) {
388     if (this->fFEBT0Thresholds[0] == 0x0) {
389       return -7;
390     }
391     if (this->fFEBT0Thresholds[1] == 0x0) {
392       return -8;
393     }
394   }
395   else {
396     return -9;
397   }
398
399   // check T0 multiplicities
400   if (this->fFEBT0Multiplicities != 0x0) {
401     for (UInt_t iPosition = 0; iPosition < 2; iPosition++) {
402       if (this->fFEBT0Multiplicities[iPosition] != 0x0) {
403         for (UInt_t iLUT = 0; iLUT < 2; iLUT++) {
404           if (this->fFEBT0Multiplicities[iPosition][iLUT] == 0x0) {
405             return -10;
406           }
407         }
408       }
409       else {
410         return -11;
411       }
412     }
413   }
414   else {
415     return -12;
416   }
417   
418
419   // check T0 LUTs
420   if (this->fFEBT0LUTs != 0x0) {
421     for (UInt_t iPosition = 0; iPosition < 2; iPosition++) {
422       if (this->fFEBT0LUTs[iPosition] != 0x0) {
423         for (UInt_t iLUT = 0; iLUT < 2; iLUT++) {
424           if (this->fFEBT0LUTs[iPosition][iLUT] == 0x0) {
425             return -13;
426           }
427         }
428       }
429       else {
430         return -14;
431       }
432     }
433   }  
434   else {
435     return -15;
436   }
437
438   // check V0 FEB thresholds
439   if (this->fFEBV0Thresholds != 0x0) {
440     for (UInt_t iPosition = 0; iPosition < 2; iPosition++) {
441       if (this->fFEBV0Thresholds[iPosition] != 0x0) {
442         for (UInt_t iCard = 0; iCard < 4; iCard++) {
443           if (this->fFEBV0Thresholds[iPosition][iCard] == 0x0) {
444             return -16;
445           }
446         }
447       }
448       else {
449         return -17;
450       }
451     }
452   }
453   else {
454     return -18;
455   }
456
457   // check V0 multiplicities
458   if (this->fFEBV0Multiplicities != 0x0) {
459     for (UInt_t iPosition = 0; iPosition < 2; iPosition++) {
460       if (this->fFEBV0Multiplicities[iPosition] != 0x0) {
461         for (UInt_t iCard = 0; iCard < 4; iCard++) {
462           if (this->fFEBV0Multiplicities[iPosition][iCard] != 0x0) {
463             for (UInt_t iLUT = 0; iLUT < 2; iLUT++) {
464               if (this->fFEBV0Multiplicities[iPosition][iCard][iLUT] == 0x0) {
465                 return -19;
466               }
467             }
468           }
469           else {
470             return -20;
471           }
472         }
473       }
474       else {
475         return -21;
476       }
477     }
478   } 
479   else {
480     return -22;
481   }
482
483   // check V0 LUTs
484   if (this->fFEBV0LUTs != 0x0) {
485     for (UInt_t iPosition = 0; iPosition < 2; iPosition++) {
486       if (this->fFEBV0LUTs[iPosition] != 0x0) {
487         for (UInt_t iCard = 0; iCard < 4; iCard++) {
488           if (this->fFEBV0LUTs[iPosition][iCard] != 0x0) {
489             for (UInt_t iLUT = 0; iLUT < 2; iLUT++) {
490               if (this->fFEBV0LUTs[iPosition][iCard][iLUT] == 0x0) {
491                 return -23;
492               }
493             }
494           }
495           else {
496             return -24;
497           }
498         }
499       }
500       else {
501         return -25;
502       }
503     }
504   } 
505   else {
506     return -26;
507   }
508
509   // check CB LUTs
510   if (this->fCBLUTs != 0x0) {
511     for (UInt_t iCB = 0; iCB < 3; iCB++) {
512       if (this->fCBLUTs[iCB] != 0x0) {
513         for (UInt_t iLUT = 0; iLUT < 2; iLUT++) {
514           if (this->fCBLUTs[iCB][iLUT] == 0x0) {
515             return -27;
516           }
517         }
518         if (iCB == kB) {
519           if (this->fCBLUTs[iCB][2] == 0x0) {
520             return -28;
521           }
522         }
523       }
524       else {
525         return -29;
526       }
527     }
528   }  
529   else {
530     return -30;
531   }
532   return 0;
533 }
534
535 //______________________________________________________________________________
536 AliTRDptrgParam* AliTRDptrgParam::Instance() 
537 {
538   // get (or create) the single instance
539
540   if (fgInstance == 0) 
541     fgInstance = new AliTRDptrgParam();
542
543   return fgInstance;
544 }
545
546 //______________________________________________________________________________
547 void AliTRDptrgParam::Terminate() 
548 {
549   // destruct the instance
550
551   if (fgInstance != 0) {
552     delete fgInstance;
553     fgInstance = 0x0;
554   }
555 }
556
557 //______________________________________________________________________________
558 void AliTRDptrgParam::LoadStandardConfiguration() {
559   // loads a standard configuration parameters for testing 
560
561   // TLMU Input Masks
562   for (UInt_t iSM = 0; iSM < 18; iSM++) {
563     this->fTLMUInputMask[iSM] = 0xFFFFFFFF; // enable all input bits
564   }
565  
566   // TLMU Input Stretch
567   this->fTLMUInputStretch = 0; // not used in simulation
568
569   // TLMU Coincidence Matrices
570   //
571   // Matrix 0: Back-To-Back
572   // Matrix 1: Back-To-Back +/-1
573   // Matrix 2: Back-To-Back +/-2
574   for (UInt_t iMatrix = 0; iMatrix < 3; iMatrix++) {
575     for (UInt_t iSlice = 0; iSlice < 18; iSlice++) {
576       if (iMatrix == 0) {
577         if (iSlice < 9) {
578           this->fTLMUcmatrices[iMatrix][iSlice] = 0x201 << iSlice; 
579           // Back-To-Back 
580           AliDebug(5, Form("fTLMUcmatrices[%d][%d]=0x%x",iMatrix,iSlice,
581                            this->fTLMUcmatrices[iMatrix][iSlice]));
582         }
583         // because of symmetrie the other slices are not necessary
584       } 
585       else if (iMatrix == 1)  {
586         // Back-To-Back +/- 1
587         if (iSlice < 8) {
588           this->fTLMUcmatrices[iMatrix][iSlice] = 0x381 << iSlice;
589         }
590         else if (iSlice == 8) {
591           this->fTLMUcmatrices[iMatrix][iSlice] = 0x30101;
592         }
593         else if (iSlice == 9) {
594           this->fTLMUcmatrices[iMatrix][iSlice] = 0x20203;
595         }
596         else {
597           this->fTLMUcmatrices[iMatrix][iSlice] = 0x407 << (iSlice - 10);
598         } 
599         AliDebug(5, Form("fTLMUcmatrices[%d][%d]=0x%x",iMatrix,iSlice,
600                          this->fTLMUcmatrices[iMatrix][iSlice])); 
601       }
602       else if (iMatrix == 2) {
603         // Back-To-Back +/-2
604         if (iSlice < 7 ) {
605           this->fTLMUcmatrices[iMatrix][iSlice] = 0xF81 << iSlice;
606         }
607         else if (iSlice == 7) {
608           this->fTLMUcmatrices[iMatrix][iSlice] = 0x3C081;
609         }
610         else if (iSlice == 8) {
611           this->fTLMUcmatrices[iMatrix][iSlice] = 0x38103;
612         }
613         else if (iSlice == 9) {
614           this->fTLMUcmatrices[iMatrix][iSlice] = 0x30207;
615         }
616         else if (iSlice == 10) {
617           this->fTLMUcmatrices[iMatrix][iSlice] = 0x2040F;
618         }
619         else {
620           this->fTLMUcmatrices[iMatrix][iSlice] = 0x81F << (iSlice - 11);
621         } 
622         AliDebug(5, Form("fTLMUcmatrices[%d][%d]=0x%x",iMatrix,iSlice,
623                          this->fTLMUcmatrices[iMatrix][iSlice]));     
624       }
625     } 
626   }
627
628   // TLMU Mulitplicity
629   this->fTLMUmultiplicity[0][0] = 0;
630   this->fTLMUmultiplicity[0][1] = 10;
631   this->fTLMUmultiplicity[1][0] = 10;
632   this->fTLMUmultiplicity[1][1] = 25;
633   this->fTLMUmultiplicity[2][0] = 25;
634   this->fTLMUmultiplicity[2][1] = 50;
635   this->fTLMUmultiplicity[3][0] = 50;
636   this->fTLMUmultiplicity[3][1] = 100;
637   this->fTLMUmultiplicity[4][0] = 100;
638   this->fTLMUmultiplicity[4][1] = 200;
639   this->fTLMUmultiplicity[5][0] = 200;
640   this->fTLMUmultiplicity[5][1] = 350;
641   this->fTLMUmultiplicity[6][0] = 350;
642   this->fTLMUmultiplicity[6][1] = 400;
643   this->fTLMUmultiplicity[7][0] = 400;
644   this->fTLMUmultiplicity[7][1] = 576;
645   this->fTLMUmultiplicity[8][0] = 1;
646   this->fTLMUmultiplicity[8][1] = 576;
647  
648   // TLMU output
649   this->fTLMUoutput[0][0] = 0;
650   this->fTLMUoutput[1][0] = 1;
651   this->fTLMUoutput[2][0] = 2;
652   this->fTLMUoutput[3][1] = 0;
653   this->fTLMUoutput[4][1] = 1;
654   this->fTLMUoutput[5][1] = 2;
655   this->fTLMUoutput[6][1] = 3;
656   this->fTLMUoutput[7][1] = 8;
657
658   // T0 FEB Thresholds
659   for (UInt_t iChannel = 0; iChannel < 12; iChannel++) {
660     this->fFEBT0Thresholds[0][iChannel] = 10;
661     this->fFEBT0Thresholds[1][iChannel] = 10;
662   }
663
664   // T0 Multiplicities
665   for (UInt_t iPosition = 0; iPosition < 2; iPosition++) {
666     for (UInt_t iLUT = 0; iLUT < 2; iLUT++) {
667       if (iLUT == 0) {
668         this->fFEBT0Multiplicities[iPosition][iLUT][0] = 0;
669       }
670       else {
671         this->fFEBT0Multiplicities[iPosition][iLUT][0] = 5;
672       }
673       this->fFEBT0Multiplicities[iPosition][iLUT][1] = 0xFFF;
674     }
675   }
676
677   // V0 FEB Thresholds
678   for (UInt_t iPosition = 0; iPosition < 2; iPosition++) {
679     for (UInt_t iCard = 0; iCard < 4; iCard++) {
680       for (UInt_t iChannel = 0; iChannel < 8; iChannel++) {
681         this->fFEBV0Thresholds[iPosition][iCard][iChannel] = 10;
682       }
683     }
684   }
685
686   // V0 Multiplicities
687   for (UInt_t iPosition = 0; iPosition < 2; iPosition++) {
688     for (UInt_t iCard = 0; iCard < 4; iCard++) {
689       for (UInt_t iLUT = 0; iLUT < 2; iLUT++) {
690         if (iLUT == 0) {
691           this->fFEBV0Multiplicities[iPosition][iCard][iLUT][0] = 0;
692         }
693         else {
694           this->fFEBV0Multiplicities[iPosition][iCard][iLUT][0] = 3;
695         }
696         this->fFEBV0Multiplicities[iPosition][iCard][iLUT][1] = 0xFF;
697       }
698     }
699   }
700
701   // CB-A LUT equations
702   this->fCBALUTequ[0] = "T0_0 || (V0-0_0 || V0-1_0 || V0-2_0 || V0-3_0)";
703   this->fCBALUTequ[1] = "!T0_1 && !V0-0_1 && !V0-1_1 && !V0-2_1 && !V0-3_1";
704
705   // CB-C LUT equations
706   this->fCBCLUTequ[0] = "T0_0 || ( V0-0_0 || V0-1_0 || V0-2_0 || V0-3_0 )";
707   this->fCBCLUTequ[1] = "!T0_1 && !V0-0_1 && !V0-1_1 && !V0-2_1 && !V0-3_1";
708
709   // CB-B LUT equations
710   this->fCBBLUTequ[0] = "CB-A_1 && !CB-C_1 && TLMU_7";
711   this->fCBBLUTequ[1] = "!CB-A_1 && CB-C_1 && TLMU_7";
712   this->fCBBLUTequ[2] = "CB-A_1 && CB-C_1 && TLMU_7";
713
714   // PT output mask
715   this->fPTmasks.fLUTs[0] = kTRUE;
716   this->fPTmasks.fLUTs[1] = kTRUE;
717   this->fPTmasks.fLUTs[2] = kTRUE;
718   this->fPTmasks.fCBA[0] = kTRUE;
719   this->fPTmasks.fCBC[0] = kTRUE;
720   for (Int_t i = 1; i < 7; i++) {
721     this->fPTmasks.fTLMU[i] = kTRUE;
722   }
723
724   return;  
725 }
726
727 //______________________________________________________________________________
728 Bool_t AliTRDptrgParam::LoadConfigurationFromFile(TString filename) {
729   // Reads pretrigger configuration file and forwards identifiers and values
730   // to the corresponding parser functions
731   // This method is only checking for certain keywords at the beginning of a
732   // line in the config file
733
734   ifstream inputFile;
735   inputFile.open(filename.Data());
736   TString line;
737   TString identifier;
738   TString value;
739   std::string str;
740
741
742   if (inputFile.is_open())
743   {
744     AliDebug(5, "---- Reading configuration file ----");
745     while (getline(inputFile, str)) {
746       line = str;
747    
748       AliDebug(5, Form("line: %s\n", line.Data()));
749       if (line.Index("TLMU") == 0) {
750         this->PrepareLine(line, identifier, value);
751         if (!this->ParseTLMU(identifier, value)) {
752           return kFALSE;
753         }
754       }
755       else if (line.Index("FEB") == 0) {
756         this->PrepareLine(line, identifier, value);
757         if (!this->ParseFEB(identifier, value)) {
758           return kFALSE;
759         }
760       }
761       else if (line.Index("CBB") == 0) {
762         this->PrepareLine(line, identifier, value);
763         if (!this->ParseCBB(identifier, value)) {
764           return kFALSE;
765         }
766       }
767       else if ((line.Index("CBA") == 0) ||
768                (line.Index("CBC") == 0)) {
769         this->PrepareLine(line, identifier, value);
770         if (!this->ParseCBAC(identifier, value)) {
771           return kFALSE;
772         }
773       }
774     }
775     AliDebug(5, "---- Finished reading configuration file ----");
776     inputFile.close();
777     return kTRUE;
778   }
779   else
780   {
781     AliDebug(5, "Error opening configuration file");
782     return kFALSE;
783   }
784   return kTRUE;
785 }
786
787
788 //______________________________________________________________________________
789 Int_t AliTRDptrgParam::GenerateLUTs() {
790   // generates all LUTs defined inside this object, this schould called only
791   // once, after configuration is loaded in order to save cpu time
792
793   // generation method:
794   // walk through address space
795   // mask address with input mask =>  get multiplicity of masked value
796   // if (multiplicity of masked value) > multiplicity condition
797   // write 1 in LUT
798   
799   // T0
800   this->fFEBT0LUTs = new Int_t**[2]; // 2 A + C side
801   for (UInt_t iPosition = 0; iPosition < 2; iPosition++) {
802     // iPosition = 0 -> A, iPosition = 1 -> C
803     this->fFEBT0LUTs[iPosition] = new Int_t*[2]; // 2 LUTs per side
804     for (UInt_t iLUT = 0; iLUT < 2; iLUT++) {
805       // LUT with 12 input channels 2^12=4096
806       this->fFEBT0LUTs[iPosition][iLUT] = new Int_t[4096];
807       AliDebug(5, Form("Generate FEBT0LUT[%d][%d]: (0x%x)>%d", iPosition, iLUT,
808                        this->fFEBT0Multiplicities[iPosition][iLUT][1],
809                        this->fFEBT0Multiplicities[iPosition][iLUT][0]));
810       for (UInt_t iEntry = 0; iEntry < 4096; iEntry++) {
811         // Check whether that entry belongs to a multiplicity exceeding the 
812         // threshold
813         if (this->GetMultiplicity(iEntry & 
814               this->fFEBT0Multiplicities[iPosition][iLUT][1]) > 
815             this->fFEBT0Multiplicities[iPosition][iLUT][0]) {
816           this->fFEBT0LUTs[iPosition][iLUT][iEntry] = 1;
817         }
818         else {
819           // initialize LUT (not done before !)
820           this->fFEBT0LUTs[iPosition][iLUT][iEntry] = 0;
821         }
822         AliDebug(10, Form("FEBT0LUTs[%d][%d][0x%x]=%d", iPosition, iLUT, iEntry,
823                          this->fFEBT0LUTs[iPosition][iLUT][iEntry])); 
824       }
825       AliDebug(5, Form("Generated FEBT0LUTs[%d][%d]", iPosition, iLUT));
826     }
827   }
828
829   // V0
830   this->fFEBV0LUTs = new Int_t***[2]; // 2 A + C side
831   for (UInt_t iPosition = 0; iPosition < 2; iPosition++) {
832     // iPosition = 0 -> A, iPosition = 1 -> C
833     this->fFEBV0LUTs[iPosition] = new Int_t**[4]; // 4 FEBs per side
834     for (UInt_t iFEB = 0; iFEB < 4; iFEB++) {
835       this->fFEBV0LUTs[iPosition][iFEB] = new Int_t*[2]; // 2 LUTs per FEB
836       for (UInt_t iLUT = 0; iLUT < 2; iLUT++) {
837       // LUT with 10 input channels 2^10=1024
838         this->fFEBV0LUTs[iPosition][iFEB][iLUT] = new Int_t[1024];
839         AliDebug(5, Form("Generate FEBV0LUT[%d][%d][%d]: (0x%x)>%d", iPosition, 
840                          iFEB, iLUT,
841                          this->fFEBV0Multiplicities[iPosition][iFEB][iLUT][1],
842                          this->fFEBV0Multiplicities[iPosition][iFEB][iLUT][0]));
843         for (UInt_t iEntry = 0; iEntry < 1024; iEntry++) {
844           // Check whether that entry belongs to a multiplicity exceeding the 
845           // threshold
846           if (this->GetMultiplicity(iEntry & 
847                 this->fFEBV0Multiplicities[iPosition][iFEB][iLUT][1]) > 
848               this->fFEBV0Multiplicities[iPosition][iFEB][iLUT][0]) {
849             this->fFEBV0LUTs[iPosition][iFEB][iLUT][iEntry] = 1;
850           }
851           else {
852             // initialize LUT (not done before !)
853             this->fFEBV0LUTs[iPosition][iFEB][iLUT][iEntry] = 0;
854           }
855           AliDebug(10, Form("FEBV0LUTs[%d][%d][%d][0x%x]=%d", iPosition, iFEB,
856                             iLUT, iEntry, 
857                             this->fFEBV0LUTs[iPosition][iFEB][iLUT][iEntry]));
858         }
859         AliDebug(5, Form("Generated FEBV0LUTs[%d][%d][%d]", iPosition, iFEB, 
860                          iLUT));
861       }
862     }
863   }
864
865   // ControlBoxes (CB-x)
866   // initialize LUTs
867   this->fCBLUTs = new Int_t**[3];
868   for (Int_t iCB = 0; iCB < 3; iCB++) {
869     if (iCB == kB) { // B
870       fCBLUTs[iCB] = new Int_t*[3];
871       this->fCBLUTs[iCB][0] = 0x0;
872       this->fCBLUTs[iCB][1] = 0x0;
873       this->fCBLUTs[iCB][2] = 0x0;
874     }
875     else { // A + C
876       fCBLUTs[iCB] = new Int_t*[2];
877       this->fCBLUTs[iCB][0] = 0x0;
878       this->fCBLUTs[iCB][1] = 0x0;
879     }
880   }
881   
882   // CB-A (CB = 1 / kA)
883   for (Int_t iLUT = 0; iLUT < 2; iLUT++) {
884     this->fCBLUTs[1][iLUT] = this->GenerateLUTbasedOnEq(this->fCBALUTequ[iLUT],
885                                                         10,1);
886     for (Int_t iEntry = 0; iEntry < 1024; iEntry++) {
887       AliDebug(10, Form("fCBLUTs[@A][%d][0x%x]=%d", iLUT, iEntry,
888                         this->fCBLUTs[1][iLUT][iEntry]));
889     }
890   }
891
892   // CB-C (CB = 2 / kC)
893   for (Int_t iLUT = 0; iLUT < 2; iLUT++) {
894     this->fCBLUTs[2][iLUT] = this->GenerateLUTbasedOnEq(this->fCBCLUTequ[iLUT],
895                                                         10,1);
896     for (Int_t iEntry = 0; iEntry < 1024; iEntry++) {
897       AliDebug(6, Form("fCBLUTs[@C][%d][0x%x]=%d", iLUT, iEntry,
898                        this->fCBLUTs[2][iLUT][iEntry]));
899     }
900   }  
901  
902   // CB-B (CB = 0 / kB)
903   for (Int_t iLUT = 0; iLUT < 3; iLUT++) {
904     this->fCBLUTs[0][iLUT] = this->GenerateLUTbasedOnEq(this->fCBBLUTequ[iLUT], 
905                                                         12,1);
906     for (Int_t iEntry = 0; iEntry < 4096; iEntry++) {
907       AliDebug(10, Form("fCBLUTs[@B][%d][0x%x]=%d", iLUT, iEntry,
908                         this->fCBLUTs[0][iLUT][iEntry]));
909     }
910   }
911
912   AliDebug(5, "LUTs were generated!");
913   return 0;
914 }
915
916 //______________________________________________________________________________
917 UInt_t AliTRDptrgParam::GetMultiplicity(UInt_t BitVector) const {
918   // returns the multiplicity of a given bit vector
919   
920   UInt_t result = 0;
921   UInt_t temp = 0x01;
922   for (UInt_t iBit = 0; iBit < 32; iBit++) {
923     if (BitVector & temp) {
924       result++;
925     }
926     temp <<= 1;
927   }
928
929   return result;
930 }
931
932 //______________________________________________________________________________
933 UInt_t AliTRDptrgParam::GetMultiplicity(Int_t BitVector) const {
934   // returns the multiplicity of a given bit vector
935   
936   UInt_t result = 0;
937   UInt_t temp = 0x01;
938   for (UInt_t iBit = 0; iBit < 32; iBit++) {
939     if (BitVector & temp) {
940       result++;
941     }
942     temp <<= 1;
943   }
944
945   return result;
946 }
947
948 //______________________________________________________________________________
949 //
950 //      Configuration file parsing (helper functions)
951 //______________________________________________________________________________
952
953 //______________________________________________________________________________
954 void AliTRDptrgParam::PrepareLine(TString line, TString& identifier, 
955                                   TString& value) {
956   // Prepares a line for parsing
957   // divide identifier and value 
958
959   // clear identifier and value
960   identifier.Clear();
961   value.Clear();  
962
963   Int_t iLetter = 0;
964   while ((line[iLetter] != ' ') && (line[iLetter] != '\t') && 
965          (line[iLetter] != '#') && (iLetter < line.Length())) {
966     // read identifier
967     identifier += line[iLetter];
968     iLetter++;
969   }
970   while (((line[iLetter] == ' ') || (line[iLetter] == '\t')) &&
971          (iLetter < line.Length()) && (line[iLetter] != '#')) {
972     // omit whitespaces and tabs in between
973     iLetter++;
974   }
975   while(iLetter < line.Length()) {
976     // read value or equation and remove white spaces and tabs
977     //if ((line[iLetter] != ' ') && (line[iLetter] != '\t') &&
978     //    (line[iLetter] != '#')) {
979     if (line[iLetter] != '#') {
980       value += line[iLetter];
981     }
982     iLetter++;
983   }
984 }
985
986 //______________________________________________________________________________
987 TString AliTRDptrgParam::CleanTString(TString string) {
988   // Removes white spaces and tabs
989
990   TString result;
991   result.Clear();
992   for (Int_t iLetter = 0; iLetter < string.Length(); iLetter++) {
993     if ((string[iLetter] != ' ') && (string[iLetter] != '\t')) {
994       result += string[iLetter];
995     }
996   } 
997   AliDebug(5, Form("Cleaned string: %s", result.Data()));  
998   return result;
999 }
1000
1001 //______________________________________________________________________________
1002 void AliTRDptrgParam::SplitUpValues(TString value, TObjArray& arr) {
1003   // splits up multiple values into a TObjArray
1004
1005   TString temp;
1006   temp.Clear();
1007   temp.Resize(0);
1008   for (Int_t iLetter = 0; iLetter < value.Length(); iLetter++) {
1009     if ((value[iLetter] != ' ') && (value[iLetter] != '\t')) {
1010       // add another letter
1011       temp += value[iLetter];
1012     }
1013     else {
1014       // seperator found: white space or tabs
1015       if (temp.Length()) {
1016         TObjString* t = new TObjString(temp.Data());
1017         arr.Add(t);      
1018         temp.Clear();
1019         temp.Resize(0);
1020       }
1021     }
1022   }
1023   if (temp.Length() != 0) {
1024     TObjString* t = new TObjString(temp.Data());
1025     arr.Add(t);         
1026   }
1027 }
1028
1029 //______________________________________________________________________________
1030 UInt_t AliTRDptrgParam::BinaryTStringToInt(TString number) const {
1031   // converts a binary TString to an integer
1032   UInt_t temp = 0x01;
1033   UInt_t result = 0x0;
1034   for (Int_t i = number.Length() - 1; i >= 0; i--) {
1035     if (number[i] == '1') {
1036       result |= temp;
1037       temp <<= 1;
1038     }
1039     else if (number[i] == '0')  {
1040       temp <<= 1;    
1041     }
1042   }
1043   return result;
1044 }
1045
1046 //______________________________________________________________________________
1047 Bool_t AliTRDptrgParam::ParseMultiplicityCondition(TString condition, 
1048                                                    UInt_t* threshold,
1049                                                    UInt_t* mask) {
1050   // converts a string formed like "M(1111_1111)>4" to a input mask and a
1051   // multiplicity threshold
1052
1053   // check whether condition is starting with "M(
1054   if ((condition[0] != 'M') || ( condition[1] != '(')) {
1055     return kFALSE;
1056   }
1057   
1058   TString maskStr = "";
1059   Int_t iLetter = 0;
1060   
1061   // extract input mask
1062   while (condition[iLetter] != ')') {
1063     maskStr += condition[iLetter++];
1064   }
1065   (*mask) = BinaryTStringToInt(maskStr);
1066   if ((*mask) == 0) { 
1067     AliDebug(5, Form("Invalid input mask: %s,[%s]", maskStr.Data(), 
1068                       condition.Data()));
1069     return kFALSE;
1070   }
1071   
1072   // ensure that ')' is followed by a '>'
1073   if (condition[++iLetter] != '>') {
1074     AliDebug(5, Form("multiplicity condition is incorrectly formed: %s", 
1075                      condition.Data()));
1076     return kFALSE;
1077   }
1078   iLetter++; // move on to the first digit
1079
1080   TString thresholdStr = "";
1081   // gain threshold string
1082   while (((condition[iLetter] != ' ') || (condition[iLetter] != '\t')) &&
1083          (iLetter < condition.Length())) {
1084     thresholdStr += condition[iLetter++];
1085   }
1086   (*threshold) = thresholdStr.Atoi(); // convert string to integer
1087   AliDebug(5, Form("mask: 0x%x, multiplicity threshold: %d", (*mask), 
1088                    (*threshold)));
1089   return kTRUE;
1090 }
1091
1092 //______________________________________________________________________________
1093 Bool_t AliTRDptrgParam::ParseFEB(TString identifier, TString value) {
1094   // Parse FEB configuration
1095
1096   //------------------------------------------
1097   if (identifier.Index("FEB/T0/A/THR") == 0) {
1098     // FEB T0 thresholds at A side
1099
1100     TObjArray arr;
1101     arr.Clear();
1102     SplitUpValues(value, arr);
1103     
1104     if (arr.GetEntries() != 12) {
1105       AliError("Wrong FEB T0 Threshold count, it must be 12 channels!");
1106       return kFALSE; 
1107     }
1108     for (Int_t iValue = 0; iValue < arr.GetEntries(); iValue++) {
1109       TObjString *ostrng = dynamic_cast<TObjString*>(arr[iValue]);
1110       if (ostrng) {
1111         this->fFEBT0Thresholds[0][iValue] = (ostrng->GetString()).Atoi();
1112       }
1113       AliDebug(5, Form("FEB/T0/A/THR[%d]=%d", iValue, 
1114                        this->fFEBT0Thresholds[0][iValue])); 
1115     }
1116     return kTRUE;
1117   }
1118
1119   //-----------------------------------------------
1120   else if (identifier.Index("FEB/T0/C/THR") == 0) {
1121     // FEB T0 thresholds at c side
1122
1123     TObjArray arr;
1124     arr.Clear();
1125     SplitUpValues(value, arr);
1126     
1127     if (arr.GetEntries() != 12) {
1128       AliError("Wrong FEB T0 Threshold count, it must be 12 channels!");
1129       return kFALSE; 
1130     }
1131     for (Int_t iValue = 0; iValue < arr.GetEntries(); iValue++) {
1132       TObjString *ostrng = dynamic_cast<TObjString*>(arr[iValue]);
1133       if (ostrng) {
1134         this->fFEBT0Thresholds[1][iValue] = (ostrng->GetString()).Atoi();
1135       }
1136       AliDebug(5, Form("FEB/T0/C/THR[%d]=%d", iValue, 
1137                        this->fFEBT0Thresholds[1][iValue])); 
1138     }
1139     return kTRUE;
1140   }
1141   
1142   //--------------------------------------------------
1143   else if ((identifier.Index("FEB/V0/A0/THR") == 0) ||
1144       (identifier.Index("FEB/V0/A1/THR") == 0) ||
1145       (identifier.Index("FEB/V0/A2/THR") == 0) ||
1146       (identifier.Index("FEB/V0/A3/THR") == 0)) {
1147     // FEB V0 thresholds at a side (cards 0,1,2,3)
1148    
1149     TString cardIDstr = identifier(8, 1);
1150     Int_t cardID = cardIDstr.Atoi();
1151  
1152     TObjArray arr;
1153     arr.Clear();
1154     SplitUpValues(value, arr);
1155     
1156     if (arr.GetEntries() != 8) {
1157       AliError("Wrong FEB V0 Threshold count, it must be 8 channels!");
1158       return kFALSE; 
1159     }
1160     for (Int_t iValue = 0; iValue < arr.GetEntries(); iValue++) {
1161       TObjString *ostrng = dynamic_cast<TObjString*>(arr[iValue]);
1162       if (ostrng) {
1163         this->fFEBV0Thresholds[0][cardID][iValue] =  
1164           (ostrng->GetString()).Atoi();
1165       }
1166       AliDebug(5, Form("FEB/V0/A%d/THR[%d]=%d", cardID, iValue, 
1167                        this->fFEBV0Thresholds[0][cardID][iValue])); 
1168     }
1169   }
1170
1171   //--------------------------------------------------
1172   else if ((identifier.Index("FEB/V0/C0/THR") == 0) ||
1173       (identifier.Index("FEB/V0/C1/THR") == 0) ||
1174       (identifier.Index("FEB/V0/C2/THR") == 0) ||
1175       (identifier.Index("FEB/V0/C3/THR") == 0)) {
1176     // FEB V0 thresholds at c side (cards 0,1,2,3)
1177    
1178     TString cardIDstr = identifier(8, 1);
1179     Int_t cardID = cardIDstr.Atoi();
1180  
1181     TObjArray arr;
1182     arr.Clear();
1183     SplitUpValues(value, arr);
1184     
1185     if (arr.GetEntries() != 8) {
1186       AliError("Wrong FEB V0 Threshold count, it must be 8 channels!");
1187       return kFALSE; 
1188     }
1189     for (Int_t iValue = 0; iValue < arr.GetEntries(); iValue++) {
1190       TObjString *ostrng = dynamic_cast<TObjString*>(arr[iValue]);
1191       if (ostrng) {
1192         this->fFEBV0Thresholds[1][cardID][iValue] = (ostrng->GetString()).Atoi();
1193       }
1194       AliDebug(5, Form("FEB/V0/C%d/THR[%d]=%d", cardID, iValue, 
1195                        this->fFEBV0Thresholds[1][cardID][iValue])); 
1196     }
1197   }
1198   
1199   //-----------------------------------------------
1200   else if (identifier.Index("FEB/T0/A/LUT") == 0) {
1201     // FEB T0 look up tables at A side
1202
1203     TString lutIDstr = identifier(13, 1);
1204     Int_t lutID = lutIDstr.Atoi();
1205     
1206     UInt_t val = 0;
1207     UInt_t mask = 0;
1208     ParseMultiplicityCondition(value, &val, &mask);
1209     this->fFEBT0Multiplicities[0][lutID][0] = val;
1210     this->fFEBT0Multiplicities[0][lutID][1] = mask;
1211     AliDebug(5, Form("FEBT0Multiplicities[0/A][%d][val] = %d", lutID, val));
1212     AliDebug(5, Form("FEBT0Multiplicities[0/A][%d][mask] = %d", lutID, mask));
1213     
1214     return kTRUE;
1215   }
1216
1217   //-----------------------------------------------
1218   else if (identifier.Index("FEB/T0/C/LUT") == 0) {
1219     // FEB T0 look up tables at C side
1220
1221     TString lutIDstr = identifier(13, 1);
1222     Int_t lutID = lutIDstr.Atoi();
1223     
1224     UInt_t val = 0;
1225     UInt_t mask = 0;
1226     ParseMultiplicityCondition(value, &val, &mask);
1227     this->fFEBT0Multiplicities[1][lutID][0] = val;
1228     this->fFEBT0Multiplicities[1][lutID][1] = mask;
1229     AliDebug(5, Form("FEBT0Multiplicities[1/C][%d][val] = %d", lutID, val));
1230     AliDebug(5, Form("FEBT0Multiplicities[1/C][%d][mask] = %d", lutID, mask));
1231
1232     return kTRUE;
1233   }
1234
1235   //--------------------------------------------------
1236   else if ((identifier.Index("FEB/V0/A0/LUT") == 0) ||
1237            (identifier.Index("FEB/V0/A1/LUT") == 0) ||
1238            (identifier.Index("FEB/V0/A2/LUT") == 0) ||
1239            (identifier.Index("FEB/V0/A3/LUT") == 0)) {
1240     // FEB V0 look up tables at A side
1241
1242     TString cardIDstr = identifier(8, 1);
1243     Int_t cardID = cardIDstr.Atoi();
1244  
1245     TString lutIDstr = identifier(14, 1);
1246     Int_t lutID = lutIDstr.Atoi();
1247      
1248     UInt_t val = 0;
1249     UInt_t mask = 0;
1250     ParseMultiplicityCondition(value, &val, &mask);
1251     this->fFEBV0Multiplicities[0][cardID][lutID][0] = val;
1252     this->fFEBV0Multiplicities[0][cardID][lutID][1] = mask;
1253     AliDebug(5, Form("FEBV0Multiplicities[0/A][%d][%d][val] = %d", cardID, 
1254                      lutID, val));
1255     AliDebug(5, Form("FEBV0Multiplicities[0/A][%d][%d][mask] = %d", cardID, 
1256                      lutID, mask));
1257
1258     return kTRUE;
1259   }
1260    
1261   //--------------------------------------------------
1262   else if ((identifier.Index("FEB/V0/C0/LUT") == 0) ||
1263            (identifier.Index("FEB/V0/C1/LUT") == 0) ||
1264            (identifier.Index("FEB/V0/C2/LUT") == 0) ||
1265            (identifier.Index("FEB/V0/C3/LUT") == 0)) {
1266     // FEB V0 look up tables at C side
1267
1268     TString cardIDstr = identifier(8, 1);
1269     Int_t cardID = cardIDstr.Atoi();
1270  
1271     TString lutIDstr = identifier(14, 1);
1272     Int_t lutID = lutIDstr.Atoi();
1273      
1274     UInt_t val = 0;
1275     UInt_t mask = 0;
1276     ParseMultiplicityCondition(value, &val, &mask);
1277     this->fFEBV0Multiplicities[1][cardID][lutID][0] = val;
1278     this->fFEBV0Multiplicities[1][cardID][lutID][1] = mask;
1279     AliDebug(5, Form("FEBV0Multiplicities[1/C][%d][%d][val] = %d", cardID, 
1280                      lutID, val));
1281     AliDebug(5, Form("FEBV0Multiplicities[1/C][%d][%d][mask] = %d", cardID, 
1282                      lutID, mask));
1283
1284     return kTRUE;
1285   }
1286   return kTRUE;
1287 }
1288
1289 //______________________________________________________________________________
1290 Bool_t AliTRDptrgParam::ParseCBAC(TString identifier, TString value) {
1291   // Parse CB-A and CB-C configuration
1292  
1293   if (identifier.Index("CBA/LUT/") == 0) {
1294     // parse CB-A's logical equations
1295     
1296     TString eqIDstr = identifier(8, 1);
1297     Int_t eqID = eqIDstr.Atoi();
1298    
1299     if ((eqID == 0) || (eqID == 1)) {
1300       this->fCBALUTequ[eqID] = this->CleanTString(value);
1301       AliDebug(5, Form("fCBALUTequ[%d]=%s", eqID, this->fCBALUTequ[eqID].Data())); 
1302     }
1303     return kTRUE;    
1304   }
1305     
1306   else if (identifier.Index("CBC/LUT/") == 0) {
1307     // parse CB-C's logical equations
1308     
1309     TString eqIDstr = identifier(8, 1);
1310     Int_t eqID = eqIDstr.Atoi();
1311    
1312     if ((eqID == 0) || (eqID == 1)) {
1313       this->fCBCLUTequ[eqID] = this->CleanTString(value);
1314       AliDebug(5, Form("fCBCLUTequ[%d]=%s", eqID, this->fCBCLUTequ[eqID].Data()));
1315     }
1316     return kTRUE;
1317   }
1318
1319   return kTRUE;
1320 }
1321
1322 //______________________________________________________________________________
1323 Bool_t AliTRDptrgParam::ParseCBB(TString identifier, TString value) {
1324   // Parse CBB configuration
1325   
1326   if (identifier.Index("CBB/LUT/") == 0) {
1327     // parse CB-B's logical equations
1328     
1329     TString eqIDstr = identifier(8, 1);
1330     Int_t eqID = eqIDstr.Atoi();
1331    
1332     if ((eqID == 0) || (eqID == 1) || (eqID == 2)) {
1333       this->fCBBLUTequ[eqID] = this->CleanTString(value);
1334       AliDebug(5, Form("fCBBLUTequ[%d]=%s", eqID, this->fCBBLUTequ[eqID].Data()));
1335     }
1336     return kTRUE;
1337   }
1338   
1339   // PT masks 
1340   else if (identifier.Index("CBB/PT/MASK/CB-A_0") == 0) { // CB-A_0
1341     if (value.Index("YES") == 0) {
1342       this->fPTmasks.fCBA[0] = kTRUE;     
1343     }
1344     else {
1345       this->fPTmasks.fCBA[0] = kFALSE;
1346     }
1347     AliDebug(5, Form("CBB/PT/MASK/CB-A_0=%d", this->fPTmasks.fCBA[0]));
1348     return kTRUE;
1349   }
1350   else if (identifier.Index("CBB/PT/MASK/CB-A_1") == 0) { // CB-A_1
1351     if (value.Index("YES") == 0) {
1352       this->fPTmasks.fCBA[1] = kTRUE;     
1353     }
1354     else {
1355       this->fPTmasks.fCBA[1] = kFALSE;
1356     }
1357     AliDebug(5, Form("CBB/PT/MASK/CB-A_1=%d", this->fPTmasks.fCBA[1]));
1358     return kTRUE;
1359   } 
1360   else if (identifier.Index("CBB/PT/MASK/CB-C_0") == 0) { // CB-C_0
1361     if (value.Index("YES") == 0) {
1362       this->fPTmasks.fCBC[0] = kTRUE;     
1363     }
1364     else {
1365       this->fPTmasks.fCBC[0] = kFALSE;
1366     }
1367     AliDebug(5, Form("CBB/PT/MASK/CB-C_0=%d",this->fPTmasks.fCBC[0]));
1368     return kTRUE;
1369   }
1370   else if (identifier.Index("CBB/PT/MASK/CB-C_1") == 0) { // CB-C_1
1371     if (value.Index("YES") == 0) {
1372       this->fPTmasks.fCBC[1] = kTRUE;     
1373     }
1374     else {
1375       this->fPTmasks.fCBC[1] = kFALSE;
1376     }
1377     AliDebug(5, Form("CBB/PT/MASK/CB-C_1=%d", this->fPTmasks.fCBC[1]));
1378     return kTRUE;
1379   } 
1380   else if (identifier.Index("CBB/PT/MASK/CB-B_0") == 0) { // CB-B_0
1381     if (value.Index("YES") == 0) {
1382       this->fPTmasks.fLUTs[0] = kTRUE;     
1383     }
1384     else {
1385       this->fPTmasks.fLUTs[0] = kFALSE;
1386     }
1387     AliDebug(5, Form("CBB/PT/MASK/CB-B_0=%d",this->fPTmasks.fLUTs[0]));
1388     return kTRUE;
1389   }
1390   else if (identifier.Index("CBB/PT/MASK/CB-B_1") == 0) { // CB-B_1
1391     if (value.Index("YES") == 0) {
1392       this->fPTmasks.fLUTs[1] = kTRUE;     
1393     }
1394     else {
1395       this->fPTmasks.fLUTs[1] = kFALSE;
1396     }
1397     AliDebug(5, Form("CBB/PT/MASK/CB-B_1/=%d", this->fPTmasks.fLUTs[1]));
1398     return kTRUE;
1399   }
1400   else if (identifier.Index("CBB/PT/MASK/CB-B_2") == 0) { // CB-B_2
1401     if (value.Index("YES") == 0) {
1402       this->fPTmasks.fLUTs[2] = kTRUE;     
1403     }
1404     else {
1405       this->fPTmasks.fLUTs[2] = kFALSE;
1406     }
1407     AliDebug(5, Form("CBB/PT/MASK/CB-B_2/=%d", this->fPTmasks.fLUTs[2]));
1408     return kTRUE;
1409   }
1410   else if (identifier.Index("BB/PT/MASK/TLMU_") == 0) {
1411     TString indexStr = identifier(16, 1);
1412     Int_t index = indexStr.Atoi();
1413     if (value.Index("YES") == 0) {
1414       this->fPTmasks.fTLMU[index] = kTRUE;
1415     }
1416     else {
1417       this->fPTmasks.fTLMU[index] = kFALSE;
1418     }
1419     AliDebug(5, Form("CBB/PT/MASK/TLMU_%d=%d", index, 
1420                      this->fPTmasks.fTLMU[index]));
1421     return kTRUE;
1422   }
1423   return kTRUE;
1424 }
1425
1426 //______________________________________________________________________________
1427 Bool_t AliTRDptrgParam::ParseTLMU(TString identifier, TString value) {
1428   // Parse TLMU configuration
1429
1430   if (identifier.Index("TLMU/IMASK/SEC") == 0) {
1431     // TLMU input masks
1432     TString indexStr = identifier(14,2);
1433     Int_t index = indexStr.Atoi();
1434     if ((index < 0) || (index > 17)) {
1435       AliDebug(5, "Wrong section index in TLMU input mask");
1436       return kFALSE;
1437     }
1438     this->fTLMUInputMask[index] = BinaryTStringToInt(value);
1439     AliDebug(5, Form("%d %x\n", index, this->fTLMUInputMask[index]));
1440     return kTRUE;
1441   }
1442
1443   //-----------------------------------------------
1444   else if (identifier.Index("TLMU/CMATRIX") == 0) {
1445     // TLMU coincidence matrices
1446
1447     // matrix index
1448     TString matrixIndexStr = identifier(12,1);
1449     Int_t matrixIndex = matrixIndexStr.Atoi();
1450     // entry index
1451     TString indexStr = identifier(17,2);
1452     Int_t index = indexStr.Atoi();
1453     this->fTLMUcmatrices[matrixIndex][index] = BinaryTStringToInt(value);
1454     AliDebug(5, Form("%d 0x%x\n", matrixIndex, 
1455                      this->fTLMUcmatrices[matrixIndex][index]));
1456     return kTRUE;
1457   }
1458
1459   //---------------------------------------------
1460   else if (identifier.Index("TLMU/MCNTR") == 0) {
1461     // TLMU multiplicity counter setup
1462     
1463     TString indexStr = identifier(10,1);
1464     Int_t index = indexStr.Atoi();
1465     TObjArray arr;
1466
1467     SplitUpValues(value, arr);
1468     
1469     TObjString *ostrng0 = dynamic_cast<TObjString*>(arr[0]);
1470     TObjString *ostrng1 = dynamic_cast<TObjString*>(arr[1]);
1471
1472     if (ostrng0 && ostrng1) {
1473
1474       TString t0 = ostrng0->GetString();
1475       TString t1 = ostrng1->GetString();
1476   
1477       this->fTLMUmultiplicity[index][0] = t0.Atoi();
1478       this->fTLMUmultiplicity[index][1] = t1.Atoi();
1479  
1480       AliDebug(5, Form("%d: %d  %d", index, this->fTLMUmultiplicity[index][0], 
1481                        this->fTLMUmultiplicity[index][1]));      
1482
1483     }
1484
1485     return kTRUE;
1486   }
1487   
1488   //----------------------------------------------
1489   else if (identifier.Index("TLMU/OUTMUX") == 0) {
1490     // TLMU output signal assignment
1491     TObjArray arr;
1492     SplitUpValues(value, arr);
1493   
1494     if (arr.GetEntries() > 8) {
1495       AliError("Too many TLMU output signals assigned");
1496       return kFALSE;
1497     } 
1498   
1499     for (Int_t iEntry = 0; iEntry < arr.GetEntries(); iEntry++) {
1500
1501       TObjString *ostrng = dynamic_cast<TObjString*>(arr[iEntry]);
1502       if (ostrng) {
1503
1504         TString t = ostrng->GetString(); 
1505       
1506         TString indexStr = t(2,1);
1507         if (t.Index("CM") == 0) { // coincidence matrix
1508           this->fTLMUoutput[iEntry][0] = indexStr.Atoi();
1509         }
1510         else if (t.Index("MC") == 0) { // multiplicity
1511           this->fTLMUoutput[iEntry][1] = indexStr.Atoi();
1512         }
1513
1514       }
1515
1516       AliDebug(5, Form("TLMU output: cm = %d, mc = %d", 
1517                        this->fTLMUoutput[iEntry][0], 
1518                        this->fTLMUoutput[iEntry][1]));
1519     }
1520     return kTRUE;
1521   }
1522   return kTRUE;
1523 }
1524
1525 //______________________________________________________________________________
1526 //
1527 //       Logical Equation to LUT processing (helper functions)
1528 //______________________________________________________________________________
1529
1530 //______________________________________________________________________________
1531 Int_t AliTRDptrgParam::LookUp(TString* const identifier) const {
1532   // Transforms identifier into look up table address bit
1533   //
1534   // this function has to be extended/changed when different identifiers for
1535   // other equations and destination LUTs should be used
1536
1537   if (identifier->CompareTo("T0_0", TString::kIgnoreCase) == 0)  
1538     return 0x001;
1539   else if (identifier->CompareTo("T0_1", TString::kIgnoreCase) == 0) 
1540     return 0x002; 
1541   else if (identifier->CompareTo("V0-0_0", TString::kIgnoreCase) == 0) 
1542     return 0x004; 
1543   else if (identifier->CompareTo("V0-0_1", TString::kIgnoreCase) == 0) 
1544     return 0x008; 
1545   else if (identifier->CompareTo("V0-1_0", TString::kIgnoreCase) == 0) 
1546     return 0x010; 
1547   else if (identifier->CompareTo("V0-1_1", TString::kIgnoreCase) == 0) 
1548     return 0x020; 
1549   else if (identifier->CompareTo("V0-2_0", TString::kIgnoreCase) == 0) 
1550     return 0x040; 
1551   else if (identifier->CompareTo("V0-2_1", TString::kIgnoreCase) == 0) 
1552     return 0x080; 
1553   else if (identifier->CompareTo("V0-3_0", TString::kIgnoreCase) == 0) 
1554     return 0x100; 
1555   else if (identifier->CompareTo("V0-3_1", TString::kIgnoreCase) == 0) 
1556     return 0x200; 
1557   else if (identifier->CompareTo("CB-A_0", TString::kIgnoreCase) == 0) 
1558     return 0x001; 
1559   else if (identifier->CompareTo("CB-A_1", TString::kIgnoreCase) == 0) 
1560     return 0x002; 
1561   else if (identifier->CompareTo("CB-C_0", TString::kIgnoreCase) == 0) 
1562     return 0x004; 
1563   else if (identifier->CompareTo("CB-C_1", TString::kIgnoreCase) == 0) 
1564     return 0x008; 
1565   else if (identifier->CompareTo("TLMU_0", TString::kIgnoreCase) == 0)  
1566     return 0x010; 
1567   else if (identifier->CompareTo("TLMU_1", TString::kIgnoreCase) == 0) 
1568     return 0x020; 
1569   else if (identifier->CompareTo("TLMU_2", TString::kIgnoreCase) == 0) 
1570     return 0x040; 
1571   else if (identifier->CompareTo("TLMU_3", TString::kIgnoreCase) == 0) 
1572     return 0x080; 
1573   else if (identifier->CompareTo("TLMU_4", TString::kIgnoreCase) == 0) 
1574     return 0x100; 
1575   else if (identifier->CompareTo("TLMU_5", TString::kIgnoreCase) == 0) 
1576     return 0x200; 
1577   else if (identifier->CompareTo("TLMU_6", TString::kIgnoreCase) == 0) 
1578     return 0x400; 
1579   else if (identifier->CompareTo("TLMU_7", TString::kIgnoreCase) == 0) 
1580     return 0x800; 
1581   else return 0x0; // Error
1582 }
1583
1584 //______________________________________________________________________________
1585 void AliTRDptrgParam::MergeResults(TArrayI*& partResult1, TArrayI*& partResult2,
1586                                    TArrayI*& results,
1587                                    TArrayI*& signalsInvolved1, 
1588                                    TArrayI*& signalsInvolved2, 
1589                                    TArrayI*& signalsInvolved, 
1590                                    Bool_t useOR) {
1591   // merges result and signal involved arrays
1592   // uses logical OR (or=kTRUE) and AND (or==kFALSE) as merging function
1593   
1594   // check whether input data is valid
1595   if ((partResult1 == 0x0) || (partResult2 == 0x0) || 
1596       (signalsInvolved1 == 0x0) || (signalsInvolved2 == 0x0)) {
1597     AliError("fatal logical equation processing error!");
1598     return;
1599   }
1600  
1601   // allocate results and signalsInvolved 
1602   results = new TArrayI(0);    
1603   signalsInvolved = new TArrayI(0);
1604
1605   // merge arrays (necessary for OR and AND)
1606   for (Int_t i = 0; i < partResult1->GetSize(); i++) {
1607     for (Int_t j = 0; j < partResult2->GetSize(); j++) {
1608       results->Set(results->GetSize() + 1); // increment size
1609       (*results)[results->GetSize() - 1] =  // add combination
1610         (*partResult1)[i] | (*partResult2)[j];
1611  
1612       signalsInvolved->Set(signalsInvolved->GetSize() + 1);
1613       (*signalsInvolved)[signalsInvolved->GetSize() - 1] = 
1614          (*signalsInvolved1)[i] | (*signalsInvolved2)[j];
1615     }
1616   }
1617   
1618   if (useOR) { // only necessary for OR
1619     // add partResult1
1620     for (Int_t i = 0; i < partResult1->GetSize(); i++) {
1621       results->Set(results->GetSize() + 1);
1622       (*results)[results->GetSize() - 1] = (*partResult1)[i];
1623       
1624       signalsInvolved->Set(signalsInvolved->GetSize() + 1);
1625       (*signalsInvolved)[signalsInvolved->GetSize()-1] = (*signalsInvolved1)[i];
1626     }
1627     // add partResult2
1628     for (Int_t i = 0; i < partResult2->GetSize(); i++) {
1629       results->Set(results->GetSize() + 1);
1630       (*results)[results->GetSize() - 1] = (*partResult2)[i];
1631       
1632       signalsInvolved->Set(signalsInvolved->GetSize() + 1);
1633       (*signalsInvolved)[signalsInvolved->GetSize()-1] = (*signalsInvolved2)[i];
1634     }
1635   }
1636   
1637   // debug output
1638   AliDebug(5, "merging results: ");
1639   for (Int_t i = 0; i < results->GetSize(); i++) {
1640     AliDebug(5, Form("0x%x 0x%x", (*results)[i], (*signalsInvolved)[i]));
1641   }
1642
1643   // free memory
1644   delete partResult1;
1645   partResult1 = 0x0;
1646   delete partResult2;
1647   partResult2 = 0x0; 
1648 }
1649
1650 //______________________________________________________________________________
1651 void AliTRDptrgParam::ConvertLogicalEqToBitVectors(TString eq, 
1652                                                    TArrayI*& results,
1653                                                    TArrayI*& signalsInvolved) {
1654   // converts a logical equation to a LUT
1655   //
1656   // input string must not contain white spaces or tabs
1657   // only identifiers, ||, &&, (, ) and ! are allowed
1658   //
1659   // neglected signals are assumed to be zero in this function
1660   // this problem is solved by "void CheckSignalsInvolved(...)"
1661
1662   AliDebug(5, Form("eq: %s", eq.Data()));
1663
1664   // temporary variables used before/while merging
1665   TArrayI* partResult1 = 0x0;
1666   TArrayI* partResult2 = 0x0;
1667   TArrayI* partResult3 = 0x0;
1668   TArrayI* partResult4 = 0x0;
1669   TArrayI* signalsInvolved1 = 0x0;
1670   TArrayI* signalsInvolved2 = 0x0;
1671   TArrayI* signalsInvolved3 = 0x0;
1672   TArrayI* signalsInvolved4 = 0x0;
1673  
1674   Int_t iChar = 0; // counter variable
1675   
1676   // variables needed for correct operator order (&& before ||!)
1677   Int_t foundORbefore = -1; // found an || in that string (-1 = not found)
1678   Int_t foundAND = -1; // found an &&
1679   Int_t foundORafter = -1; // found a second OR after &&
1680
1681   // variables needed for correct bracket processing
1682   Int_t enteredBrackets = 0; // indicates in which bracket layer the parser is
1683   Int_t bracketLevelAtZero = -1; // when enteredBrackets = 0 was reached first
1684   // after it ascended  
1685
1686   while ((iChar < eq.Length())) { //--------------------------------------------
1687     // walk through string
1688
1689     // operators ---------------------------------------------------------------
1690     if ((enteredBrackets == 0 ) && (eq[iChar] != '(') && (eq[iChar] != ')'))  {
1691       // '|'
1692       if (eq[iChar] == '|') {
1693         if (eq[iChar + 1] == '|') { // ||
1694           iChar++; // jump to the next charakter
1695           if (foundAND == -1) {
1696             foundORbefore = iChar;
1697           }
1698           else if ((foundORafter == -1) && (foundAND != -1)) {
1699             foundORafter = iChar;
1700           }
1701         }
1702         else { // bit-wise and not supported
1703           AliError(Form("LogicalEquation incorrect: %s", eq.Data()));
1704           AliError("bit-wise AND (&) not supported for now");
1705           return;
1706         }
1707       }
1708       // '&' 
1709       else if (eq[iChar] == '&') {
1710         if (eq[iChar] == '&') { // ||
1711           iChar++; // jump to the next charakter
1712           if (foundAND == -1) {
1713             foundAND = iChar;
1714           }
1715         }
1716         else { // bit-wise or not supported
1717           AliError(Form("LogicalEquation incorrect: %s", eq.Data()));
1718           AliError("bit-wise OR (|) not supported for now");
1719           return;
1720         }
1721       }
1722     }
1723     // brackets ----------------------------------------------------------------
1724     // '(' 
1725     if (eq[iChar] == '(') {
1726       enteredBrackets++;      
1727     }
1728     // ')' 
1729     else if (eq[iChar] == ')') {
1730       enteredBrackets--;
1731       if (enteredBrackets < 0) {        
1732         AliError(Form("LogicalEquation incorrect: %s", eq.Data()));     
1733         AliError("Too many )s");
1734       }
1735       if ((enteredBrackets == 0) && (bracketLevelAtZero == -1) &&
1736           (foundAND == -1) && (foundORbefore == -1)) {
1737         // needed to detected equations encapsulated in brackets: (...)
1738         bracketLevelAtZero = iChar;
1739       }
1740     }      
1741     iChar++; // go on to the next letter/char
1742   } //--------------------------------------------------------------------------
1743
1744   if (bracketLevelAtZero == (eq.Length() - 1)) { // strip ( ) and process again
1745     ConvertLogicalEqToBitVectors(eq(1, eq.Length() -2), results, 
1746                                  signalsInvolved);
1747     return;     
1748   }
1749   else if (foundAND == -1) { // no AND
1750     if (foundORbefore != -1) { // only OR / || found and no AND
1751       ConvertLogicalEqToBitVectors(eq(0, foundORbefore-1), partResult1, 
1752                                    signalsInvolved1); 
1753       ConvertLogicalEqToBitVectors(eq(foundORbefore+1, 
1754                                       eq.Length()-foundORbefore-1),
1755                                    partResult2, signalsInvolved2);
1756       
1757       MergeResults(partResult1, partResult2, results, signalsInvolved1,
1758                    signalsInvolved2, signalsInvolved, kTRUE);
1759       return;
1760     } 
1761     else { // only identifier remained!
1762       results = new TArrayI(1);
1763       signalsInvolved = new TArrayI(1);
1764       if (eq[0] != '!') { // identifier without negation
1765         (*results)[0] = LookUp(&eq); 
1766         (*signalsInvolved)[0] = (*results)[0];
1767       }
1768       else { // identifier with negation
1769         (*results)[0] = 0;
1770         TString eqNegated = eq(1, eq.Length()-1);
1771         (*signalsInvolved)[0] = LookUp(&eqNegated);
1772       } 
1773       return;
1774     }
1775   }
1776   // found single or multiple AND / && 
1777   else if ((foundORafter != -1) && (foundORbefore != -1)) { 
1778     // found: ...||...&&...||...   
1779     ConvertLogicalEqToBitVectors(eq(0, foundORbefore-1), partResult1, 
1780                                  signalsInvolved1);
1781     ConvertLogicalEqToBitVectors(eq(foundORbefore+1, 
1782                                     foundORafter-foundORbefore-2),
1783                                  partResult2, signalsInvolved2);
1784     ConvertLogicalEqToBitVectors(eq(foundORafter+1, eq.Length()-foundORafter-1),
1785                                  partResult3, signalsInvolved3);
1786
1787     // merge: 4 = 1 || 2 
1788     MergeResults(partResult1, partResult2, partResult4, signalsInvolved1,
1789                  signalsInvolved2, signalsInvolved4, kTRUE);
1790     // merge results = 3 || 4
1791     MergeResults(partResult3, partResult4, results, signalsInvolved3,
1792                  signalsInvolved4, signalsInvolved, kTRUE);
1793     return;
1794   } 
1795   else if (foundORbefore != -1) { 
1796     // found ...||...&&...
1797     ConvertLogicalEqToBitVectors(eq(0, foundORbefore - 1), partResult1, 
1798                                  signalsInvolved1); 
1799     ConvertLogicalEqToBitVectors(eq(foundORbefore+1, 
1800                                     eq.Length()-foundORbefore-1),
1801                                  partResult2, signalsInvolved2);
1802    
1803     MergeResults(partResult1, partResult2, results, signalsInvolved1,
1804                  signalsInvolved2, signalsInvolved, kTRUE);
1805     return;
1806   }
1807   else if (foundORafter != -1) {
1808     // found  ...&&...||...
1809     ConvertLogicalEqToBitVectors(eq(0, foundORafter - 1), partResult1, 
1810                                  signalsInvolved1); 
1811     ConvertLogicalEqToBitVectors(eq(foundORafter+1, 
1812                                     eq.Length()-foundORafter-1),
1813                                  partResult2, signalsInvolved2);
1814    
1815     MergeResults(partResult1, partResult2, results, signalsInvolved1,
1816                  signalsInvolved2, signalsInvolved, kTRUE);
1817     return;
1818   }
1819   else /* if (foundAND != -1)*/ { // found ...&&...
1820     ConvertLogicalEqToBitVectors(eq(0, foundAND-1), partResult1, 
1821                                  signalsInvolved1); 
1822     ConvertLogicalEqToBitVectors(eq(foundAND+1, eq.Length()-foundAND-1), 
1823                                  partResult2, signalsInvolved2); 
1824
1825     MergeResults(partResult1, partResult2, results, signalsInvolved1,
1826                  signalsInvolved2, signalsInvolved, kFALSE);    
1827     return;
1828   }
1829   
1830   AliError("Logical equation parser error!");
1831   return;
1832 }
1833
1834 //______________________________________________________________________________
1835 void AliTRDptrgParam::CheckSignalsInvolved(TArrayI*& results, 
1836                                            TArrayI*& signalsInvolved,
1837                                            Int_t inputWidth) {
1838   // checks whether all input signals are taken into account
1839   //
1840   // this function is needed to be able to write equations which contain not all
1841   // possible signals and which are not mentioned in the equation do not effect
1842   // the result
1843   // X=B&&C=(A||!A)&&B&&C
1844
1845   // this routine is quite inefficient but working O((2^inputWidth)^3)
1846
1847   // generate mask:
1848   Int_t temp = 0x1;
1849   Int_t mask = 0x0;
1850   for (Int_t iSignal = 0; iSignal < inputWidth; iSignal++) {
1851     mask |= temp;
1852     temp <<= 1; // move temp to the next bit 
1853   }
1854   
1855   for (Int_t iResult = 0; iResult < results->GetSize(); iResult++) {
1856     // tricky: size of results increases while loop is iterating
1857     // that is needed to generate all valid input signal combinations
1858     if (mask != (*signalsInvolved)[iResult]) {
1859       // not all input signals are taken into account
1860       Int_t inputSignal = 0x1;
1861       for (Int_t iSignal = 0; iSignal < inputWidth; iSignal++) {
1862         if (!(inputSignal & (*signalsInvolved)[iResult])) {
1863           Int_t newInvolvedSignalCombination = 
1864             (*signalsInvolved)[iResult] | inputSignal;
1865           Int_t newResult = inputSignal | (*results)[iResult];
1866           Bool_t signalCombinationAlreadyEnlisted = kFALSE;
1867           for (Int_t iEntry = 0; iEntry < signalsInvolved->GetSize(); iEntry++){
1868             // this loop is needed to reduce the amount of equal entries in 
1869             // signalsInvolved
1870             // maybe a table with all possible input values could reduce the
1871             // computional effort, but this would consume a lot of ram
1872             if ((signalsInvolved->At(iEntry) == newInvolvedSignalCombination) &&
1873                 (results->At(iEntry) == newResult)) {
1874               signalCombinationAlreadyEnlisted = kTRUE;
1875               break;
1876             }
1877           }
1878           if (!signalCombinationAlreadyEnlisted) {
1879             results->Set(results->GetSize() + 1);
1880             (*results)[results->GetSize() - 1] = inputSignal | 
1881                                                  (*results)[iResult];
1882             // add variant with active bit, variant with inactive signal
1883             // is already containt in the results array
1884
1885             // update signalsInvolved:
1886             signalsInvolved->Set(signalsInvolved->GetSize() + 1);
1887             (*signalsInvolved)[signalsInvolved->GetSize() - 1] =
1888               (*signalsInvolved)[iResult] | inputSignal;
1889           }
1890         }
1891         inputSignal <<= 1; // move temp to the next input signal      
1892       }      
1893     }
1894   }
1895   return;
1896 }
1897
1898 //______________________________________________________________________________
1899 Int_t* AliTRDptrgParam::GenerateLUTbasedOnEq(TString eq, Int_t inputWidth, 
1900                                              Int_t initValue) {
1901   // Processes the conversion of a logical equation to a look up table
1902   
1903   TArrayI* results = 0x0;
1904   TArrayI* signalsInvolved = 0x0;
1905  
1906   ConvertLogicalEqToBitVectors(eq, results, signalsInvolved);
1907   // generate bit vectors
1908   
1909   if ((results != 0x0) && (signalsInvolved != 0x0)) {
1910
1911     CheckSignalsInvolved(results, signalsInvolved, inputWidth);
1912     // add bit vectors for signals which are not taken into account
1913
1914     Int_t lutSize =  0x1 << inputWidth; // 2^inputwidth elements
1915     Int_t* resultingLUT = new Int_t[lutSize]; // create LUT
1916     for (Int_t iLUTentry = 0; iLUTentry < lutSize; iLUTentry++) { // init LUT
1917       resultingLUT[iLUTentry] = 0;
1918     }
1919     for (Int_t iEntry = 0; iEntry < results->GetSize(); iEntry++) {
1920       resultingLUT[(*results)[iEntry]] = initValue;
1921     }
1922   
1923     delete results;
1924     results = 0x0;
1925
1926     delete signalsInvolved;
1927     signalsInvolved = 0x0;
1928   
1929     return resultingLUT;
1930
1931   }
1932   else {
1933
1934     return 0x0;
1935
1936   }
1937
1938 }
1939
1940 //______________________________________________________________________________
1941 //___ GETTER FUNCTIONS__________________________________________________________
1942 //______________________________________________________________________________
1943 UInt_t* AliTRDptrgParam::GetFEBT0Thresholds(AliTRDptrgFEBPosition_t FEBposition)
1944   const
1945 {
1946   // get T0 FEB Thresholds
1947   return this->fFEBT0Thresholds[FEBposition - 1];
1948   // 0 kB, 1= kA, 2, kC => -1 because T0FEBs are only in position kA and kC
1949 }
1950
1951 //_____________________________________________________________________________
1952 Int_t* AliTRDptrgParam::GetFEBT0LUT(AliTRDptrgFEBPosition_t FEBposition, 
1953                                     Int_t iLUT) {
1954   // get T0 FEB LUTs
1955   if (this->fFEBT0LUTs == 0x0) {
1956     this->GenerateLUTs();
1957   }
1958   return this->fFEBT0LUTs[FEBposition - 1][iLUT]; 
1959   // 0 kB, 1= kA, 2, kC => -1 because T0FEBs are only in position kA and kC
1960
1961
1962 //______________________________________________________________________________
1963 UInt_t* AliTRDptrgParam::GetFEBV0Thresholds(AliTRDptrgFEBPosition_t FEBposition,
1964                                            Int_t iCard) const {
1965   // get V0 FEB Thresholds
1966   return this->fFEBV0Thresholds[FEBposition - 1][iCard];
1967   // 0 kB, 1= kA, 2, kC => -1 because T0FEBs are only in position kA and kC
1968 }
1969
1970 //______________________________________________________________________________
1971 Int_t* AliTRDptrgParam::GetFEBV0LUT(AliTRDptrgFEBPosition_t FEBposition, 
1972                                     Int_t iCard, Int_t iLUT) {
1973   // get V0 FEB LUTs
1974   if (this->fFEBV0LUTs == 0x0) {
1975     this->GenerateLUTs();
1976   }
1977   return this->fFEBV0LUTs[FEBposition - 1][iCard][iLUT];
1978   // 0 kB, 1= kA, 2, kC => -1 because T0FEBs are only in position kA and kC
1979 }
1980
1981 //______________________________________________________________________________
1982 Int_t* AliTRDptrgParam::GetCBLUT(UInt_t iCB, Int_t LUTid) {
1983   // return control box LUT
1984   // iCB: 0 = B, 1 = A, 2 = C
1985   if (this->fCBLUTs == 0x0) {
1986     this->GenerateLUTs();
1987   }
1988   return this->fCBLUTs[iCB][LUTid];
1989 }
1990