re-activate contrib code
[u/mrichter/AliRoot.git] / TRD / AliTRDptrgFEB.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 //  Pre-Trigger simulation                                                
21 //                                                                        
22 //  Authors: F. Reidt (Felix.Reidt@cern.ch)                               
23 //                
24 //  This class is used to simulate the front end box behavior of the 
25 //  pretrigger system. Digits of T0 and V0 are used as input. A threshold
26 //  discrimination, masking and first processing with look up tables  is 
27 //  done during the simulation process
28 //                                                                  
29 ////////////////////////////////////////////////////////////////////////////
30
31 #include <TClonesArray.h> 
32 #include <TTree.h>
33
34 #include "AliRunLoader.h"
35 #include "AliLoader.h"
36 #include "AliLog.h"
37
38 #include "AliVZEROdigit.h" 
39 #include "AliVZEROCalibData.h"
40 #include "AliT0digit.h"
41
42 #include "AliTRDptrgParam.h"
43 #include "AliTRDptrgLUT.h"
44 #include "AliTRDptrgFEB.h"
45
46 ClassImp(AliTRDptrgFEB)
47
48 //______________________________________________________________________________
49 AliTRDptrgFEB::AliTRDptrgFEB(AliRunLoader *rl) 
50   : TObject(),
51   fRunLoader(rl),
52   fParam(0),
53   fLUTArray(0),
54   fType(AliTRDptrgParam::kUndefined),
55   fOperatingMode(AliTRDptrgParam::kDigits),
56   fInputChannelCount(0),
57   fPosition(AliTRDptrgParam::kUnknown),  
58   fID(0),
59   fThreshold(0)
60 {
61   // default constructor
62   AliError("default ctor - not recommended");
63 }
64
65 //______________________________________________________________________________
66 AliTRDptrgFEB::AliTRDptrgFEB(AliRunLoader *rl, AliTRDptrgParam::AliTRDptrgFEBType_t febType, 
67                              AliTRDptrgParam::AliTRDptrgOperatingMode_t operatingMode,
68                              AliTRDptrgParam::AliTRDptrgFEBPosition_t position, Int_t id, 
69                              AliTRDptrgParam *param)
70   : TObject(),
71   fRunLoader(rl),
72   fParam(param),
73   fLUTArray(0),
74   fType(febType),
75   fOperatingMode(operatingMode),
76   fInputChannelCount(0),
77   fPosition(position),
78   fID(id),
79   fThreshold(0x0) 
80 {
81   // prefered constructor
82   
83   this->LoadParams(); // load configuration parameters
84
85 }
86
87 //______________________________________________________________________________
88 AliTRDptrgFEB::~AliTRDptrgFEB() 
89 {
90   // destructor
91   if (this->fParam == 0x0) {  
92     if (this->fThreshold != 0x0) {
93       delete[] this->fThreshold;
94       this->fThreshold = 0x0;
95    }
96   }
97   // delete LUTArray
98   this->fLUTArray.Delete();
99 }
100
101 //______________________________________________________________________________
102 Int_t AliTRDptrgFEB::LoadDigits()
103 {
104   // loads T0 or V0 digits and discriminates them automatically
105  
106   if (this->fType == AliTRDptrgParam::kVZERO) {
107     // load V0's digits --------------------------------------------------------
108     // behavior adapted for AliVZERODigitizer.cxx 40613 2010-04-22 09:57:15Z   
109  
110     // get V0 run loader
111     AliLoader* loader = this->fRunLoader->GetLoader( "VZEROLoader" );
112
113     if (!loader) {
114       AliError("Cannot get VZERO loader");
115       return -1;
116     }
117     loader->LoadDigits("READ");
118     TTree* vzeroDigitsTree = loader->TreeD();
119
120     if (!vzeroDigitsTree) {
121       AliError("Cannot get the VZERO digit tree");
122       return -1;
123     }
124     
125                 
126     TClonesArray* vzeroDigits = NULL;
127     TBranch* digitBranch = vzeroDigitsTree->GetBranch("VZERODigit");
128     digitBranch->SetAddress(&vzeroDigits);
129     vzeroDigitsTree->GetEvent(0);       
130     
131   
132     Int_t nDigits = vzeroDigits->GetEntriesFast(); // get digit count
133                 
134     AliDebug(5, Form("Found a whole of %d digits", nDigits));    
135                 
136     Int_t inputVector = 0x0; // Vector which is feed into the LUT
137                 
138     for (Int_t iDigit=0; iDigit<nDigits; iDigit++) {
139       // loop over all digits
140       AliDebug(5, "Looping over digit");
141       AliVZEROdigit* digit = (AliVZEROdigit*)vzeroDigits->At(iDigit);
142                               
143       Int_t pmNumber   = digit->PMNumber();
144       //      Int_t board   = pmNumber / 8; // changed in Version 40613
145       Int_t feeBoard = AliVZEROCalibData::GetBoardNumber(pmNumber);
146       Int_t board = feeBoard % 4; // feeBoard V0-A: 1-4; V0-C: 5-8 => board: 1-4
147
148       Int_t channel = pmNumber % 8;
149
150       Int_t position = -1;
151       if ((pmNumber >= 32) && (pmNumber <= 63)) { // V0-A (matched v40613)
152         position = 1; // AliTRDptrgParam::kA
153       } 
154       else if ((pmNumber >= 0) && (pmNumber <= 31)) { // V0-C (matched v40613)
155         position = 2; // kB
156       }
157
158       AliDebug(5, 
159         Form("pmNumber: %d; feeBoard: %d; board: %d; channel: %d; position %d",
160              pmNumber, feeBoard, board, channel, position));  
161
162       if (position == -1)   {
163         AliError("Wrong VZERO pmt position found");
164         loader->UnloadDigits();
165         return -1;
166       }
167
168       // check whether the digits belongs to the current FEB, otherwise omit it
169       if ((position == this->fPosition) && (board == this->fID)) {
170         AliDebug(5, "Found an digit corresponding to the current FEB");
171         Float_t value = digit->ADC();
172         AliDebug(5, Form("ADC value: %f\n", value));
173         Int_t channelBitMask = 0x01; 
174         // channel0 => 0x01; channel1=> 0x02;  2^(channel number)
175         channelBitMask <<= channel;
176         if (value >= this->fThreshold[channel]) {
177           inputVector |= channelBitMask;
178           AliDebug(5,
179             Form("Threshold exceeded in channel %d, new inputVector 0x%x", 
180                  channel, inputVector));
181         }
182       }
183     }
184
185     AliDebug(5, Form("inputVector: 0x%x", inputVector));
186     loader->UnloadDigits();
187     return inputVector;
188   }
189   else if (this->fType == AliTRDptrgParam::kTZERO) {
190     // load T0's digits --------------------------------------------------------
191     AliLoader * fT0Loader = this->fRunLoader->GetLoader("T0Loader");
192     //   AliT0digit *fDigits; 
193     if (!fT0Loader) {
194       AliError("Cannot get T0 loader");
195       return -1;
196     }
197       
198     fT0Loader->LoadDigits("READ");
199     // Creating T0 data container
200
201     TTree* treeD = fT0Loader->TreeD();
202     if (!treeD) {
203       AliError("no digits tree");
204       return -1;
205     }
206     AliT0digit* digits = new AliT0digit();
207     TBranch *brDigits = treeD->GetBranch("T0");
208
209     if (brDigits) {
210       brDigits->SetAddress(&digits);
211     }
212     else {
213       AliError("Branch T0 DIGIT not found");
214       return -1;
215     }     
216     brDigits->GetEntry(0);              
217
218     TArrayI qtc0(24); // Array must have 24 entries!
219     TArrayI qtc1(24); // Array must have 24 entries!
220     
221     digits->GetQT0(qtc0); // baseline (reference level)
222     digits->GetQT1(qtc1); // measurement value
223
224     Int_t inputVector = 0x0; // vector to be fed into the look up table
225     
226     // PMT Positions
227     // C: 0  to 11
228     // A: 12 to 23
229     // positions according to AliT0Digitizer.cxx Revision 37491
230     Int_t nStart = 0;
231     if (this->fPosition == AliTRDptrgParam::kC) { // C
232       nStart = 0;
233     }
234     else if (this->fPosition == AliTRDptrgParam::kA) { // A
235       nStart = 12;
236     }
237
238     Int_t channelBitMask = 0x01;
239     for (Int_t i = 0 + nStart; i < nStart + 12; i++) {
240       //Int_t channelBitMask = 0x01;
241       AliDebug(5, Form("channel: %d", i));
242
243       Int_t value = qtc1[i] - qtc0[i]; // calculate correct measurement value
244
245       if (value > (Int_t)this->fThreshold[i - nStart]) {
246         inputVector |= channelBitMask;    // Add bit
247           
248         AliDebug(5, Form("Threshold exceeded in channel %d,", i));
249         AliDebug(5, Form("new inputVector 0x%x", inputVector));       
250         AliDebug(5, Form("channelBitMask 0x%x", channelBitMask));
251       }
252       channelBitMask <<= 1; // go on to the next channel
253     }
254     
255     delete digits;
256     return inputVector;
257   }
258   return -1;
259 }
260
261 //______________________________________________________________________________
262 Int_t AliTRDptrgFEB::LoadAndProcessHits()
263 {
264   // loads TO or VO hits and converts them to digits optimized for ptrg  
265   // afterwards the digits will be discriminated
266   AliError("LoadAndProcessHits() - not yet implemented!\n");
267   if (this->fType == AliTRDptrgParam::kVZERO) {         
268     return 0;
269   }
270   else if (this->fType == AliTRDptrgParam::kTZERO) {
271     return 0;
272   }
273   return -1;
274 }
275
276 //______________________________________________________________________________
277 Bool_t AliTRDptrgFEB::LoadParams()
278 {
279   // Load Parameters
280
281   if (this->fParam == 0x0) {
282     AliWarning("No paramater object specified - start loading defaults\n");
283     if (this->fType == AliTRDptrgParam::kVZERO) {               
284       // initialize threshold
285       this->fThreshold = new UInt_t[8]; 
286       for (Int_t i = 0; i < 8; i++) {
287         this->fThreshold[i] = 10; 
288       }
289       // initialize LUTsoutputWidth=<value optimized out>
290       AliTRDptrgLUT* lut = new AliTRDptrgLUT();
291       this->fLUTArray.AddLast(lut);
292       lut = new AliTRDptrgLUT(); 
293       this->fLUTArray.AddLast(lut);
294                         // the following lines are only needed for test reasons
295       Int_t* initData = new Int_t[256]; // 2^8
296       lut = dynamic_cast<AliTRDptrgLUT*>(this->fLUTArray.At(0));
297       if (lut) {
298         for (Int_t i = 0; i < 256; i++ ) {
299           initData[i] = i;
300         }
301         lut->InitTable(8, 8, initData, kTRUE); // make copy of initData
302       }
303       lut = dynamic_cast<AliTRDptrgLUT*>(this->fLUTArray.At(1));
304       if (lut) {
305         for (Int_t i = 255; i >= 0; i--) {
306           initData[255 - i] = i;  // inverse ramp
307         }
308         lut->InitTable(8, 8, initData, kTRUE);
309       }
310       delete [] initData;
311     }
312     else {
313       // initialize threshold
314       this->fThreshold = new UInt_t[12];
315       for (Int_t i = 0; i < 12; i++) {
316         this->fThreshold[i] = 10; 
317       }
318       
319       // initialize LUTsoutputWidth=<value optimized out>
320       AliTRDptrgLUT* lut = new AliTRDptrgLUT();
321       this->fLUTArray.AddLast(lut);
322       lut = new AliTRDptrgLUT(); // this->fRunLoader
323       this->fLUTArray.AddLast(lut);
324       // the following lines are only needed for test reasons
325       lut = dynamic_cast<AliTRDptrgLUT*>(this->fLUTArray.At(0));
326       Int_t* initData = new Int_t[4096]; // 2^12
327       if (lut) {
328         for (Int_t i = 0; i < 4096; i++ ) {
329           initData[i] = i;
330         }
331         lut->InitTable(12, 12, initData, kTRUE); // make a copy of the table
332       }
333       lut = dynamic_cast<AliTRDptrgLUT*>(this->fLUTArray.At(1));
334       if (lut) {
335         //for (Int_t i = 4095; i >= 0; i--) {
336         for (Int_t i = 4096; i > 0; i--) {
337           initData[4096 - i] = i;  // inverse ramp
338         }
339         lut->InitTable(12, 12, initData, kTRUE); // make a copy of the table
340       }
341       delete [] initData;    
342     }
343     return false;
344   }
345   else {
346     // load parameters from object
347     if (this->fType == AliTRDptrgParam::kVZERO) {               
348       // threshold
349       this->fThreshold = 
350         this->fParam->GetFEBV0Thresholds(this->fPosition, (this->fID - 1));
351
352       // look up tables
353       // 1
354       AliTRDptrgLUT* LUT = new AliTRDptrgLUT();
355       LUT->InitTable(8, 8, this->fParam->GetFEBV0LUT(this->fPosition, 
356                                                      (this->fID - 1),
357                                                      0), kFALSE);
358       // do not make a copy of the table due to performance reasons
359       this->fLUTArray.AddLast(LUT);
360  
361       // 2
362       LUT = new AliTRDptrgLUT(); 
363       LUT->InitTable(8, 8, this->fParam->GetFEBV0LUT(this->fPosition, 
364                                                      (this->fID - 1),
365                                                      1), kFALSE);
366       // do not make a copy of the table due to performance reasons
367       this->fLUTArray.AddLast(LUT);
368     }
369     else {              
370       // threshold
371       this->fThreshold =
372         this->fParam->GetFEBT0Thresholds(this->fPosition);
373
374       // look up tables
375       // 1
376       AliTRDptrgLUT* LUT = new AliTRDptrgLUT();
377       LUT->InitTable(12, 12, fParam->GetFEBT0LUT(this->fPosition, 0), kFALSE); 
378       // do not make a copy of the table due to performance reasosn
379       this->fLUTArray.AddLast(LUT);
380
381       // 2
382       LUT = new AliTRDptrgLUT(); 
383       LUT->InitTable(12, 12, fParam->GetFEBT0LUT(this->fPosition, 1), kFALSE); 
384       // do not make a copy of the table due to performance reasosn      
385       this->fLUTArray.AddLast(LUT);
386     }
387     return true;
388   }
389   
390   return false;
391 }
392
393 //______________________________________________________________________________
394 Int_t* AliTRDptrgFEB::Simulate()
395 {
396   // simulates the FEB behavior and returns a 2 bit ouput 
397   // (least significant bits)
398   
399   Int_t *result = new Int_t;
400   (*result) = -1; 
401   if (this->fOperatingMode == AliTRDptrgParam::kDigits) {
402     Int_t inputVector = this->LoadDigits();
403     delete result; // delete error return value
404
405     // perform look up
406     Int_t nLUTs = this->fLUTArray.GetEntriesFast();  // get LUT count
407     result = new Int_t[nLUTs + 1]; // generate new return array
408     result[0] = nLUTs; // storage array length in the first array value
409     for (Int_t iLUT = 0; iLUT < nLUTs; iLUT++) { 
410       // process the return value for each LUT and store the result in the array
411       AliDebug(4, Form("FEB: (pos=%d,id=%d,lut=%d,vector=0x%x)", 
412                        this->fPosition, this->fID, iLUT, inputVector));
413
414       AliTRDptrgLUT *lutTmp = dynamic_cast<AliTRDptrgLUT*>(this->fLUTArray[iLUT]);
415       if (lutTmp) {
416         result[iLUT + 1] =  lutTmp->LookUp(inputVector);
417       }
418       AliDebug(4, Form("FEB result[%d] = 0x%x",(iLUT + 1),result[iLUT + 1])); 
419     }
420   }
421   else if (this->fOperatingMode == AliTRDptrgParam::kHits) {
422     return result;
423   }
424   return result;
425 }