]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/AliMagF.cxx
Updates and bug fixes for the full tracker and hit reconstructor. (Indra)
[u/mrichter/AliRoot.git] / STEER / AliMagF.cxx
CommitLineData
4c039060 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
4c039060 16
db83d72f 17#include <TClass.h>
18#include <TFile.h>
19#include <TSystem.h>
33fe5eb1 20#include <TPRegexp.h>
fe4da5cc 21
22#include "AliMagF.h"
db83d72f 23#include "AliMagWrapCheb.h"
24#include "AliLog.h"
972ca52f 25
fe4da5cc 26ClassImp(AliMagF)
27
9251fceb 28const Double_t AliMagF::fgkSol2DipZ = -700.;
47c3d315 29const UShort_t AliMagF::fgkPolarityConvention = AliMagF::kConvLHC;
1dd3d90e 30/*
31 Explanation for polarity conventions: these are the mapping between the
32 current signs and main field components in L3 (Bz) and Dipole (Bx) (in Alice frame)
33 1) kConvMap2005: used for the field mapping in 2005
34 positive L3 current -> negative Bz
35 positive Dip current -> positive Bx
36 2) kConvMapDCS2008: defined by the microswitches/cabling of power converters as of 2008 - 1st half 2009
37 positive L3 current -> positive Bz
38 positive Dip current -> positive Bx
39 3) kConvLHC : defined by LHC
e3eadfac 40 positive L3 current -> positive Bz
1dd3d90e 41 positive Dip current -> negative Bx
42
43 Note: only "negative Bz(L3) with postive Bx(Dipole)" and its inverse was mapped in 2005. Hence
44 the GRP Manager will reject the runs with the current combinations (in the convention defined by the
45 static Int_t AliMagF::GetPolarityConvention()) which do not lead to such field polarities.
46*/
e2afb3b6 47//_______________________________________________________________________
48AliMagF::AliMagF():
db83d72f 49 TVirtualMagField(),
50 fMeasuredMap(0),
51 fMapType(k5kG),
52 fSolenoid(0),
53 fBeamType(kNoBeamField),
54 fBeamEnergy(0),
db83d72f 55 //
e2afb3b6 56 fInteg(0),
db83d72f 57 fPrecInteg(0),
58 fFactorSol(1.),
59 fFactorDip(1.),
60 fMax(15),
61 fDipoleOFF(kFALSE),
e2afb3b6 62 //
db83d72f 63 fQuadGradient(0),
64 fDipoleField(0),
65 fCCorrField(0),
66 fACorr1Field(0),
67 fACorr2Field(0),
68 fParNames("","")
69{
e2afb3b6 70 // Default constructor
71 //
72}
73
74//_______________________________________________________________________
4642ac4b 75AliMagF::AliMagF(const char *name, const char* title, Double_t factorSol, Double_t factorDip,
02233f2b 76 BMap_t maptype, BeamType_t bt, Double_t be,Int_t integ, Double_t fmax, const char* path):
db83d72f 77 TVirtualMagField(name),
78 fMeasuredMap(0),
79 fMapType(maptype),
80 fSolenoid(0),
02233f2b 81 fBeamType(bt),
82 fBeamEnergy(be),
db83d72f 83 //
84 fInteg(integ),
604e0531 85 fPrecInteg(1),
db83d72f 86 fFactorSol(1.),
87 fFactorDip(1.),
972ca52f 88 fMax(fmax),
db83d72f 89 fDipoleOFF(factorDip==0.),
90 //
91 fQuadGradient(0),
92 fDipoleField(0),
93 fCCorrField(0),
94 fACorr1Field(0),
95 fACorr2Field(0),
96 fParNames("","")
fe4da5cc 97{
9251fceb 98 // Initialize the field with Geant integration option "integ" and max field "fmax,
99 // Impose scaling of parameterized L3 field by factorSol and of dipole by factorDip.
100 // The "be" is the energy of the beam in GeV/nucleon
aee8290b 101 //
db83d72f 102 SetTitle(title);
103 if(integ<0 || integ > 2) {
104 AliWarning(Form("Invalid magnetic field flag: %5d; Helix tracking chosen instead",integ));
105 fInteg = 2;
106 }
107 if (fInteg == 0) fPrecInteg = 0;
aee8290b 108 //
4642ac4b 109 if (fBeamEnergy<=0 && fBeamType!=kNoBeamField) {
110 if (fBeamType == kBeamTypepp) fBeamEnergy = 7000.; // max proton energy
02233f2b 111 else if (fBeamType == kBeamTypeAA) fBeamEnergy = 2750; // max PbPb energy
4642ac4b 112 AliInfo("Maximim possible beam energy for requested beam is assumed");
113 }
db83d72f 114 const char* parname = 0;
115 //
f04e7f5f 116 if (fMapType == k2kG) parname = fDipoleOFF ? "Sol12_Dip0_Hole":"Sol12_Dip6_Hole";
117 else if (fMapType == k5kG) parname = fDipoleOFF ? "Sol30_Dip0_Hole":"Sol30_Dip6_Hole";
118 else if (fMapType == k5kGUniform) parname = "Sol30_Dip6_Uniform";
119 else AliFatal(Form("Unknown field identifier %d is requested\n",fMapType));
db83d72f 120 //
121 SetDataFileName(path);
122 SetParamName(parname);
123 //
db83d72f 124 LoadParameterization();
125 InitMachineField(fBeamType,fBeamEnergy);
f04e7f5f 126 double xyz[3]={0.,0.,0.};
127 fSolenoid = GetBz(xyz);
128 SetFactorSol(factorSol);
129 SetFactorDip(factorDip);
e86708b3 130 AliInfo(Form("Alice B fields: Solenoid (%+.2f*)%.0f kG, Dipole %s (%+.2f) %s",
131 factorSol,(fMapType==k5kG||fMapType==k5kGUniform)?5.:2.,
439b5096 132 fDipoleOFF ? "OFF":"ON",factorDip,fMapType==k5kGUniform?" |Constant Field!":""));
133 AliInfo(Form("Machine B fields for %s beam (%.0f GeV): QGrad: %.4f Dipole: %.4f",
02233f2b 134 bt==kBeamTypeAA ? "A-A":(bt==kBeamTypepp ? "p-p":"OFF"),be,fQuadGradient,fDipoleField));
fe4da5cc 135}
136
eeda4611 137//_______________________________________________________________________
138AliMagF::AliMagF(const AliMagF &src):
db83d72f 139 TVirtualMagField(src),
140 fMeasuredMap(0),
141 fMapType(src.fMapType),
142 fSolenoid(src.fSolenoid),
143 fBeamType(src.fBeamType),
144 fBeamEnergy(src.fBeamEnergy),
eeda4611 145 fInteg(src.fInteg),
146 fPrecInteg(src.fPrecInteg),
db83d72f 147 fFactorSol(src.fFactorSol),
148 fFactorDip(src.fFactorDip),
eeda4611 149 fMax(src.fMax),
db83d72f 150 fDipoleOFF(src.fDipoleOFF),
151 fQuadGradient(src.fQuadGradient),
152 fDipoleField(src.fDipoleField),
153 fCCorrField(src.fCCorrField),
154 fACorr1Field(src.fACorr1Field),
155 fACorr2Field(src.fACorr2Field),
156 fParNames(src.fParNames)
eeda4611 157{
db83d72f 158 if (src.fMeasuredMap) fMeasuredMap = new AliMagWrapCheb(*src.fMeasuredMap);
eeda4611 159}
160
e2afb3b6 161//_______________________________________________________________________
db83d72f 162AliMagF::~AliMagF()
ff66b122 163{
db83d72f 164 delete fMeasuredMap;
165}
166
167//_______________________________________________________________________
168Bool_t AliMagF::LoadParameterization()
169{
170 if (fMeasuredMap) {
171 AliError(Form("Field data %s are already loaded from %s\n",GetParamName(),GetDataFileName()));
172 return kTRUE;
173 }
ff66b122 174 //
db83d72f 175 char* fname = gSystem->ExpandPathName(GetDataFileName());
176 TFile* file = TFile::Open(fname);
177 if (!file) {
178 AliError(Form("Failed to open magnetic field data file %s\n",fname));
179 return kFALSE;
180 }
ff66b122 181 //
db83d72f 182 fMeasuredMap = dynamic_cast<AliMagWrapCheb*>(file->Get(GetParamName()));
183 if (!fMeasuredMap) {
184 AliError(Form("Did not find field %s in %s\n",GetParamName(),fname));
185 return kFALSE;
186 }
187 file->Close();
188 delete file;
189 return kTRUE;
ff66b122 190}
191
db83d72f 192
ff66b122 193//_______________________________________________________________________
db83d72f 194void AliMagF::Field(const Double_t *xyz, Double_t *b)
fe4da5cc 195{
db83d72f 196 // Method to calculate the field at point xyz
aee8290b 197 //
9251fceb 198 // b[0]=b[1]=b[2]=0.0;
199 if (fMeasuredMap && xyz[2]>fMeasuredMap->GetMinZ() && xyz[2]<fMeasuredMap->GetMaxZ()) {
db83d72f 200 fMeasuredMap->Field(xyz,b);
201 if (xyz[2]>fgkSol2DipZ || fDipoleOFF) for (int i=3;i--;) b[i] *= fFactorSol;
9251fceb 202 else for (int i=3;i--;) b[i] *= fFactorDip;
db83d72f 203 }
9251fceb 204 else MachineField(xyz, b);
aee8290b 205 //
fe4da5cc 206}
eeda4611 207
208//_______________________________________________________________________
db83d72f 209Double_t AliMagF::GetBz(const Double_t *xyz) const
eeda4611 210{
db83d72f 211 // Method to calculate the field at point xyz
212 //
9251fceb 213 if (fMeasuredMap && xyz[2]>fMeasuredMap->GetMinZ() && xyz[2]<fMeasuredMap->GetMaxZ()) {
214 double bz = fMeasuredMap->GetBz(xyz);
215 return (xyz[2]>fgkSol2DipZ || fDipoleOFF) ? bz*fFactorSol : bz*fFactorDip;
db83d72f 216 }
9251fceb 217 else return 0.;
eeda4611 218}
219
220//_______________________________________________________________________
db83d72f 221AliMagF& AliMagF::operator=(const AliMagF& src)
eeda4611 222{
db83d72f 223 if (this != &src && src.fMeasuredMap) {
224 if (fMeasuredMap) delete fMeasuredMap;
225 fMeasuredMap = new AliMagWrapCheb(*src.fMeasuredMap);
226 SetName(src.GetName());
227 fSolenoid = src.fSolenoid;
228 fBeamType = src.fBeamType;
229 fBeamEnergy = src.fBeamEnergy;
db83d72f 230 fInteg = src.fInteg;
231 fPrecInteg = src.fPrecInteg;
232 fFactorSol = src.fFactorSol;
233 fFactorDip = src.fFactorDip;
234 fMax = src.fMax;
235 fDipoleOFF = src.fDipoleOFF;
236 fParNames = src.fParNames;
237 }
238 return *this;
eeda4611 239}
240
241//_______________________________________________________________________
db83d72f 242void AliMagF::InitMachineField(BeamType_t btype, Double_t benergy)
eeda4611 243{
4642ac4b 244 if (btype==kNoBeamField) {
db83d72f 245 fQuadGradient = fDipoleField = fCCorrField = fACorr1Field = fACorr2Field = 0.;
9251fceb 246 return;
db83d72f 247 }
248 //
9251fceb 249 double rigScale = benergy/7000.; // scale according to ratio of E/Enominal
250 // for ions assume PbPb (with energy provided per nucleon) and account for A/Z
251 if (btype == kBeamTypeAA) rigScale *= 208./82.;
252 //
253 fQuadGradient = 22.0002*rigScale;
254 fDipoleField = 37.8781*rigScale;
255 //
256 // SIDE C
257 fCCorrField = -9.6980;
258 // SIDE A
259 fACorr1Field = -13.2247;
260 fACorr2Field = 11.7905;
db83d72f 261 //
eeda4611 262}
eed8a1a2 263
db83d72f 264//_______________________________________________________________________
265void AliMagF::MachineField(const Double_t *x, Double_t *b) const
eed8a1a2 266{
db83d72f 267 // ---- This is the ZDC part
9251fceb 268 // Compansators for Alice Muon Arm Dipole
269 const Double_t kBComp1CZ = 1075., kBComp1hDZ = 260./2., kBComp1SqR = 4.0*4.0;
270 const Double_t kBComp2CZ = 2049., kBComp2hDZ = 153./2., kBComp2SqR = 4.5*4.5;
271 //
272 const Double_t kTripQ1CZ = 2615., kTripQ1hDZ = 637./2., kTripQ1SqR = 3.5*3.5;
90ae20c9 273 const Double_t kTripQ2CZ = 3480., kTripQ2hDZ = 550./2., kTripQ2SqR = 3.5*3.5;
9251fceb 274 const Double_t kTripQ3CZ = 4130., kTripQ3hDZ = 550./2., kTripQ3SqR = 3.5*3.5;
275 const Double_t kTripQ4CZ = 5015., kTripQ4hDZ = 637./2., kTripQ4SqR = 3.5*3.5;
db83d72f 276 //
9251fceb 277 const Double_t kDip1CZ = 6310.8, kDip1hDZ = 945./2., kDip1SqRC = 4.5*4.5, kDip1SqRA = 3.375*3.375;
278 const Double_t kDip2CZ = 12640.3, kDip2hDZ = 945./2., kDip2SqRC = 4.5*4.5, kDip2SqRA = 3.75*3.75;
279 const Double_t kDip2DXC = 9.7, kDip2DXA = 9.4;
db83d72f 280 //
281 double rad2 = x[0] * x[0] + x[1] * x[1];
282 //
9251fceb 283 b[0] = b[1] = b[2] = 0;
284 //
db83d72f 285 // SIDE C **************************************************
286 if(x[2]<0.){
9251fceb 287 if(TMath::Abs(x[2]+kBComp2CZ)<kBComp2hDZ && rad2 < kBComp2SqR){
288 b[0] = fCCorrField*fFactorDip;
db83d72f 289 }
9251fceb 290 else if(TMath::Abs(x[2]+kTripQ1CZ)<kTripQ1hDZ && rad2 < kTripQ1SqR){
db83d72f 291 b[0] = fQuadGradient*x[1];
292 b[1] = fQuadGradient*x[0];
db83d72f 293 }
9251fceb 294 else if(TMath::Abs(x[2]+kTripQ2CZ)<kTripQ2hDZ && rad2 < kTripQ2SqR){
db83d72f 295 b[0] = -fQuadGradient*x[1];
296 b[1] = -fQuadGradient*x[0];
db83d72f 297 }
9251fceb 298 else if(TMath::Abs(x[2]+kTripQ3CZ)<kTripQ3hDZ && rad2 < kTripQ3SqR){
db83d72f 299 b[0] = -fQuadGradient*x[1];
300 b[1] = -fQuadGradient*x[0];
db83d72f 301 }
9251fceb 302 else if(TMath::Abs(x[2]+kTripQ4CZ)<kTripQ4hDZ && rad2 < kTripQ4SqR){
db83d72f 303 b[0] = fQuadGradient*x[1];
304 b[1] = fQuadGradient*x[0];
db83d72f 305 }
9251fceb 306 else if(TMath::Abs(x[2]+kDip1CZ)<kDip1hDZ && rad2 < kDip1SqRC){
db83d72f 307 b[1] = fDipoleField;
db83d72f 308 }
9251fceb 309 else if(TMath::Abs(x[2]+kDip2CZ)<kDip2hDZ && rad2 < kDip2SqRC) {
310 double dxabs = TMath::Abs(x[0])-kDip2DXC;
311 if ( (dxabs*dxabs + x[1]*x[1])<kDip2SqRC) {
db83d72f 312 b[1] = -fDipoleField;
db83d72f 313 }
314 }
315 }
316 //
317 // SIDE A **************************************************
318 else{
9251fceb 319 if(TMath::Abs(x[2]-kBComp1CZ)<kBComp1hDZ && rad2 < kBComp1SqR) {
db83d72f 320 // Compensator magnet at z = 1075 m
9251fceb 321 b[0] = fACorr1Field*fFactorDip;
db83d72f 322 }
323 //
9251fceb 324 if(TMath::Abs(x[2]-kBComp2CZ)<kBComp2hDZ && rad2 < kBComp2SqR){
325 b[0] = fACorr2Field*fFactorDip;
326 }
327 else if(TMath::Abs(x[2]-kTripQ1CZ)<kTripQ1hDZ && rad2 < kTripQ1SqR){
db83d72f 328 b[0] = -fQuadGradient*x[1];
329 b[1] = -fQuadGradient*x[0];
eed8a1a2 330 }
9251fceb 331 else if(TMath::Abs(x[2]-kTripQ2CZ)<kTripQ2hDZ && rad2 < kTripQ2SqR){
332 b[0] = fQuadGradient*x[1];
333 b[1] = fQuadGradient*x[0];
eed8a1a2 334 }
9251fceb 335 else if(TMath::Abs(x[2]-kTripQ3CZ)<kTripQ3hDZ && rad2 < kTripQ3SqR){
336 b[0] = fQuadGradient*x[1];
337 b[1] = fQuadGradient*x[0];
db83d72f 338 }
9251fceb 339 else if(TMath::Abs(x[2]-kTripQ4CZ)<kTripQ4hDZ && rad2 < kTripQ4SqR){
db83d72f 340 b[0] = -fQuadGradient*x[1];
341 b[1] = -fQuadGradient*x[0];
db83d72f 342 }
9251fceb 343 else if(TMath::Abs(x[2]-kDip1CZ)<kDip1hDZ && rad2 < kDip1SqRA){
db83d72f 344 b[1] = -fDipoleField;
db83d72f 345 }
9251fceb 346 else if(TMath::Abs(x[2]-kDip2CZ)<kDip2hDZ && rad2 < kDip2SqRA) {
347 double dxabs = TMath::Abs(x[0])-kDip2DXA;
348 if ( (dxabs*dxabs + x[1]*x[1])<kDip2SqRA) {
db83d72f 349 b[1] = fDipoleField;
350 }
351 }
352 }
9251fceb 353 //
db83d72f 354}
355
356//_______________________________________________________________________
357void AliMagF::GetTPCInt(const Double_t *xyz, Double_t *b) const
358{
47c3d315 359 // Method to calculate the integral_0^z of br,bt,bz
db83d72f 360 b[0]=b[1]=b[2]=0.0;
361 if (fMeasuredMap) {
362 fMeasuredMap->GetTPCInt(xyz,b);
363 for (int i=3;i--;) b[i] *= fFactorSol;
364 }
365}
366
47c3d315 367//_______________________________________________________________________
368void AliMagF::GetTPCRatInt(const Double_t *xyz, Double_t *b) const
369{
370 // Method to calculate the integral_0^z of bx/bz,by/bz and (bx/bz)^2+(by/bz)^2
371 b[0]=b[1]=b[2]=0.0;
372 if (fMeasuredMap) {
373 fMeasuredMap->GetTPCRatInt(xyz,b);
374 b[2] /= 100;
375 }
376}
377
db83d72f 378//_______________________________________________________________________
379void AliMagF::GetTPCIntCyl(const Double_t *rphiz, Double_t *b) const
380{
47c3d315 381 // Method to calculate the integral_0^z of br,bt,bz
db83d72f 382 // in cylindrical coordiates ( -pi<phi<pi convention )
383 b[0]=b[1]=b[2]=0.0;
384 if (fMeasuredMap) {
385 fMeasuredMap->GetTPCIntCyl(rphiz,b);
386 for (int i=3;i--;) b[i] *= fFactorSol;
387 }
eed8a1a2 388}
1dd3d90e 389
47c3d315 390//_______________________________________________________________________
391void AliMagF::GetTPCRatIntCyl(const Double_t *rphiz, Double_t *b) const
392{
393 // Method to calculate the integral_0^z of bx/bz,by/bz and (bx/bz)^2+(by/bz)^2
394 // in cylindrical coordiates ( -pi<phi<pi convention )
395 b[0]=b[1]=b[2]=0.0;
396 if (fMeasuredMap) {
397 fMeasuredMap->GetTPCRatIntCyl(rphiz,b);
398 b[2] /= 100;
399 }
400}
401
1dd3d90e 402//_______________________________________________________________________
403void AliMagF::SetFactorSol(Float_t fc)
404{
405 // set the sign/scale of the current in the L3 according to fgkPolarityConvention
406 switch (fgkPolarityConvention) {
407 case kConvDCS2008: fFactorSol = -fc; break;
408 case kConvLHC : fFactorSol = -fc; break;
409 default : fFactorSol = fc; break; // case kConvMap2005: fFactorSol = fc; break;
410 }
411}
412
413//_______________________________________________________________________
414void AliMagF::SetFactorDip(Float_t fc)
415{
416 // set the sign*scale of the current in the Dipole according to fgkPolarityConvention
417 switch (fgkPolarityConvention) {
418 case kConvDCS2008: fFactorDip = fc; break;
419 case kConvLHC : fFactorDip = -fc; break;
420 default : fFactorDip = fc; break; // case kConvMap2005: fFactorDip = fc; break;
421 }
422}
423
424//_______________________________________________________________________
425Double_t AliMagF::GetFactorSol() const
426{
427 // return the sign*scale of the current in the Dipole according to fgkPolarityConventionthe
428 switch (fgkPolarityConvention) {
429 case kConvDCS2008: return -fFactorSol;
430 case kConvLHC : return -fFactorSol;
431 default : return fFactorSol; // case kConvMap2005: return fFactorSol;
432 }
433}
434
435//_______________________________________________________________________
436Double_t AliMagF::GetFactorDip() const
437{
438 // return the sign*scale of the current in the Dipole according to fgkPolarityConventionthe
439 switch (fgkPolarityConvention) {
440 case kConvDCS2008: return fFactorDip;
441 case kConvLHC : return -fFactorDip;
442 default : return fFactorDip; // case kConvMap2005: return fFactorDip;
443 }
444}
33fe5eb1 445
446//_____________________________________________________________________________
447AliMagF* AliMagF::CreateFieldMap(Float_t l3Cur, Float_t diCur, Int_t convention, Bool_t uniform,
5cf76849 448 Float_t beamenergy, const Char_t *beamtype, const Char_t *path)
33fe5eb1 449{
450 //------------------------------------------------
451 // The magnetic field map, defined externally...
452 // L3 current 30000 A -> 0.5 T
453 // L3 current 12000 A -> 0.2 T
454 // dipole current 6000 A
455 // The polarities must match the convention (LHC or DCS2008)
456 // unless the special uniform map was used for MC
457 //------------------------------------------------
458 const Float_t l3NominalCurrent1=30000.; // (A)
459 const Float_t l3NominalCurrent2=12000.; // (A)
460 const Float_t diNominalCurrent =6000. ; // (A)
461
462 const Float_t tolerance=0.03; // relative current tolerance
463 const Float_t zero=77.; // "zero" current (A)
464 //
465 BMap_t map;
466 double sclL3,sclDip;
467 //
468 Float_t l3Pol = l3Cur > 0 ? 1:-1;
469 Float_t diPol = diCur > 0 ? 1:-1;
470
471 l3Cur = TMath::Abs(l3Cur);
472 diCur = TMath::Abs(diCur);
473 //
474 if (TMath::Abs((sclDip=diCur/diNominalCurrent)-1.) > tolerance && !uniform) {
475 if (diCur <= zero) sclDip = 0.; // some small current.. -> Dipole OFF
476 else {
477 AliErrorGeneral("AliMagF",Form("Wrong dipole current (%f A)!",diCur));
478 return 0;
479 }
480 }
481 //
482 if (uniform) {
483 // special treatment of special MC with uniform mag field (normalized to 0.5 T)
484 // no check for scaling/polarities are done
485 map = k5kGUniform;
486 sclL3 = l3Cur/l3NominalCurrent1;
487 }
488 else {
489 if (TMath::Abs((sclL3=l3Cur/l3NominalCurrent1)-1.) < tolerance) map = k5kG;
490 else if (TMath::Abs((sclL3=l3Cur/l3NominalCurrent2)-1.) < tolerance) map = k2kG;
e0418f7d 491 else if (l3Cur <= zero && diCur<=zero) { sclL3=0; sclDip=0; map = k5kGUniform;}
33fe5eb1 492 else {
493 AliErrorGeneral("AliMagF",Form("Wrong L3 current (%f A)!",l3Cur));
494 return 0;
495 }
496 }
497 //
17c30c5b 498 if (sclDip!=0 && map!=k5kGUniform) {
499 if ( (l3Cur<=zero) || ((convention==kConvLHC && l3Pol!=diPol) || (convention==kConvDCS2008 && l3Pol==diPol)) ) {
500 AliErrorGeneral("AliMagF",Form("Wrong combination for L3/Dipole polarities (%c/%c) for convention %d",
501 l3Pol>0?'+':'-',diPol>0?'+':'-',GetPolarityConvention()));
502 return 0;
503 }
33fe5eb1 504 }
505 //
506 if (l3Pol<0) sclL3 = -sclL3;
507 if (diPol<0) sclDip = -sclDip;
508 //
509 BeamType_t btype = kNoBeamField;
510 TString btypestr = beamtype;
511 btypestr.ToLower();
512 TPRegexp protonBeam("(proton|p)\\s*-?\\s*\\1");
513 TPRegexp ionBeam("(lead|pb|ion|a)\\s*-?\\s*\\1");
514 if (btypestr.Contains(ionBeam)) btype = kBeamTypeAA;
515 else if (btypestr.Contains(protonBeam)) btype = kBeamTypepp;
516 else AliInfoGeneral("AliMagF",Form("Assume no LHC magnet field for the beam type %s, ",beamtype));
517 char ttl[80];
518 sprintf(ttl,"L3: %+5d Dip: %+4d kA; %s | Polarities in %s convention",(int)TMath::Sign(l3Cur,float(sclL3)),
519 (int)TMath::Sign(diCur,float(sclDip)),uniform ? " Constant":"",
520 convention==kConvLHC ? "LHC":"DCS2008");
521 // LHC and DCS08 conventions have opposite dipole polarities
522 if ( GetPolarityConvention() != convention) sclDip = -sclDip;
523 //
5cf76849 524 return new AliMagF("MagneticFieldMap", ttl,sclL3,sclDip,map,btype,beamenergy,2,10.,path);
33fe5eb1 525 //
526}
527
528//_____________________________________________________________________________
529const char* AliMagF::GetBeamTypeText() const
530{
531 const char *beamNA = "No Beam";
532 const char *beamPP = "p-p";
533 const char *beamPbPb= "Pb-Pb";
534 switch ( fBeamType ) {
535 case kBeamTypepp : return beamPP;
536 case kBeamTypeAA : return beamPbPb;
537 case kNoBeamField:
538 default: return beamNA;
539 }
540}
541