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