2 /**************************************************************************
3 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
5 * Author: The ALICE Off-line Project. *
6 * Contributors are mentioned in the code where appropriate. *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
17 ////////////////////////////////////////////////////////////////////////////
19 // MCM configuraton handler //
21 // Author: U. Westerhoff //
23 ////////////////////////////////////////////////////////////////////////////
27 #include "AliTRDtrapConfigHandler.h"
32 #include "AliTRDpadPlane.h"
33 #include "AliTRDtrapConfig.h"
34 #include "AliTRDcalibDB.h"
35 #include "AliTRDCommonParam.h"
38 #include "AliTRDarrayDictionary.h"
41 #include "TGeoGlobalMagField.h"
42 #include "AliMagWrapCheb.h"
43 #include "AliTRDgeometry.h"
46 #include "TGeoMatrix.h"
50 ClassImp(AliTRDtrapConfigHandler)
53 AliTRDtrapConfigHandler::AliTRDtrapConfigHandler() :
62 , fPidTracklengthCorr(kFALSE)
65 fGeo = new AliTRDgeometry;
69 AliTRDtrapConfigHandler::~AliTRDtrapConfigHandler()
74 void AliTRDtrapConfigHandler::ResetMCMs()
77 // Reset all MCM registers and DMEM
80 AliTRDtrapConfig *cfg = AliTRDtrapConfig::Instance();
86 Int_t AliTRDtrapConfigHandler::LoadConfig(TString filename, Int_t det)
89 // load a TRAP configuration from a file
90 // The file format is the format created by the standalone
91 // command coder scc / show_cfdat but without the running number
92 // scc /show_cfdat adds as the first column
93 // which are two tools to inspect/export configurations from wingDB
103 AliTRDtrapConfig *cfg = AliTRDtrapConfig::Instance();
105 AliDebug(5, Form("Processing file %s", filename.Data()));
106 std::ifstream infile;
107 infile.open(filename.Data(), std::ifstream::in);
108 if (!infile.is_open()) {
109 AliError(Form("Can not open MCM configuration file %s", filename.Data()));
114 Int_t extali, addr, data;
116 while(infile.good()) {
121 infile >> std::skipws >> cmd >> addr >> data >> extali;
122 // std::cout << "no: " << no << ", cmd " << cmd << ", extali " << extali << ", addr " << addr << ", data " << data << endl;
124 if(cmd!=999 && extali!=-1 && addr != -1 && data!= -1 && extali!=-1) {
125 if(cmd==fgkScsnCmdWrite)
126 cfg->AddValues(det, cmd, extali, addr, data);
127 else if(cmd == fgkScsnLTUparam)
128 ProcessLTUparam(extali, addr, data);
134 else if(!infile.eof() && !infile.good()) {
136 infile.ignore(256, '\n');
146 AliDebug(5, Form("Ignored lines: %i, ignored cmds: %i", ignoredLines, ignoredCmds));
149 if(ignoredLines>readLines)
150 AliError(Form("More than 50 %% of the input file could not be processed. Perhaps you should check the input file %s", filename.Data()));
158 void AliTRDtrapConfigHandler::ProcessLTUparam(Int_t dest, Int_t addr, UInt_t data)
161 // Process the LTU parameters and stores them in internal class variables
162 // or transfer the stored values to AliTRDtrapConfig, depending on the dest parameter
167 case 0: // set the parameters in AliTRDtrapConfig
169 ConfigureDRange(); // deflection range
170 ConfigureNTimebins(); // timebins in the drift region
171 ConfigurePIDcorr(); // scaling parameters for the PID
174 case 1: // set variables
177 case 0: fPtMin = float(data) / 1000.; break; // pt_min in GeV/c (*1000)
178 case 1: fBField = float(data) / 1000. ; break; // B in T (*1000)
179 case 2: fOmegaTau = float(data) / 1.0E6 ; break; // omega*tau
180 case 3: fNTimebins = data; break;
181 // ntimbins: drift time (for 3 cm) in timebins (5 add. bin. digits)
182 case 4: fScaleQ0 = data; break;
183 case 5: fScaleQ1 = data; break;
184 case 6: fPidTracklengthCorr = (bool) data; break;
185 case 7: fTiltCorr = (bool) data; break;
190 AliError(Form("dest %i not implemented", dest));
196 void AliTRDtrapConfigHandler::ConfigureNTimebins()
199 // Set timebins in the drift region
201 AliTRDtrapConfig::Instance()->AddValues(fDet, fgkScsnCmdWrite, 127, AliTRDtrapConfig::fgkDmemAddrNdrift, fNTimebins);
206 void AliTRDtrapConfigHandler::ConfigureDyCorr()
209 // Deflection length correction
210 // due to Lorentz angle and tilted pad correction
211 // This correction is in units of padwidth / (256*32)
215 if(fGeo->GetStack(fDet) == 2)
220 Double_t dyLorentz = - fOmegaTau * fGeo->CdrHght(); // CdrHght: Height of the drift region
221 Double_t globalPos[3];
222 Double_t tiltingAngle = fGeo->GetPadPlane(fDet)->GetTiltingAngle();
223 Double_t scalePad = 256. * 32.;
226 for (Int_t r = 0; r < nRobs; r++) {
227 for (Int_t m = 0; m < 16; m++) {
228 if(GetPadPosNonRot(r, m, 9, globalPos)==0) {
229 double dyTilt = ( fGeo->CdrHght() * TMath::Tan(tiltingAngle * TMath::DegToRad()) * globalPos[2]/globalPos[0]);
233 dyCorr = dyLorentz + dyTilt;
238 dyCorrInt = TMath::Nint(dyCorr * scalePad / fGeo->GetPadPlane(fDet)->GetWidthIPad()); // The correction is in units of 1/256 of the
239 // pad width, including 5 binary digits
242 AliError("No transformation matrix available");
245 Int_t dest = 1<<10 | r<<7 | m;
246 AliTRDtrapConfig::Instance()->AddValues(fDet, fgkScsnCmdWrite, dest, AliTRDtrapConfig::fgkDmemAddrDeflCorr, dyCorrInt);
255 void AliTRDtrapConfigHandler::ConfigureDRange()
258 // deflection range LUT
259 // range calculated according to B-field (in T) and pt_min (in GeV/c)
260 // if pt_min < 0.1 GeV/c the maximal allowed range for the tracklet
261 // deflection (-64..63) is used
264 static const int x=0;
265 static const int y=1;
266 static const Double_t dyBin = 140e-6;
268 Int_t dyMinInt=fgkDyMinCut;
269 Int_t dyMaxInt=fgkDyMaxCut;
273 if(fGeo->GetStack(fDet) == 2)
278 for (Int_t r = 0; r < nRobs; r++) {
279 for (Int_t m = 0; m < 16; m++) {
280 for (Int_t c = 0; c < 18; c++) {
283 dyMinInt=fgkDyMinCut;
284 dyMaxInt=fgkDyMaxCut;
287 if(GetPadPosNonRot(r, m, c, mcmPos)==0) {
288 Double_t radius = fPtMin/(0.3*fBField);
290 double vertexPos[2] = {0,0};
292 Double_t distanceX = (vertexPos[x]-mcmPos[x]) / 100.; // cm -> m
293 Double_t distanceY = (vertexPos[y]-mcmPos[y]) / 100.; // cm -> m
295 Double_t maxDeflTemp = (TMath::Sqrt( Square(distanceX) + Square(distanceY)) / 2) / radius;
296 Double_t localPhi = TMath::ATan2(distanceY, distanceX);
298 Double_t maxDeflAngle=0;
299 if(maxDeflTemp < 1. ) {
300 maxDeflAngle = TMath::ASin(maxDeflTemp);
301 Double_t dyMin = fGeo->CdrHght()/100. * TMath::Tan(localPhi - maxDeflAngle); // CdrHght: Height of the drift region in cm
302 Double_t dyMax = fGeo->CdrHght()/100. * TMath::Tan(localPhi + maxDeflAngle);
304 dyMinInt = Int_t (dyMin / dyBin);
305 dyMaxInt = Int_t (dyMax / dyBin);
307 if(dyMinInt < fgkDyMinCut)
308 dyMinInt = fgkDyMinCut;
309 if(dyMaxInt > fgkDyMaxCut)
310 dyMaxInt = fgkDyMaxCut;
313 dyMinInt = fgkDyMinCut;
314 dyMaxInt = fgkDyMaxCut;
317 // cout << "maxdefl: " << maxDeflAngle << ", localPhi " << localPhi << endl;
318 // cout << "r " << r << ", m" << m << ", c " << c << ", min angle: " << localPhi-maxDeflAngle << ", max: " << localPhi+maxDeflAngle
319 // << ", min int: " << dyMinInt << ", max int: " << dyMaxInt << endl;
322 AliError("No geometry model loaded\n");
326 Int_t dest = 1<<10 | r<<7 | m;
327 Int_t lutAddr = AliTRDtrapConfig::fgkDmemAddrDeflCutStart + 2*c;
328 AliTRDtrapConfig::Instance()->AddValues(fDet, fgkScsnCmdWrite, dest, lutAddr+0, dyMinInt);
329 AliTRDtrapConfig::Instance()->AddValues(fDet, fgkScsnCmdWrite, dest, lutAddr+1, dyMaxInt);
335 void AliTRDtrapConfigHandler::PrintGeoTest()
338 // Prints some information about the geometry. Only for debugging
343 // for(int sm=0; sm<6; sm++) {
344 for(int stack=0; stack<5; stack++) {
345 for(int layer=0; layer<6; layer++) {
347 fDet = sm*30+stack*6+layer;
348 for (Int_t r = 0; r < 6; r++) {
349 for (Int_t m = 0; m < 16; m++) {
350 for (Int_t c = 7; c < 8; c++) {
351 GetPadPosNonRot(r, m, c, mcmPos);
352 cout << stack << ";" << layer << ";" << r << ";" << m
353 << ";" << mcmPos[0] << ";" << mcmPos[1] << ";" << mcmPos[2] << endl;
364 void AliTRDtrapConfigHandler::ConfigurePIDcorr()
367 // Calculate the MCM individual correction factors for the PID
368 // and transfer them to AliTRDtrapConfig
371 static const Int_t addrLUTcor0 = AliTRDtrapConfig::fgkDmemAddrLUTcor0;
372 static const Int_t addrLUTcor1 = AliTRDtrapConfig::fgkDmemAddrLUTcor1;
377 Double_t globalPos[3];
380 if(fGeo->GetStack(fDet) == 2)
385 for (Int_t r=0; r<nRobs; r++) {
386 for(Int_t m=0; m<16; m++) {
388 if(GetPadPosNonRot(r, m, 9, globalPos)==0) {
389 Double_t elongation = TMath::Abs(TMath::Sqrt(globalPos[0]*globalPos[0] + globalPos[1]*globalPos[1] + globalPos[2]*globalPos[2]) / globalPos[0]);
391 if(fPidTracklengthCorr==kFALSE) {
396 cor0 = Int_t ((1.0*fScaleQ0* (1/elongation) ));
397 cor1 = Int_t ((1.0*fScaleQ1* (1/elongation) ));
400 Int_t dest = 1<<10 | r<<7 | m;
401 AliTRDtrapConfig::Instance()->AddValues(fDet, fgkScsnCmdWrite, dest, addrLUTcor0, cor0);
402 AliTRDtrapConfig::Instance()->AddValues(fDet, fgkScsnCmdWrite, dest, addrLUTcor1, cor1);
405 AliError("No transformation matrix available");
413 Int_t AliTRDtrapConfigHandler::GetPadPosNonRot(Int_t rob, Int_t mcm, Int_t channel, Double_t trackCoor[3])
416 // Calcutate the gobal coordinates for an mcm channel in the supermodule at position -0.5
419 Int_t stack = fGeo->GetStack(fDet);
420 Int_t layer = fGeo->GetLayer(fDet);
422 AliTRDpadPlane *plane = fGeo->GetPadPlane(layer, stack);
424 AliError(Form("stack %i, layer %i, det %i", stack, layer, fDet));
431 Double_t radialPos = fGeo->AnodePos()-0.83; //
432 // Double_t radialPos = 300.65 + 12.60 * layer; // cm // taken from libTRD/geometry/geometry.cc, probably not the final value
434 GetLocalPadPos(plane, rob, mcm, channel, locYZ);
440 //transform from loc[3] - coordinates of the pad
441 // Go to tracking coordinates
443 TGeoHMatrix *fMatrix = fGeo->GetClusterMatrix(fDet);
445 AliError(Form("stack %i, layer %i, det %i", stack, layer, fDet));
448 fMatrix->LocalToMaster(loc, trackCoor);
453 void AliTRDtrapConfigHandler::GetLocalPadPos(AliTRDpadPlane *plane, Int_t rob, Int_t mcm, Int_t channel, Double_t result[2])
456 // calculate the local coordinates for an mcm channel
459 Double_t localY, localZ;
462 if(rob%2 == 0) //side a
463 padCol = (mcm % fgkMCMperROBCol) * fgkPadsPerMCM + channel;
465 padCol = (mcm % fgkMCMperROBCol) * fgkPadsPerMCM + (plane->GetNcols()/2) + channel;
467 Int_t padRow = ((Int_t) floor(rob/2.0)) * fgkMCMperROBRow + ((Int_t) floor(mcm/4));
469 if(padCol<0 || padCol>= plane->GetNcols())
470 AliError(Form("Invalid pad col: %i\n", padCol));
472 if(padRow<0 || padRow>= plane->GetNrows())
473 AliError(Form("Invalid pad row: %i\n", padRow));
475 if(padCol+1 == plane->GetNcols()) // last pad
476 localY = plane->GetColPos(padCol) + (plane->GetColEnd()-plane->GetColPos(padCol))/2;
478 localY = plane->GetColPos(padCol) + (plane->GetColPos(padCol+1)-plane->GetColPos(padCol))/2;
480 if(padRow+1 == plane->GetNrows())
481 localZ = plane->GetRowPosROC(padRow) + (plane->GetRowEndROC() - plane->GetRowPosROC(padRow))/2;
483 localZ = plane->GetRowPosROC(padRow) + (plane->GetRowPosROC(padRow+1) - plane->GetRowPosROC(padRow))/2;
485 // std::cout << "pad col " << padCol << ", pad row " << padRow << std::endl;
486 // std::cout << "pos y (col) " << localY << ", pos z (row) " << localZ << std::endl;
493 Double_t AliTRDtrapConfigHandler::Square(Double_t val)
496 // calculate the square of the argument