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