- fix coverity
[u/mrichter/AliRoot.git] / TRD / AliTRDtrapConfigHandler.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 ////////////////////////////////////////////////////////////////////////////
17 //                                                                        //
18 //  MCM configuraton handler                                              //
19 //                                                                        //
20 //  Author: U. Westerhoff                                                 //
21 //                                                                        //
22 ////////////////////////////////////////////////////////////////////////////
23
24 #include "AliTRDtrapConfigHandler.h"
25
26 #include <iostream>
27 #include <sstream>
28 #include <iomanip>
29
30 #include "AliLog.h"
31
32 #include "AliTRDtrapConfig.h"
33 #include "AliTRDgeometry.h"
34 #include "AliTRDcalibDB.h"
35
36 #include "TMath.h"
37 #include "TGeoMatrix.h"
38 #include "TGraph.h"
39
40 #include "Cal/AliTRDCalOnlineGainTable.h"
41 #include "Cal/AliTRDCalOnlineGainTableROC.h"
42 #include "Cal/AliTRDCalOnlineGainTableMCM.h"
43
44 using namespace std;
45
46 ClassImp(AliTRDtrapConfigHandler)
47
48 AliTRDtrapConfigHandler::AliTRDtrapConfigHandler() :
49      ltuParam()
50      , fRestrictiveMask((0x3ffff << 11) | (0x1f << 6) | 0x3f)
51      , fGtbl()
52 {
53
54 }
55
56
57 AliTRDtrapConfigHandler::~AliTRDtrapConfigHandler()
58 {
59
60 }
61
62 void AliTRDtrapConfigHandler::ResetMCMs()
63 {
64    //
65    // Reset all MCM registers and DMEM
66    //
67
68    AliTRDtrapConfig *cfg = AliTRDtrapConfig::Instance();
69    cfg->ResetRegs();
70    cfg->ResetDmem();
71 }
72
73
74 Int_t AliTRDtrapConfigHandler::LoadConfig()
75 {
76   // load a default configuration which is suitable for simulation
77   // for a detailed description of the registers see the TRAP manual
78   // if you want to resimulate tracklets on real data use the appropriate config instead
79
80   AliTRDtrapConfig *cfg = AliTRDtrapConfig::Instance();
81
82   // HC header configuration bits
83   cfg->SetTrapReg(AliTRDtrapConfig::kC15CPUA, 0x2102); // zs, deh
84
85   // no. of timebins
86   cfg->SetTrapReg(AliTRDtrapConfig::kC13CPUA, 24);
87
88   // pedestal filter
89   cfg->SetTrapReg(AliTRDtrapConfig::kFPNP, 4*10);
90   cfg->SetTrapReg(AliTRDtrapConfig::kFPTC, 0);
91   cfg->SetTrapReg(AliTRDtrapConfig::kFPBY, 0); // bypassed!
92
93   // gain filter
94   for (Int_t adc = 0; adc < 20; adc++) {
95     cfg->SetTrapReg(AliTRDtrapConfig::TrapReg_t(AliTRDtrapConfig::kFGA0+adc), 40);
96     cfg->SetTrapReg(AliTRDtrapConfig::TrapReg_t(AliTRDtrapConfig::kFGF0+adc), 15);
97   }
98   cfg->SetTrapReg(AliTRDtrapConfig::kFGTA, 20);
99   cfg->SetTrapReg(AliTRDtrapConfig::kFGTB, 2060);
100   cfg->SetTrapReg(AliTRDtrapConfig::kFGBY, 0);  // bypassed!
101
102   // tail cancellation
103   cfg->SetTrapReg(AliTRDtrapConfig::kFTAL, 200);
104   cfg->SetTrapReg(AliTRDtrapConfig::kFTLL, 0);
105   cfg->SetTrapReg(AliTRDtrapConfig::kFTLS, 200);
106   cfg->SetTrapReg(AliTRDtrapConfig::kFTBY, 0);
107
108   // tracklet calculation
109   cfg->SetTrapReg(AliTRDtrapConfig::kTPQS0, 5);
110   cfg->SetTrapReg(AliTRDtrapConfig::kTPQE0, 10);
111   cfg->SetTrapReg(AliTRDtrapConfig::kTPQS1, 11);
112   cfg->SetTrapReg(AliTRDtrapConfig::kTPQE1, 20);
113   cfg->SetTrapReg(AliTRDtrapConfig::kTPFS, 5);
114   cfg->SetTrapReg(AliTRDtrapConfig::kTPFE, 20);
115   cfg->SetTrapReg(AliTRDtrapConfig::kTPVBY, 0);
116   cfg->SetTrapReg(AliTRDtrapConfig::kTPVT, 10);
117   cfg->SetTrapReg(AliTRDtrapConfig::kTPHT, 150);
118   cfg->SetTrapReg(AliTRDtrapConfig::kTPFP, 40);
119   cfg->SetTrapReg(AliTRDtrapConfig::kTPCL, 1);
120   cfg->SetTrapReg(AliTRDtrapConfig::kTPCT, 10);
121
122   // ndrift (+ 5 binary digits)
123   ltuParam.SetNtimebins(20 << 5);
124   // deflection + tilt correction
125   ltuParam.SetRawOmegaTau(0.16133);
126   // deflection range table
127   ltuParam.SetRawPtMin(0.1);
128   // magnetic field
129   ltuParam.SetRawMagField(0.0);
130   // scaling factors for q0, q1
131   ltuParam.SetRawScaleQ0(0);
132   ltuParam.SetRawScaleQ1(0);
133   // disable length correction and tilting correction
134   ltuParam.SetRawLengthCorrectionEnable(kFALSE);
135   ltuParam.SetRawTiltCorrectionEnable(kFALSE);
136
137   // apply ltuParams to all detectors
138   for(Int_t det=0; det<AliTRDgeometry::Ndet(); det++) {
139      ConfigureDyCorr(det);
140      ConfigureDRange(det); // deflection range
141      ConfigureNTimebins(det);  // timebins in the drift region
142      ConfigurePIDcorr(det);  // scaling parameters for the PID
143   }
144
145   // ****** hit position LUT
146
147   // now calculate it from PRF
148   AliTRDcalibDB *cal = AliTRDcalibDB::Instance();
149
150   Double_t padResponse[3]; // pad response left, central, right
151   Double_t padResponseR[3]; // pad response left, central, right
152   Double_t padResponseL[3]; // pad response left, central, right
153
154   for (Int_t iBin = 0; iBin < 128; iBin++)
155     cfg->SetTrapReg((AliTRDtrapConfig::TrapReg_t) (AliTRDtrapConfig::kTPL00 + iBin), 0, 0, 0, 0);
156
157   for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
158     TGraph gr(128);
159     for (Int_t iBin = 0; iBin < 256*0.5; iBin++) {
160       cal->PadResponse(1., iBin*1./256.,    iLayer, padResponse);
161       cal->PadResponse(1., iBin*1./256.-1., iLayer, padResponseR);
162       cal->PadResponse(1., iBin*1./256.+1., iLayer, padResponseL);
163       gr.SetPoint(iBin, (0.5 * (padResponseR[1] - padResponseL[1])/padResponse[1] * 256), iBin);
164     }
165     for (Int_t iBin = 0; iBin < 128; iBin++) {
166       Int_t corr = (Int_t) (gr.Eval(iBin)) - iBin;
167       if (corr < 0)
168         corr = 0;
169       else if (corr > 31)
170         corr = 31;
171       for (Int_t iStack = 0; iStack < 540/6; iStack++) {
172         cfg->SetTrapReg((AliTRDtrapConfig::TrapReg_t) (AliTRDtrapConfig::kTPL00 + iBin), corr, 6*iStack + iLayer);
173       }
174     }
175   }
176   // ****** hit position LUT configuration end
177
178   // event buffer
179   cfg->SetTrapReg(AliTRDtrapConfig::kEBSF, 1);  // 0: store filtered; 1: store unfiltered
180
181   // zs applied to data stored in event buffer (sel. by EBSF)
182   cfg->SetTrapReg(AliTRDtrapConfig::kEBIS, 15 << 2); // single indicator threshold (plus two digits)
183   cfg->SetTrapReg(AliTRDtrapConfig::kEBIT, 30 << 2); // sum indicator threshold (plus two digits)
184   cfg->SetTrapReg(AliTRDtrapConfig::kEBIL, 0xf0);   // lookup table
185   cfg->SetTrapReg(AliTRDtrapConfig::kEBIN, 0);      // neighbour sensitivity
186
187   // raw data
188   cfg->SetTrapReg(AliTRDtrapConfig::kNES, (0x0000 << 16) | 0x1000);
189
190   return 0;
191 }
192
193
194 Int_t AliTRDtrapConfigHandler::LoadConfig(TString filename)
195 {
196    //
197   // load a TRAP configuration from a file
198    // The file format is the format created by the standalone
199    // command coder scc / show_cfdat but without the running number
200    // scc /show_cfdat adds as the first column
201    // which are two tools to inspect/export configurations from wingDB
202    //
203
204    Int_t ignoredLines=0;
205    Int_t ignoredCmds=0;
206    Int_t readLines=0;
207
208
209    AliTRDtrapConfig *cfg = AliTRDtrapConfig::Instance();
210
211    AliDebug(5, Form("Processing file %s", filename.Data()));
212    std::ifstream infile;
213    infile.open(filename.Data(), std::ifstream::in);
214    if (!infile.is_open()) {
215     AliError(Form("Can not open MCM configuration file %s", filename.Data()));
216     return kFALSE;
217    }
218
219    UInt_t cmd;
220    Int_t extali, addr, data;
221
222    // reset restrictive mask
223    fRestrictiveMask = (0x3ffff << 11) | (0x1f << 6) | 0x3f;
224    char linebuffer[512];
225    istringstream line;
226
227    while(infile.getline(linebuffer, 512) && infile.good()) {
228       line.clear();
229       line.str(linebuffer);
230       cmd=999;
231       extali=-1;
232       addr=-1;
233       data=-1;
234       line >> std::skipws >> cmd >> addr >> data >> extali;  // the lines read from config file can contain additional columns.
235       // Therefore the detour via istringstream
236
237       if(cmd!=999 && addr != -1 && data!= -1 && extali!=-1) {
238
239          if(cmd==fgkScsnCmdWrite) {
240             for(Int_t det=0; det<AliTRDgeometry::Ndet(); det++) {
241                UInt_t rocpos = (1 << (AliTRDgeometry::GetSector(det)+11)) | (1 << (AliTRDgeometry::GetStack(det)+6)) | (1 << AliTRDgeometry::GetLayer(det));
242                AliDebug(1, Form("checking restriction: mask=0x%08x, rocpos=0x%08x", fRestrictiveMask, rocpos));
243                if ((fRestrictiveMask & rocpos) == rocpos) {
244                  AliDebug(1, Form("match: %i %i %i %i", cmd, extali, addr, data));
245                   cfg->AddValues(det, cmd, extali, addr, data);
246                }
247             }
248          }
249
250          else if(cmd == fgkScsnLTUparam) {
251             ProcessLTUparam(extali, addr, data);
252          }
253
254          else if(cmd == fgkScsnCmdRestr) {
255             fRestrictiveMask = data;
256            AliDebug(1, Form("updated restrictive mask to 0x%08x", fRestrictiveMask));
257          }
258
259          else if((cmd == fgkScsnCmdReset) ||
260                  (cmd == fgkScsnCmdRobReset)) {
261            cfg->ResetRegs();
262          }
263
264          else if (cmd == fgkScsnCmdSetHC) {
265            Int_t fullVersion = ((data & 0x7F00) >> 1) | (data & 0x7f);
266
267            for (Int_t iDet = 0; iDet < AliTRDgeometry::Ndet(); iDet++) {
268              Int_t smls = (AliTRDgeometry::GetSector(iDet) << 6) | (AliTRDgeometry::GetLayer(iDet) << 3) | AliTRDgeometry::GetStack(iDet);
269
270              for (Int_t iRob = 0; iRob < 8; iRob++) {
271                // HC mergers
272                cfg->SetTrapReg(AliTRDtrapConfig::kC14CPUA, 0xc << 16, iDet, iRob, 17);
273                cfg->SetTrapReg(AliTRDtrapConfig::kC15CPUA, ((1<<29) | (fullVersion<<15) | (1<<12) | (smls<<1) | (iRob%2)), iDet, iRob, 17);
274
275                // board mergers
276                cfg->SetTrapReg(AliTRDtrapConfig::kC14CPUA, 0, iDet, iRob, 16);
277                cfg->SetTrapReg(AliTRDtrapConfig::kC15CPUA, ((1<<29) | (fullVersion<<15) | (1<<12) | (smls<<1) | (iRob%2)), iDet, iRob, 16);
278
279                // and now for the others
280                for (Int_t iMcm = 0; iMcm < 16; iMcm++) {
281                  cfg->SetTrapReg(AliTRDtrapConfig::kC14CPUA, iMcm | (iRob << 4) | (3 << 16), iDet, iRob, iMcm);
282                  cfg->SetTrapReg(AliTRDtrapConfig::kC15CPUA, ((1<<29) | (fullVersion<<15) | (1<<12) | (smls<<1) | (iRob%2)), iDet, iRob, iMcm);
283                }
284              }
285            }
286          }
287
288          else if((cmd == fgkScsnCmdRead) ||
289                  (cmd == fgkScsnCmdPause) ||
290                  (cmd == fgkScsnCmdPtrg) ||
291                  (cmd == fgkScsnCmdHwPtrg) ||
292                  (cmd == fgkScsnCmdRobPower) ||
293                  (cmd == fgkScsnCmdTtcRx) ||
294                  (cmd == fgkScsnCmdMcmTemp) ||
295                  (cmd == fgkScsnCmdOri) ||
296                  (cmd == fgkScsnCmdPM) ) {
297            AliDebug(2, Form("ignored SCSN command: %i %i %i %i", cmd, addr, data, extali));
298          }
299
300          else {
301             AliWarning(Form("unknown SCSN command: %i %i %i %i", cmd, addr, data, extali));
302             ignoredCmds++;
303          }
304
305          readLines++;
306       }
307
308       else if(!infile.eof() && !infile.good()) {
309          infile.clear();
310          infile.ignore(256, '\n');
311          ignoredLines++;
312       }
313
314       if(!infile.eof())
315          infile.clear();
316    }
317
318    infile.close();
319
320    AliDebug(5, Form("Ignored lines: %i, ignored cmds: %i", ignoredLines, ignoredCmds));
321
322
323    if(ignoredLines>readLines)
324       AliError(Form("More than 50 %% of the input file could not be processed. Perhaps you should check the input file %s", filename.Data()));
325
326
327    return kTRUE;
328 }
329
330
331
332 Int_t AliTRDtrapConfigHandler::SetGaintable(AliTRDCalOnlineGainTable const &gtbl)
333 {
334    fGtbl=gtbl;
335    return 0;
336 }
337
338
339 void AliTRDtrapConfigHandler::ProcessLTUparam(Int_t dest, Int_t addr, UInt_t data)
340 {
341    //
342    // Process the LTU parameters and stores them in internal class variables
343    // or transfer the stored values to AliTRDtrapConfig, depending on the dest parameter
344    //
345
346    switch (dest) {
347
348    case 0: // set the parameters in AliTRDtrapConfig
349       for(Int_t det=0; det<AliTRDgeometry::Ndet(); det++) {
350          ConfigureDyCorr(det);
351          ConfigureDRange(det); // deflection range
352          ConfigureNTimebins(det);  // timebins in the drift region
353          ConfigurePIDcorr(det);  // scaling parameters for the PID
354       }
355       break;
356
357    case 1: // set variables
358       switch (addr) {
359
360       case 0: ltuParam.SetPtMin(data); break; // pt_min in GeV/c (*1000)
361       case 1: ltuParam.SetMagField(data); break; // B in T (*1000)
362       case 2: ltuParam.SetOmegaTau(data); break; // omega*tau
363       case 3: ltuParam.SetNtimebins(data); break;
364         // ntimbins: drift time (for 3 cm) in timebins (5 add. bin. digits)
365       case 4: ltuParam.SetScaleQ0(data); break;
366       case 5: ltuParam.SetScaleQ1(data); break;
367       case 6: ltuParam.SetLengthCorrectionEnable(data); break;
368       case 7: ltuParam.SetTiltCorrectionEnable(data); break;
369       }
370       break;
371
372    default:
373       AliError(Form("dest %i not implemented", dest));
374    }
375
376 }
377
378
379 void AliTRDtrapConfigHandler::ConfigureNTimebins(Int_t det)
380 {
381    //
382    // Set timebins in the drift region
383    //
384   AliTRDtrapConfig::Instance()->AddValues(det, fgkScsnCmdWrite, 127, AliTRDtrapConfig::fgkDmemAddrNdrift, ltuParam.GetNtimebins());
385 }
386
387
388
389 void AliTRDtrapConfigHandler::ConfigureDyCorr(Int_t det)
390 {
391    //
392    //  Deflection length correction
393    //  due to Lorentz angle and tilted pad correction
394    //  This correction is in units of padwidth / (256*32)
395    //
396
397    Int_t nRobs = AliTRDgeometry::GetStack(det) == 2 ? 6 : 8;
398
399   for (Int_t r = 0; r < nRobs; r++) {
400     for (Int_t m = 0; m < 16; m++) {
401       Int_t dest =  1<<10 | r<<7 | m;
402       Int_t dyCorrInt = ltuParam.GetDyCorrection(det, r, m);
403       AliTRDtrapConfig::Instance()->AddValues(det, fgkScsnCmdWrite, dest, AliTRDtrapConfig::fgkDmemAddrDeflCorr, dyCorrInt);
404     }
405   }
406 }
407
408
409
410
411
412 void AliTRDtrapConfigHandler::ConfigureDRange(Int_t det)
413 {
414    //
415    // deflection range LUT
416    // range calculated according to B-field (in T) and pt_min (in GeV/c)
417    // if pt_min < 0.1 GeV/c the maximal allowed range for the tracklet
418    // deflection (-64..63) is used
419    //
420
421   Int_t nRobs = AliTRDgeometry::GetStack(det) == 2 ? 6 : 8;
422
423   Int_t dyMinInt;
424   Int_t dyMaxInt;
425
426    for (Int_t r = 0; r < nRobs; r++) {
427       for (Int_t m = 0; m < 16; m++) {
428          for (Int_t c = 0; c < 18; c++) {
429
430            // cout << "maxdefl: " << maxDeflAngle << ", localPhi " << localPhi << endl;
431            // cout << "r " << r << ", m" << m << ", c " << c << ", min angle: " << localPhi-maxDeflAngle << ", max: " << localPhi+maxDeflAngle
432            //   << ", min int: " << dyMinInt << ", max int: " << dyMaxInt << endl;
433            Int_t dest =  1<<10 | r<<7 | m;
434            Int_t lutAddr = AliTRDtrapConfig::fgkDmemAddrDeflCutStart + 2*c;
435            ltuParam.GetDyRange(det, r, m, c, dyMinInt, dyMaxInt);
436            AliTRDtrapConfig::Instance()->AddValues(det, fgkScsnCmdWrite, dest, lutAddr+0, dyMinInt);
437            AliTRDtrapConfig::Instance()->AddValues(det, fgkScsnCmdWrite, dest, lutAddr+1, dyMaxInt);
438          }
439       }
440    }
441 }
442
443 void AliTRDtrapConfigHandler::PrintGeoTest()
444 {
445    //
446    // Prints some information about the geometry. Only for debugging
447    //
448
449    int sm=0;
450    //   for(int sm=0; sm<6; sm++) {
451    for(int stack=0; stack<5; stack++) {
452       for(int layer=0; layer<6; layer++) {
453
454          Int_t det = sm*30+stack*6+layer;
455          for (Int_t r = 0; r < 6; r++) {
456             for (Int_t m = 0; m < 16; m++) {
457                for (Int_t c = 7; c < 8; c++) {
458                  cout << stack << ";" << layer << ";" << r << ";" << m
459                       << ";" << ltuParam.GetX(det, r, m)
460                       << ";" << ltuParam.GetLocalY(det, r, m, c)
461                       << ";" << ltuParam.GetLocalZ(det, r, m) << endl;
462                }
463             }
464          }
465       }
466    }
467    // }
468 }
469
470
471 void AliTRDtrapConfigHandler::ConfigurePIDcorr(Int_t det)
472 {
473    //
474    // Calculate the MCM individual correction factors for the PID
475    // and transfer them to AliTRDtrapConfig
476    //
477
478    static const Int_t addrLUTcor0 = AliTRDtrapConfig::fgkDmemAddrLUTcor0;
479    static const Int_t addrLUTcor1 = AliTRDtrapConfig::fgkDmemAddrLUTcor1;
480
481    UInt_t cor0;
482    UInt_t cor1;
483
484    Int_t nRobs = AliTRDgeometry::GetStack(det) == 2 ? 6 : 8;
485
486    for (Int_t r=0; r<nRobs; r++) {
487       for(Int_t m=0; m<16; m++) {
488          Int_t dest =  1<<10 | r<<7 | m;
489          if(fGtbl.GetGainTableROC(det) && fGtbl.GetGainTableROC(det)->GetGainTableMCM(r, m))
490             ltuParam.GetCorrectionFactors(det, r, m, 9, cor0, cor1, fGtbl.GetGainTableROC(det)->GetGainTableMCM(r, m)->GetMCMGain());
491          else
492             ltuParam.GetCorrectionFactors(det, r, m, 9, cor0, cor1);
493          AliTRDtrapConfig::Instance()->AddValues(det, fgkScsnCmdWrite, dest, addrLUTcor0, cor0);
494          AliTRDtrapConfig::Instance()->AddValues(det, fgkScsnCmdWrite, dest, addrLUTcor1, cor1);
495     }
496   }
497 }