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