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