* provided "as is" without express or implied warranty. *
**************************************************************************/
-/*
-$Log$
-
-Revision 1.4 2000/03/28 12:40:24 fca
-Introduce factor for magnetic field
-
-
-Revision 1.3 1999/09/29 09:24:29 fca
-Introduction of the Copyright and cvs Log
-
-*/
+#include <TClass.h>
+#include <TFile.h>
+#include <TSystem.h>
+#include <TPRegexp.h>
#include "AliMagF.h"
-#include "TSystem.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-
-//ZDC part -------------------------------------------------------------------
-
- static const Float_t G1=20.03;
- static const Float_t FDIP=-37.34;
- static const Float_t FDIMU=6.;
- static const Float_t FCORN=11.72;
-//
-// ZBEG Beginning of the inner triplet
-// D1BEG Beginning of separator dipole 1
-// D2BEG Beginning of separator dipole 2
-// CORBEG Corrector dipole beginning (because of dimuon arm)
-//
- static const Float_t CORBEG=1920,COREND=CORBEG+190, CORRA2=4.5*4.5;
-//
- static const Float_t ZBEG=2300;
- static const Float_t Z1BEG=ZBEG+ 0,Z1END=Z1BEG+630,Z1RA2=3.5*3.5;
- static const Float_t Z2BEG=ZBEG+ 880,Z2END=Z2BEG+550,Z2RA2=3.5*3.5;
- static const Float_t Z3BEG=ZBEG+1530,Z3END=Z3BEG+550,Z3RA2=3.5*3.5;
- static const Float_t Z4BEG=ZBEG+2430,Z4END=Z4BEG+630,Z4RA2=3.5*3.5;
- static const Float_t D1BEG=5843.5 ,D1END=D1BEG+945,D1RA2=4.5*4.5;
- static const Float_t D2BEG=12113.2 ,D2END=D2BEG+945,D2RA2=4.5*.5;
-
-//ZDC part -------------------------------------------------------------------
+#include "AliMagWrapCheb.h"
+#include "AliLog.h"
ClassImp(AliMagF)
-//________________________________________
-AliMagF::AliMagF(const char *name, const char *title, const Int_t integ, const Int_t map,
- const Float_t factor, const Float_t fmax)
- : TNamed(name,title)
+const Double_t AliMagF::fgkSol2DipZ = -700.;
+const UShort_t AliMagF::fgkPolarityConvention = kConvLHC;
+
+/*
+ Explanation for polarity conventions: these are the mapping between the
+ current signs and main field components in L3 (Bz) and Dipole (Bx) (in Alice frame)
+ 1) kConvMap2005: used for the field mapping in 2005
+ positive L3 current -> negative Bz
+ positive Dip current -> positive Bx
+ 2) kConvMapDCS2008: defined by the microswitches/cabling of power converters as of 2008 - 1st half 2009
+ positive L3 current -> positive Bz
+ positive Dip current -> positive Bx
+ 3) kConvLHC : defined by LHC
+ positive L3 current -> positive Bz
+ positive Dip current -> negative Bx
+
+ Note: only "negative Bz(L3) with postive Bx(Dipole)" and its inverse was mapped in 2005. Hence
+ the GRP Manager will reject the runs with the current combinations (in the convention defined by the
+ static Int_t AliMagF::GetPolarityConvention()) which do not lead to such field polarities.
+*/
+//_______________________________________________________________________
+AliMagF::AliMagF():
+ TVirtualMagField(),
+ fMeasuredMap(0),
+ fMapType(k5kG),
+ fSolenoid(0),
+ fBeamType(kNoBeamField),
+ fBeamEnergy(0),
+ //
+ fInteg(0),
+ fPrecInteg(0),
+ fFactorSol(1.),
+ fFactorDip(1.),
+ fMax(15),
+ fDipoleOFF(kFALSE),
+ //
+ fQuadGradient(0),
+ fDipoleField(0),
+ fCCorrField(0),
+ fACorr1Field(0),
+ fACorr2Field(0),
+ fParNames("","")
{
- fMap = map;
- fType = Undef;
- fInteg = integ;
- fFactor = factor;
- fMax = fmax;
+ // Default constructor
+ //
}
-//________________________________________
-void AliMagF::Field(Float_t*, Float_t *b)
+//_______________________________________________________________________
+AliMagF::AliMagF(const char *name, const char* title, Double_t factorSol, Double_t factorDip,
+ BMap_t maptype, BeamType_t bt, Double_t be,Int_t integ, Double_t fmax, const char* path):
+ TVirtualMagField(name),
+ fMeasuredMap(0),
+ fMapType(maptype),
+ fSolenoid(0),
+ fBeamType(bt),
+ fBeamEnergy(be),
+ //
+ fInteg(integ),
+ fPrecInteg(1),
+ fFactorSol(1.),
+ fFactorDip(1.),
+ fMax(fmax),
+ fDipoleOFF(factorDip==0.),
+ //
+ fQuadGradient(0),
+ fDipoleField(0),
+ fCCorrField(0),
+ fACorr1Field(0),
+ fACorr2Field(0),
+ fParNames("","")
{
- printf("Undefined MagF Field called, returning 0\n");
- b[0]=b[1]=b[2]=0;
+ // Initialize the field with Geant integration option "integ" and max field "fmax,
+ // Impose scaling of parameterized L3 field by factorSol and of dipole by factorDip.
+ // The "be" is the energy of the beam in GeV/nucleon
+ //
+ SetTitle(title);
+ if(integ<0 || integ > 2) {
+ AliWarning(Form("Invalid magnetic field flag: %5d; Helix tracking chosen instead",integ));
+ fInteg = 2;
+ }
+ if (fInteg == 0) fPrecInteg = 0;
+ //
+ if (fBeamEnergy<=0 && fBeamType!=kNoBeamField) {
+ if (fBeamType == kBeamTypepp) fBeamEnergy = 7000.; // max proton energy
+ else if (fBeamType == kBeamTypeAA) fBeamEnergy = 2750; // max PbPb energy
+ AliInfo("Maximim possible beam energy for requested beam is assumed");
+ }
+ const char* parname = 0;
+ //
+ if (fMapType == k2kG) parname = fDipoleOFF ? "Sol12_Dip0_Hole":"Sol12_Dip6_Hole";
+ else if (fMapType == k5kG) parname = fDipoleOFF ? "Sol30_Dip0_Hole":"Sol30_Dip6_Hole";
+ else if (fMapType == k5kGUniform) parname = "Sol30_Dip6_Uniform";
+ else AliFatal(Form("Unknown field identifier %d is requested\n",fMapType));
+ //
+ SetDataFileName(path);
+ SetParamName(parname);
+ //
+ LoadParameterization();
+ InitMachineField(fBeamType,fBeamEnergy);
+ double xyz[3]={0.,0.,0.};
+ fSolenoid = GetBz(xyz);
+ SetFactorSol(factorSol);
+ SetFactorDip(factorDip);
+ AliInfo(Form("Alice B fields: Solenoid (%+.2f*)%.0f kG, Dipole %s (%+.2f) %s",
+ factorSol,(fMapType==k5kG||fMapType==k5kGUniform)?5.:2.,
+ fDipoleOFF ? "OFF":"ON",factorDip,fMapType==k5kGUniform?" |Constant Field!":""));
+ AliInfo(Form("Machine B fields for %s beam (%.0f GeV): QGrad: %.4f Dipole: %.4f",
+ bt==kBeamTypeAA ? "A-A":(bt==kBeamTypepp ? "p-p":"OFF"),be,fQuadGradient,fDipoleField));
}
-
-ClassImp(AliMagFC)
-//________________________________________
-AliMagFC::AliMagFC(const char *name, const char *title, const Int_t integ, const Int_t map,
- const Float_t factor, const Float_t fmax)
- : AliMagF(name,title,integ,map,factor,fmax)
+//_______________________________________________________________________
+AliMagF::AliMagF(const AliMagF &src):
+ TVirtualMagField(src),
+ fMeasuredMap(0),
+ fMapType(src.fMapType),
+ fSolenoid(src.fSolenoid),
+ fBeamType(src.fBeamType),
+ fBeamEnergy(src.fBeamEnergy),
+ fInteg(src.fInteg),
+ fPrecInteg(src.fPrecInteg),
+ fFactorSol(src.fFactorSol),
+ fFactorDip(src.fFactorDip),
+ fMax(src.fMax),
+ fDipoleOFF(src.fDipoleOFF),
+ fQuadGradient(src.fQuadGradient),
+ fDipoleField(src.fDipoleField),
+ fCCorrField(src.fCCorrField),
+ fACorr1Field(src.fACorr1Field),
+ fACorr2Field(src.fACorr2Field),
+ fParNames(src.fParNames)
{
- printf("Constant Field %s created: map= %d, factor= %f\n",fName.Data(),map,factor);
- fType = Const;
+ if (src.fMeasuredMap) fMeasuredMap = new AliMagWrapCheb(*src.fMeasuredMap);
}
-//________________________________________
-void AliMagFC::Field(Float_t *x, Float_t *b)
+//_______________________________________________________________________
+AliMagF::~AliMagF()
{
- b[0]=b[1]=b[2]=0;
- if(fMap==1) {
- if(TMath::Abs(x[2])<700 && x[0]*x[0]+(x[1]+30)*(x[1]+30) < 560*560) {
- b[2]=2;
- } else {
- if ( 725 <= x[2] && x[2] <= 1225 ) {
- Float_t dz = TMath::Abs(975-x[2])*0.01;
- b[0]=(1-0.1*dz*dz)*7;
- }
- else {
-//This is the ZDC part
- Float_t rad2=x[0]*x[0]+x[1]*x[1];
- if(rad2<D2RA2) {
- if(x[2]>D2BEG) {
-
-// Separator Dipole D2
- if(x[2]<D2END) b[1]=FDIP;
- } else if(x[2]>D1BEG) {
-
-// Separator Dipole D1
- if(x[2]<D1END) b[1]=-FDIP;
- }
- if(rad2<CORRA2) {
+ delete fMeasuredMap;
+}
-// First quadrupole of inner triplet de-focussing in x-direction
-// Inner triplet
- if(x[2]>Z4BEG) {
- if(x[2]<Z4END) {
-
-// 2430 <-> 3060
- b[0]=-G1*x[1];
- b[1]=-G1*x[0];
- }
- } else if(x[2]>Z3BEG) {
- if(x[2]<Z3END) {
+//_______________________________________________________________________
+Bool_t AliMagF::LoadParameterization()
+{
+ if (fMeasuredMap) {
+ AliError(Form("Field data %s are already loaded from %s\n",GetParamName(),GetDataFileName()));
+ return kTRUE;
+ }
+ //
+ char* fname = gSystem->ExpandPathName(GetDataFileName());
+ TFile* file = TFile::Open(fname);
+ if (!file) {
+ AliError(Form("Failed to open magnetic field data file %s\n",fname));
+ return kFALSE;
+ }
+ //
+ fMeasuredMap = dynamic_cast<AliMagWrapCheb*>(file->Get(GetParamName()));
+ if (!fMeasuredMap) {
+ AliError(Form("Did not find field %s in %s\n",GetParamName(),fname));
+ return kFALSE;
+ }
+ file->Close();
+ delete file;
+ return kTRUE;
+}
-// 1530 <-> 2080
- b[0]=G1*x[1];
- b[1]=G1*x[0];
- }
- } else if(x[2]>Z2BEG) {
- if(x[2]<Z2END) {
-
-// 890 <-> 1430
- b[0]=G1*x[1];
- b[1]=G1*x[0];
- }
- } else if(x[2]>Z1BEG) {
- if(x[2]<Z1END) {
-// 0 <-> 630
- b[0]=-G1*x[1];
- b[1]=-G1*x[0];
- }
- } else if(x[2]>CORBEG) {
- if(x[2]<COREND) {
-// Corrector dipole (because of dimuon arm)
- b[0]=FCORN;
- }
- }
- }
- }
- }
- }
- if(fFactor!=1) {
- b[0]*=fFactor;
- b[1]*=fFactor;
- b[2]*=fFactor;
- }
- } else {
- printf("Invalid field map for constant field %d\n",fMap);
- exit(1);
+//_______________________________________________________________________
+void AliMagF::Field(const Double_t *xyz, Double_t *b)
+{
+ // Method to calculate the field at point xyz
+ //
+ // b[0]=b[1]=b[2]=0.0;
+ if (fMeasuredMap && xyz[2]>fMeasuredMap->GetMinZ() && xyz[2]<fMeasuredMap->GetMaxZ()) {
+ fMeasuredMap->Field(xyz,b);
+ if (xyz[2]>fgkSol2DipZ || fDipoleOFF) for (int i=3;i--;) b[i] *= fFactorSol;
+ else for (int i=3;i--;) b[i] *= fFactorDip;
}
+ else MachineField(xyz, b);
+ //
}
-
-ClassImp(AliMagFCM)
-//________________________________________
-AliMagFCM::AliMagFCM(const char *name, const char *title, const Int_t integ, const Int_t map,
- const Float_t factor, const Float_t fmax)
- : AliMagF(name,title,integ,map,factor,fmax)
+//_______________________________________________________________________
+Double_t AliMagF::GetBz(const Double_t *xyz) const
{
- fType = ConMesh;
- printf("Constant Mesh Field %s created: map= %d, factor= %f, file= %s\n",fName.Data(),map,factor,fTitle.Data());
+ // Method to calculate the field at point xyz
+ //
+ if (fMeasuredMap && xyz[2]>fMeasuredMap->GetMinZ() && xyz[2]<fMeasuredMap->GetMaxZ()) {
+ double bz = fMeasuredMap->GetBz(xyz);
+ return (xyz[2]>fgkSol2DipZ || fDipoleOFF) ? bz*fFactorSol : bz*fFactorDip;
+ }
+ else return 0.;
}
-//________________________________________
-void AliMagFCM::Field(Float_t *x, Float_t *b)
+//_______________________________________________________________________
+AliMagF& AliMagF::operator=(const AliMagF& src)
{
- Double_t ratx, raty, ratz, hix, hiy, hiz, ratx1, raty1, ratz1,
- bhyhz, bhylz, blyhz, blylz, bhz, blz, xl[3];
- const Double_t one=1;
- Int_t ix, iy, iz;
-
- // --- find the position in the grid ---
-
- b[0]=b[1]=b[2]=0;
- if(-700<x[2] && x[2]<fZbeg && x[0]*x[0]+(x[1]+30)*(x[1]+30) < 560*560) {
- b[2]=2;
- } else {
- Bool_t infield=(fZbeg<=x[2] && x[2]<fZbeg+fZdel*(fZn-1)
- && ( fXbeg <= TMath::Abs(x[0]) && TMath::Abs(x[0]) < fXbeg+fXdel*(fXn-1) )
- && ( fYbeg <= TMath::Abs(x[1]) && TMath::Abs(x[1]) < fYbeg+fYdel*(fYn-1) ));
- if(infield) {
- xl[0]=TMath::Abs(x[0])-fXbeg;
- xl[1]=TMath::Abs(x[1])-fYbeg;
- xl[2]=x[2]-fZbeg;
-
- // --- start with x
-
- hix=xl[0]*fXdeli;
- ratx=hix-int(hix);
- ix=int(hix);
-
- hiy=xl[1]*fYdeli;
- raty=hiy-int(hiy);
- iy=int(hiy);
-
- hiz=xl[2]*fZdeli;
- ratz=hiz-int(hiz);
- iz=int(hiz);
-
- if(fMap==2) {
- // ... simple interpolation
- ratx1=one-ratx;
- raty1=one-raty;
- ratz1=one-ratz;
- bhyhz = Bx(ix ,iy+1,iz+1)*ratx1+Bx(ix+1,iy+1,iz+1)*ratx;
- bhylz = Bx(ix ,iy+1,iz )*ratx1+Bx(ix+1,iy+1,iz )*ratx;
- blyhz = Bx(ix ,iy ,iz+1)*ratx1+Bx(ix+1,iy ,iz+1)*ratx;
- blylz = Bx(ix ,iy ,iz )*ratx1+Bx(ix+1,iy ,iz )*ratx;
- bhz = blyhz *raty1+bhyhz *raty;
- blz = blylz *raty1+bhylz *raty;
- b[0] = blz *ratz1+bhz *ratz;
- //
- bhyhz = By(ix ,iy+1,iz+1)*ratx1+By(ix+1,iy+1,iz+1)*ratx;
- bhylz = By(ix ,iy+1,iz )*ratx1+By(ix+1,iy+1,iz )*ratx;
- blyhz = By(ix ,iy ,iz+1)*ratx1+By(ix+1,iy ,iz+1)*ratx;
- blylz = By(ix ,iy ,iz )*ratx1+By(ix+1,iy ,iz )*ratx;
- bhz = blyhz *raty1+bhyhz *raty;
- blz = blylz *raty1+bhylz *raty;
- b[1] = blz *ratz1+bhz *ratz;
- //
- bhyhz = Bz(ix ,iy+1,iz+1)*ratx1+Bz(ix+1,iy+1,iz+1)*ratx;
- bhylz = Bz(ix ,iy+1,iz )*ratx1+Bz(ix+1,iy+1,iz )*ratx;
- blyhz = Bz(ix ,iy ,iz+1)*ratx1+Bz(ix+1,iy ,iz+1)*ratx;
- blylz = Bz(ix ,iy ,iz )*ratx1+Bz(ix+1,iy ,iz )*ratx;
- bhz = blyhz *raty1+bhyhz *raty;
- blz = blylz *raty1+bhylz *raty;
- b[2] = blz *ratz1+bhz *ratz;
- //printf("ratx,raty,ratz,b[0],b[1],b[2] %f %f %f %f %f %f\n",
- //ratx,raty,ratz,b[0],b[1],b[2]);
- //
- // ... use the dipole symmetry
- if (x[0]*x[1] < 0) b[1]=-b[1];
- if (x[0]<0) b[2]=-b[2];
- } else {
- printf("Invalid field map for constant mesh %d\n",fMap);
- }
- } else {
-//This is the ZDC part
- Float_t rad2=x[0]*x[0]+x[1]*x[1];
- if(rad2<D2RA2) {
- if(x[2]>D2BEG) {
-
-// Separator Dipole D2
- if(x[2]<D2END) b[1]=FDIP;
- } else if(x[2]>D1BEG) {
-
-// Separator Dipole D1
- if(x[2]<D1END) b[1]=-FDIP;
- }
- if(rad2<CORRA2) {
-
-// First quadrupole of inner triplet de-focussing in x-direction
-// Inner triplet
- if(x[2]>Z4BEG) {
- if(x[2]<Z4END) {
-
-// 2430 <-> 3060
- b[0]=-G1*x[1];
- b[1]=-G1*x[0];
- }
- } else if(x[2]>Z3BEG) {
- if(x[2]<Z3END) {
-
-// 1530 <-> 2080
- b[0]=G1*x[1];
- b[1]=G1*x[0];
- }
- } else if(x[2]>Z2BEG) {
- if(x[2]<Z2END) {
+ if (this != &src && src.fMeasuredMap) {
+ if (fMeasuredMap) delete fMeasuredMap;
+ fMeasuredMap = new AliMagWrapCheb(*src.fMeasuredMap);
+ SetName(src.GetName());
+ fSolenoid = src.fSolenoid;
+ fBeamType = src.fBeamType;
+ fBeamEnergy = src.fBeamEnergy;
+ fInteg = src.fInteg;
+ fPrecInteg = src.fPrecInteg;
+ fFactorSol = src.fFactorSol;
+ fFactorDip = src.fFactorDip;
+ fMax = src.fMax;
+ fDipoleOFF = src.fDipoleOFF;
+ fParNames = src.fParNames;
+ }
+ return *this;
+}
-// 890 <-> 1430
- b[0]=G1*x[1];
- b[1]=G1*x[0];
- }
- } else if(x[2]>Z1BEG) {
- if(x[2]<Z1END) {
+//_______________________________________________________________________
+void AliMagF::InitMachineField(BeamType_t btype, Double_t benergy)
+{
+ if (btype==kNoBeamField) {
+ fQuadGradient = fDipoleField = fCCorrField = fACorr1Field = fACorr2Field = 0.;
+ return;
+ }
+ //
+ double rigScale = benergy/7000.; // scale according to ratio of E/Enominal
+ // for ions assume PbPb (with energy provided per nucleon) and account for A/Z
+ if (btype == kBeamTypeAA) rigScale *= 208./82.;
+ //
+ fQuadGradient = 22.0002*rigScale;
+ fDipoleField = 37.8781*rigScale;
+ //
+ // SIDE C
+ fCCorrField = -9.6980;
+ // SIDE A
+ fACorr1Field = -13.2247;
+ fACorr2Field = 11.7905;
+ //
+}
-// 0 <-> 630
- b[0]=-G1*x[1];
- b[1]=-G1*x[0];
- }
- } else if(x[2]>CORBEG) {
- if(x[2]<COREND) {
-// Corrector dipole (because of dimuon arm)
- b[0]=FCORN;
- }
- }
- }
+//_______________________________________________________________________
+void AliMagF::MachineField(const Double_t *x, Double_t *b) const
+{
+ // ---- This is the ZDC part
+ // Compansators for Alice Muon Arm Dipole
+ const Double_t kBComp1CZ = 1075., kBComp1hDZ = 260./2., kBComp1SqR = 4.0*4.0;
+ const Double_t kBComp2CZ = 2049., kBComp2hDZ = 153./2., kBComp2SqR = 4.5*4.5;
+ //
+ const Double_t kTripQ1CZ = 2615., kTripQ1hDZ = 637./2., kTripQ1SqR = 3.5*3.5;
+ const Double_t kTripQ2CZ = 3480., kTripQ2hDZ = 550./2., kTripQ2SqR = 3.5*3.5;
+ const Double_t kTripQ3CZ = 4130., kTripQ3hDZ = 550./2., kTripQ3SqR = 3.5*3.5;
+ const Double_t kTripQ4CZ = 5015., kTripQ4hDZ = 637./2., kTripQ4SqR = 3.5*3.5;
+ //
+ const Double_t kDip1CZ = 6310.8, kDip1hDZ = 945./2., kDip1SqRC = 4.5*4.5, kDip1SqRA = 3.375*3.375;
+ const Double_t kDip2CZ = 12640.3, kDip2hDZ = 945./2., kDip2SqRC = 4.5*4.5, kDip2SqRA = 3.75*3.75;
+ const Double_t kDip2DXC = 9.7, kDip2DXA = 9.4;
+ //
+ double rad2 = x[0] * x[0] + x[1] * x[1];
+ //
+ b[0] = b[1] = b[2] = 0;
+ //
+ // SIDE C **************************************************
+ if(x[2]<0.){
+ if(TMath::Abs(x[2]+kBComp2CZ)<kBComp2hDZ && rad2 < kBComp2SqR){
+ b[0] = fCCorrField*fFactorDip;
+ }
+ else if(TMath::Abs(x[2]+kTripQ1CZ)<kTripQ1hDZ && rad2 < kTripQ1SqR){
+ b[0] = fQuadGradient*x[1];
+ b[1] = fQuadGradient*x[0];
+ }
+ else if(TMath::Abs(x[2]+kTripQ2CZ)<kTripQ2hDZ && rad2 < kTripQ2SqR){
+ b[0] = -fQuadGradient*x[1];
+ b[1] = -fQuadGradient*x[0];
+ }
+ else if(TMath::Abs(x[2]+kTripQ3CZ)<kTripQ3hDZ && rad2 < kTripQ3SqR){
+ b[0] = -fQuadGradient*x[1];
+ b[1] = -fQuadGradient*x[0];
+ }
+ else if(TMath::Abs(x[2]+kTripQ4CZ)<kTripQ4hDZ && rad2 < kTripQ4SqR){
+ b[0] = fQuadGradient*x[1];
+ b[1] = fQuadGradient*x[0];
+ }
+ else if(TMath::Abs(x[2]+kDip1CZ)<kDip1hDZ && rad2 < kDip1SqRC){
+ b[1] = fDipoleField;
+ }
+ else if(TMath::Abs(x[2]+kDip2CZ)<kDip2hDZ && rad2 < kDip2SqRC) {
+ double dxabs = TMath::Abs(x[0])-kDip2DXC;
+ if ( (dxabs*dxabs + x[1]*x[1])<kDip2SqRC) {
+ b[1] = -fDipoleField;
}
}
}
- if(fFactor!=1) {
- b[0]*=fFactor;
- b[1]*=fFactor;
- b[2]*=fFactor;
+ //
+ // SIDE A **************************************************
+ else{
+ if(TMath::Abs(x[2]-kBComp1CZ)<kBComp1hDZ && rad2 < kBComp1SqR) {
+ // Compensator magnet at z = 1075 m
+ b[0] = fACorr1Field*fFactorDip;
+ }
+ //
+ if(TMath::Abs(x[2]-kBComp2CZ)<kBComp2hDZ && rad2 < kBComp2SqR){
+ b[0] = fACorr2Field*fFactorDip;
+ }
+ else if(TMath::Abs(x[2]-kTripQ1CZ)<kTripQ1hDZ && rad2 < kTripQ1SqR){
+ b[0] = -fQuadGradient*x[1];
+ b[1] = -fQuadGradient*x[0];
+ }
+ else if(TMath::Abs(x[2]-kTripQ2CZ)<kTripQ2hDZ && rad2 < kTripQ2SqR){
+ b[0] = fQuadGradient*x[1];
+ b[1] = fQuadGradient*x[0];
+ }
+ else if(TMath::Abs(x[2]-kTripQ3CZ)<kTripQ3hDZ && rad2 < kTripQ3SqR){
+ b[0] = fQuadGradient*x[1];
+ b[1] = fQuadGradient*x[0];
+ }
+ else if(TMath::Abs(x[2]-kTripQ4CZ)<kTripQ4hDZ && rad2 < kTripQ4SqR){
+ b[0] = -fQuadGradient*x[1];
+ b[1] = -fQuadGradient*x[0];
+ }
+ else if(TMath::Abs(x[2]-kDip1CZ)<kDip1hDZ && rad2 < kDip1SqRA){
+ b[1] = -fDipoleField;
+ }
+ else if(TMath::Abs(x[2]-kDip2CZ)<kDip2hDZ && rad2 < kDip2SqRA) {
+ double dxabs = TMath::Abs(x[0])-kDip2DXA;
+ if ( (dxabs*dxabs + x[1]*x[1])<kDip2SqRA) {
+ b[1] = fDipoleField;
+ }
+ }
}
+ //
}
-//________________________________________
-void AliMagFCM::ReadField()
+//_______________________________________________________________________
+void AliMagF::GetTPCInt(const Double_t *xyz, Double_t *b) const
{
- FILE *magfile;
- Int_t ix, iy, iz, ipx, ipy, ipz;
- Float_t bx, by, bz;
- char *fname;
- printf("Reading Magnetic Field %s from file %s\n",fName.Data(),fTitle.Data());
- fname = gSystem->ExpandPathName(fTitle.Data());
- magfile=fopen(fname,"r");
- delete [] fname;
- if (magfile) {
- fscanf(magfile,"%d %d %d %f %f %f %f %f %f",
- &fXn, &fYn, &fZn, &fXdel, &fYdel, &fZdel, &fXbeg, &fYbeg, &fZbeg);
- printf("fXn %d, fYn %d, fZn %d, fXdel %f, fYdel %f, fZdel %f, fXbeg %f, fYbeg %f, fZbeg %f\n",
- fXn, fYn, fZn, fXdel, fYdel, fZdel, fXbeg, fYbeg, fZbeg);
- fXdeli=1./fXdel;
- fYdeli=1./fYdel;
- fZdeli=1./fZdel;
- fB = new TVector(3*fXn*fYn*fZn);
- for (iz=0; iz<fZn; iz++) {
- ipz=iz*3*(fXn*fYn);
- for (iy=0; iy<fYn; iy++) {
- ipy=ipz+iy*3*fXn;
- for (ix=0; ix<fXn; ix++) {
- ipx=ipy+ix*3;
- fscanf(magfile,"%f %f %f",&bz,&by,&bx);
- (*fB)(ipx+2)=bz;
- (*fB)(ipx+1)=by;
- (*fB)(ipx )=bx;
- }
- }
- }
- } else {
- printf("File %s not found !\n",fTitle.Data());
- exit(1);
+ // Method to calculate the integral of magnetic integral from xyz to nearest cathode plane
+ b[0]=b[1]=b[2]=0.0;
+ if (fMeasuredMap) {
+ fMeasuredMap->GetTPCInt(xyz,b);
+ for (int i=3;i--;) b[i] *= fFactorSol;
}
}
-// -------------------------------------------------------
-
-ClassImp(AliMagFDM)
-//________________________________________
-AliMagFDM::AliMagFDM(const char *name, const char *title, const Int_t integ,
-const Int_t map, const Float_t factor, const Float_t fmax)
- : AliMagF(name,title,integ,map,factor,fmax)
-
+//_______________________________________________________________________
+void AliMagF::GetTPCIntCyl(const Double_t *rphiz, Double_t *b) const
{
- fType = DipoMap;
-
- printf("Field Map for Muon Arm from IP till muon filter %s created: map= %d, factor= %f, file=%s\n",fName.Data(),map,factor,fTitle.Data());
-
+ // Method to calculate the integral of magnetic integral from point to nearest cathode plane
+ // in cylindrical coordiates ( -pi<phi<pi convention )
+ b[0]=b[1]=b[2]=0.0;
+ if (fMeasuredMap) {
+ fMeasuredMap->GetTPCIntCyl(rphiz,b);
+ for (int i=3;i--;) b[i] *= fFactorSol;
+ }
}
-//________________________________________
-
-void AliMagFDM::Field(Float_t *xfi, Float_t *b)
+//_______________________________________________________________________
+void AliMagF::SetFactorSol(Float_t fc)
{
- static const Double_t eps=0.1E-06;
- static const Double_t pi2=.6283185E+01;
- static const Double_t one=1;
- static const Double_t fdYaxi = 0.3;
-
- static const Int_t kiip=33;
- static const Int_t miip=0;
- static const Int_t liip=0;
-
- static const Int_t kiic=0;
- static const Int_t miic=0;
- static const Int_t liic=0;
-
- static const Double_t fdZbg=502.92; // Start of Map using in z
- static const Double_t fdZL3=600; // Beginning of L3 door in z
-
- Double_t x[3];
- Double_t xL3[3];
- Double_t bint[3];
-
- Double_t r0;
-
- Double_t bbj;
- Int_t Kvar,jb;
-
- Double_t Zp1, Zp2,Xp1,Xp2,Yp1,Yp2;
- Double_t Zz1, Zz2,Yy1,Yy2,X2,X1;
-
-// --- start the map fiel from z = 502.92 cm ---
-
- x[0] = xfi[0];
- x[1] = xfi[1];
- x[2] = xfi[2];
- b[0]=b[1]=b[2]=0;
- // printf("x[0] %f,x[1] %f,x[2] %f\n",x[0],x[1],x[2]);
-
- Double_t rr=TMath::Sqrt(x[0]*x[0]+x[1]*x[1]);
- r0=rr/100;
- Double_t Rpmax;
- Rpmax=fdRmax;
- if ( (-700<x[2] && x[2]<=fdZbg &&
- (x[0]*x[0]+(x[1]+30)*(x[1]+30))< 560*560)
- || (fdZbg<x[2] && x[2]<=fdZL3 && rr>=Rpmax*100) )
- {
- b[2]=2;
- }
-
- xL3[0]=x[0]/100;
- xL3[1]=(x[1]+30)/100;
- xL3[2]=x[2]/100;
-
- Double_t xminn=xL3[2]*fdAx1+fdCx1;
- Double_t xmaxx=xL3[2]*fdAx2+fdCx2;
- Double_t Zcmin,Zcmax,Ycmin,Ycmax;
-
- Zcmin=fdZmin;
- Zcmax=fdZmax;
- Ycmin=fdYmin;
- Ycmax=fdYmax;
-
-if ((fdZbg/100<xL3[2] && xL3[2]<Zcmin && r0<Rpmax) || ((Zcmin<=xL3[2] && xL3[2] <= Zcmax ) && (Ycmin<=xL3[1] && xL3[1]<= Ycmax) && (xminn <= xL3[0] && xL3[0] <= xmaxx)))
- {
- if(fMap==3)
- {
- if (xL3[2]<Zcmin && r0<Rpmax)
- {
- //--------------------- Polar part ----------------------
-
- Double_t yyp,ph0;
- Int_t kp0, lp0, mp0;
- Int_t kpi,lpi,mpi;
- Double_t alp1,alp2,alp3;
- Double_t zpz,rp,fip,cphi;
-
- kpi=kiip;
- lpi=liip;
- mpi=miip;
-
- zpz=xL3[2];
-
- FZ(&zpz, fdZp ,&fdZpdl,&kpi,&kp0,&Zp1 ,&Zp2,&fdZpl) ;
-
- yyp=xL3[1]- 0.3;
- cphi=yyp/r0;
- ph0=TMath::ACos(cphi);
- if (xL3[0]< 0) {ph0=pi2 - ph0;}
-
- fip=ph0;
- FZ(&fip,fdPhi,&fdPhid ,&mpi,&mp0, &Xp1,&Xp2,&fdPhin);
-
- Double_t Rdel;
- Rdel=fdRdel;
-
- if (r0<= fdRdel)
- {
-
- if(r0< eps)
- {
-
- bint[0]=(Zp1*fdBpx[kp0][0][0] + Zp2*fdBpx[kp0+1][0][0])*10;
- bint[1]=(Zp1*fdBpy[kp0][0][0] + Zp2*fdBpy[kp0+1][0][0])*10;
- bint[2]=(Zp1*fdBpz[kp0][0][0] + Zp2*fdBpz[kp0+1][0][0])*10;
-
- }
-
- alp2= fdB[0][0][mp0]*yyp + fdB[0][1][mp0]*xL3[0];
- alp3= fdB[1][0][mp0]*yyp + fdB[1][1][mp0]*xL3[0];
- alp1= one - alp2 - alp3;
-
- for (jb=0; jb<3 ; jb++)
- {
- Kvar=jb;
- FRfuncBi(&Kvar,&Zp1,&Zp2,&alp1,&alp2,&alp3, &kp0,&mp0, &bbj);
- bint[jb] = bbj*10 ;
- }
- }
- else
- {
- rp=r0;
-
- FZ(&rp,fdR ,&fdRdel,&lpi,&lp0,&Yp1,&Yp2,&fdRn);
-
- for (jb=0; jb<3 ; jb++)
- {
- Kvar=jb;
- FGfuncBi(&Zp1,&Zp2,&Yp1,&Yp2,&Xp1,&Xp2,&Kvar,&kp0,&lp0,&mp0,&bbj);
-
- bint[jb] = bbj*10 ;
- }
- }
-
- b[0]=bint[0];
- b[1]=bint[1];
- b[2]=bint[2];
-
-// fprintf(fitest,"------------- Freg2 run -------------\n");
-
- }
- else
- {
- //-------------- Cartensian part ------------------
-
- Double_t zzc,yyc;
- Int_t k0, l0,m0;
- Double_t xx1, xx2,dx, xxx ,xXl;
- Int_t kci,mci,lci;
-
- kci=kiic;
- lci=liic;
- mci=miic;
-
- xx1 = fdAx1*xL3[2] + fdCx1;
- xx2 = fdAx2*xL3[2] + fdCx2;
-
- zzc=xL3[2];
- FZ(&zzc, fdZc ,&fdZdel, &kci,&k0, &Zz1, &Zz2, &fdZl);
-
- yyc=xL3[1];
- FZ(&yyc, fdY , &fdYdel,&lci, &l0, &Yy1, &Yy2,&fdYl);
-
- xXl = fdXl-one;
- dx = (xx2-xx1)/xXl;
- xxx= xL3[0]-xx1;
- // xm = xxx/dx;
- m0 = int(xxx/dx);
-
- if(xL3[0]<(xx1+m0*dx) || xL3[0] >(xx1+(m0+1)*dx))
- {
- m0=m0+1;
- printf(" m0 %d, m0+1 %d\n",m0,m0+1);
- }
-
- X2=(xL3[0]-( xx1+m0*dx))/dx;
- X1=one-X2;
- m0=m0-1;
- for (jb=3; jb<6; jb++)
- {
- Kvar=jb;
- FGfuncBi(&Zz1,&Zz2,&Yy1,&Yy2,&X1,&X2,&Kvar,&k0, &l0, &m0, &bbj);
- bint[jb-3] = bbj*10 ;
- }
-
- b[0]=bint[0];
- b[1]=bint[1];
- b[2]=bint[2];
-
-// fprintf(fitest,"------------ Freg1 run -----------------\n");
- }
-
- } else {
- printf("Unknown map of Dipole region %d\n",fMap);
- }
-
-} else {
-
-//This is the ZDC part
- Float_t rad2=x[0]*x[0]+x[1]*x[1];
- if(rad2<D2RA2) {
- if(x[2]>D2BEG) {
-
-// Separator Dipole D2
- if(x[2]<D2END) b[1]=FDIP;
- } else if(x[2]>D1BEG) {
-
-// Separator Dipole D1
- if(x[2]<D1END) b[1]=-FDIP;
- }
- if(rad2<CORRA2) {
-
-// First quadrupole of inner triplet de-focussing in x-direction
-// Inner triplet
- if(x[2]>Z4BEG) {
- if(x[2]<Z4END) {
-
-// 2430 <-> 3060
- b[0]=-G1*x[1];
- b[1]=-G1*x[0];
- }
- } else if(x[2]>Z3BEG) {
- if(x[2]<Z3END) {
-
-// 1530 <-> 2080
- b[0]=G1*x[1];
- b[1]=G1*x[0];
- }
- } else if(x[2]>Z2BEG) {
- if(x[2]<Z2END) {
-
-// 890 <-> 1430
- b[0]=G1*x[1];
- b[1]=G1*x[0];
- }
- } else if(x[2]>Z1BEG) {
- if(x[2]<Z1END) {
-
-// 0 <-> 630
- b[0]=-G1*x[1];
- b[1]=-G1*x[0];
- }
- } else if(x[2]>CORBEG) {
- if(x[2]<COREND) {
-// Corrector dipole (because of dimuon arm)
-// b[0]=FCORN;
- b[0]=-FCORN;
- }
- }
- }
- }
- }
-
- if(fFactor!=1) {
- b[0]*=fFactor;
- b[1]*=fFactor;
- b[2]*=fFactor;
+ // set the sign/scale of the current in the L3 according to fgkPolarityConvention
+ switch (fgkPolarityConvention) {
+ case kConvDCS2008: fFactorSol = -fc; break;
+ case kConvLHC : fFactorSol = -fc; break;
+ default : fFactorSol = fc; break; // case kConvMap2005: fFactorSol = fc; break;
}
}
-//_________________________________________
-
-void AliMagFDM::FZ(Double_t *u, Float_t *Ar, Float_t *du,Int_t *ki,Int_t *kf,Double_t *a1,Double_t *a2 ,Int_t *nu)
-
- {
- static const Double_t one=1;
- Int_t l,ik,ikj;
- Double_t temp;
- Double_t ddu,delu,ar;
-
- Int_t nk,ku;
- temp=*u;
- nk=*nu;
- ik=*ki;
- delu=*du;
-
- ar=Ar[ik];
- ddu=temp-ar;
-
- ku=int(ddu/delu);
- ikj=ik+ku;
- if (ddu<=0) ikj=0;
-
- for(l=ikj; l<nk; l++)
- {
-
- if(temp < Ar[l])
- {
- *kf=l;
- *a2=(temp-Ar[l])/(Ar[l+1]-Ar[l]);
- *a1= one - *a2;
- break;
- }
- }
+//_______________________________________________________________________
+void AliMagF::SetFactorDip(Float_t fc)
+{
+ // set the sign*scale of the current in the Dipole according to fgkPolarityConvention
+ switch (fgkPolarityConvention) {
+ case kConvDCS2008: fFactorDip = fc; break;
+ case kConvLHC : fFactorDip = -fc; break;
+ default : fFactorDip = fc; break; // case kConvMap2005: fFactorDip = fc; break;
}
+}
-/*-------------FRfuncBi----------------*/
-
-void AliMagFDM::FRfuncBi(Int_t *kai,Double_t *za1, Double_t *za2, Double_t *al1, Double_t *al2, Double_t *al3, Int_t *ka, Int_t *ma, Double_t *ba)
-
+//_______________________________________________________________________
+Double_t AliMagF::GetFactorSol() const
{
-Double_t fa11,fa12,fa13;
-Double_t fa21,fa22,fa23;
-Double_t faY1,faY2;
-Double_t bba;
-
-Double_t zaa1,zaa2,alf1,alf2,alf3;
-Int_t kaai,kaa,maa;
-kaai=*kai;
-kaa=*ka;
-maa=*ma;
-zaa1=*za1;
-zaa2=*za2;
-alf1=*al1;
-alf2=*al2;
-alf3=*al3;
-
- if (kaai==0 ) {
- fa11 = fdBpx[kaa][0][0];
- fa12 = fdBpx[kaa][0][maa];
- fa13 = fdBpx[kaa][0][maa+1];
- fa21 = fdBpx[kaa+1][0][0];
- fa22 = fdBpx[kaa+1][0][maa];
- fa23 = fdBpx[kaa+1][0][maa+1];
- }
- if (kaai==1 ) {
- fa11 = fdBpy[kaa][0][0];
- fa12 = fdBpy[kaa][0][maa];
- fa13 = fdBpy[kaa][0][maa+1];
- fa21 = fdBpy[kaa+1][0][0];
- fa22 = fdBpy[kaa+1][0][maa];
- fa23 = fdBpy[kaa+1][0][maa+1];
- }
- if (kaai==2 ) {
- fa11 = fdBpz[kaa][0][0];
- fa12 = fdBpz[kaa][0][maa];
- fa13 = fdBpz[kaa][0][maa+1];
- fa21 = fdBpz[kaa+1][0][0];
- fa22 = fdBpz[kaa+1][0][maa];
- fa23 = fdBpz[kaa+1][0][maa+1];
- }
- faY1=alf1*fa11+alf2*fa12+alf3*fa13;
- faY2=alf1*fa21+alf2*fa22+alf3*fa23;
- bba = zaa1*faY1+zaa2*faY2;
- *ba=bba;
-
+ // return the sign*scale of the current in the Dipole according to fgkPolarityConventionthe
+ switch (fgkPolarityConvention) {
+ case kConvDCS2008: return -fFactorSol;
+ case kConvLHC : return -fFactorSol;
+ default : return fFactorSol; // case kConvMap2005: return fFactorSol;
+ }
}
-
-/*----------- FGfuncBi------------*/
-
-void AliMagFDM::FGfuncBi(Double_t *zz1,Double_t *zz2, Double_t *yy1,Double_t *yy2, Double_t *xx1,Double_t *xx2, Int_t *kvr, Int_t *kk, Int_t *ll, Int_t *mm, Double_t *bb)
-
-{
-Double_t fy1, fy2, ffy;
-Double_t gy1,gy2,ggy;
-Double_t z1,z2,y1,y2,x1,x2;
-
-Int_t k,l,m,kv;
-Double_t bbi;
-
-Double_t bf11,bf12,bf21,bf22;
-Double_t bg11,bg12,bg21,bg22;
-k=*kk;
-l=*ll;
-m=*mm;
-
-kv=*kvr;
-
-z1=*zz1;
-z2=*zz2;
-y1=*yy1;
-y2=*yy2;
-x1=*xx1;
-x2=*xx2;
-
-/*-----------------Polar part ------------------*/
-
-if(kv==0) {
- bf11=fdBpx[k][l][m];
- bf12=fdBpx[k+1][l][m];
- bf21=fdBpx[k+1][l+1][m];
- bf22=fdBpx[k][l+1][m];
-
- bg11=fdBpx[k][l][m+1];
- bg12=fdBpx[k+1][l][m+1];
- bg21=fdBpx[k+1][l+1][m+1];
- bg22=fdBpx[k][l+1][m+1];
- }
- if(kv==1) {
- bf11=fdBpy[k][l][m];
- bf12=fdBpy[k+1][l][m];
- bf21=fdBpy[k+1][l+1][m];
- bf22=fdBpy[k][l+1][m];
-
- bg11=fdBpy[k][l][m+1];
- bg12=fdBpy[k+1][l][m+1];
- bg21=fdBpy[k+1][l+1][m+1];
- bg22=fdBpy[k][l+1][m+1];
- }
-
- if(kv==2) {
- bf11=fdBpz[k][l][m];
- bf12=fdBpz[k+1][l][m];
- bf21=fdBpz[k+1][l+1][m];
- bf22=fdBpz[k][l+1][m];
-
- bg11=fdBpz[k][l][m+1];
- bg12=fdBpz[k+1][l][m+1];
- bg21=fdBpz[k+1][l+1][m+1];
- bg22=fdBpz[k][l+1][m+1];
- }
-/*-----------------Cartensian part ---------------*/
-
- if(kv==3) {
- bf11=fdBcx[k][l][m];
- bf12=fdBcx[k+1][l][m];
- bf21=fdBcx[k+1][l+1][m];
- bf22=fdBcx[k][l+1][m];
-
- bg11=fdBcx[k][l][m+1];
- bg12=fdBcx[k+1][l][m+1];
- bg21=fdBcx[k+1][l+1][m+1];
- bg22=fdBcx[k][l+1][m+1];
- }
-
- if(kv==4) {
- bf11=fdBcy[k][l][m];
- bf12=fdBcy[k+1][l][m];
- bf21=fdBcy[k+1][l+1][m];
- bf22=fdBcy[k][l+1][m];
-
- bg11=fdBcy[k][l][m+1];
- bg12=fdBcy[k+1][l][m+1];
- bg21=fdBcy[k+1][l+1][m+1];
- bg22=fdBcy[k][l+1][m+1];
- }
- if(kv==5) {
- bf11=fdBcz[k][l][m];
- bf12=fdBcz[k+1][l][m];
- bf21=fdBcz[k+1][l+1][m];
- bf22=fdBcz[k][l+1][m];
-
- bg11=fdBcz[k][l][m+1];
- bg12=fdBcz[k+1][l][m+1];
- bg21=fdBcz[k+1][l+1][m+1];
- bg22=fdBcz[k][l+1][m+1];
- }
-
-
-
- fy1=z1*bf11+z2*bf12;
- fy2=z2*bf21+z1* bf22;
- ffy=y1*fy1+ y2*fy2;
-
-
- gy1 = z1*bg11+z2*bg12;
- gy2 = z2*bg21+z1*bg22;
- ggy= y1*gy1 + y2*gy2;
-
- bbi = x1*ffy+x2*ggy;
-
- *bb=bbi;
-
-}
-//____________________________________________
-
-void AliMagFDM::ReadField()
+//_______________________________________________________________________
+Double_t AliMagF::GetFactorDip() const
{
- FILE *magfile;
-
- Int_t ik, il, im;
- Float_t zzp, rr,phii;
- Float_t zz, yy, bx,by,bz,bb;
-
- char *fname;
- printf("Reading Magnetic Field %s from file %s\n",fName.Data(),fTitle.Data());
- fname = gSystem->ExpandPathName(fTitle.Data());
- magfile=fopen(fname,"r");
- delete [] fname;
-
- printf("Cartensian part\n");
-
- if (magfile) {
-
-// Cartensian part
-
- fscanf(magfile,"%d %d %d ",&fdYl, &fdXl, &fdZl);
-
- printf("fdYl %d, fdXl %d, fdZl %d\n",fdYl, fdXl, fdZl);
-
- for (ik=0; ik<fdZl; ik++)
- {
-
- fscanf(magfile, " %e ", &zz);
- fdZc[ik]=zz;
+ // return the sign*scale of the current in the Dipole according to fgkPolarityConventionthe
+ switch (fgkPolarityConvention) {
+ case kConvDCS2008: return fFactorDip;
+ case kConvLHC : return -fFactorDip;
+ default : return fFactorDip; // case kConvMap2005: return fFactorDip;
+ }
+}
- }
-
- for (ik=0; ik<fdYl; ik++)
- {
- fscanf(magfile, " %e ", &yy);
- fdY[ik]=yy;
+//_____________________________________________________________________________
+AliMagF* AliMagF::CreateFieldMap(Float_t l3Cur, Float_t diCur, Int_t convention, Bool_t uniform,
+ Float_t beamenergy, const Char_t *beamtype, const Char_t *path)
+{
+ //------------------------------------------------
+ // The magnetic field map, defined externally...
+ // L3 current 30000 A -> 0.5 T
+ // L3 current 12000 A -> 0.2 T
+ // dipole current 6000 A
+ // The polarities must match the convention (LHC or DCS2008)
+ // unless the special uniform map was used for MC
+ //------------------------------------------------
+ const Float_t l3NominalCurrent1=30000.; // (A)
+ const Float_t l3NominalCurrent2=12000.; // (A)
+ const Float_t diNominalCurrent =6000. ; // (A)
+
+ const Float_t tolerance=0.03; // relative current tolerance
+ const Float_t zero=77.; // "zero" current (A)
+ //
+ BMap_t map;
+ double sclL3,sclDip;
+ //
+ Float_t l3Pol = l3Cur > 0 ? 1:-1;
+ Float_t diPol = diCur > 0 ? 1:-1;
- }
- for (ik=0; ik<81; ik++)
- {
- printf("fdZc %e,fdY %e\n", fdZc[ik],fdY[ik]);
- }
-
- fscanf(magfile," %e %e %e %e %e %e %e %e %e %e %e ", &fdYdel,&fdXdel,&fdZdel,&fdZmax,&fdZmin,&fdYmax,&fdYmin,&fdAx1,&fdCx1,&fdAx2,&fdCx2);
-
-printf("fdYdel %e, fdXdel %e, fdZdel %e\n",fdYdel,fdXdel,fdZdel);
-printf("fdZmax %e, fdZmin %e, fdYmax %e,fdYmin %e\n",fdZmax,fdZmin,fdYmax,fdYmin);
-printf("fdAx1 %e, fdCx1 %e, fdAx2 %e, fdCx %e\n",fdAx1,fdCx1,fdAx2,fdCx2);
-
- for (il=0; il<44; il++) {
- for (im=0; im<81; im++) {
- for (ik=0; ik<81; ik++) {
-
- fscanf(magfile, " %e ", &by);
- fdBcy[ik][im][il]=by;
- }
- }
- }
-
- for (il=0; il<44; il++) {
- for (im=0; im<81; im++) {
- for (ik=0; ik<81; ik++) {
-
- fscanf(magfile, " %e ", &bx);
- fdBcx[ik][im][il]=bx;
- }
- }
+ l3Cur = TMath::Abs(l3Cur);
+ diCur = TMath::Abs(diCur);
+ //
+ if (TMath::Abs((sclDip=diCur/diNominalCurrent)-1.) > tolerance && !uniform) {
+ if (diCur <= zero) sclDip = 0.; // some small current.. -> Dipole OFF
+ else {
+ AliErrorGeneral("AliMagF",Form("Wrong dipole current (%f A)!",diCur));
+ return 0;
}
-
- for (il=0; il<44; il++) {
- for (im=0; im<81; im++) {
- for (ik=0; ik<81; ik++) {
-
- fscanf(magfile, " %e ", &bz);
- fdBcz[ik][im][il]=bz;
- }
- }
- }
-//---------------------- Polar part ---------------------------------
-
- printf("Polar part\n");
- fscanf(magfile,"%d %d %d ", &fdZpl, &fdRn, &fdPhin);
- printf("fdZpl %d, fdRn %d, fdPhin %d\n",fdZpl,fdRn,fdPhin);
-
- printf(" fdZp array\n");
-
- for (ik=0; ik<51; ik++)
- {
- fscanf(magfile, " %e ", &zzp);
- fdZp[ik]=zzp;
- printf(" %e\n",fdZp[ik]);
- }
-
- printf(" fdR array\n");
-
- for (ik=0; ik<10; ik++)
- {
- fscanf(magfile, " %e ", &rr);
- fdR[ik]=rr;
- printf(" %e\n",fdR[ik]);
- }
-
-// printf("fdPhi array\n");
-
- for (il=0; il<33; il++)
- {
- fscanf(magfile, " %e ", &phii);
- fdPhi[il]=phii;
-// printf(" %e\n",fdPhi[il]);
- }
-
- fscanf(magfile," %e %e %e %e %e %e %e ",&fdZpdl,&fdPhid,&fdRdel,&fdZpmx,&fdZpmn,&fdRmax, &fdRmin);
-
-printf("fdZpdl %e, fdPhid %e, fdRdel %e, fdZpmx %e, fdZpmn %e,fdRmax %e,fdRmin %e \n", fdZpdl,fdPhid, fdRdel,fdZpmx, fdZpmn,fdRmax, fdRmin);
-
-
- for (il=0; il<33; il++) {
- for (im=0; im<10; im++) {
- for (ik=0; ik<51; ik++) {
- fscanf(magfile, " %e ", &by);
- fdBpy[ik][im][il]=by;
- }
- }
- }
-
- for (il=0; il<33; il++) {
- for (im=0; im<10; im++) {
- for (ik=0; ik<51; ik++) {
- fscanf(magfile, " %e ", &bx);
- fdBpx[ik][im][il]=bx;
- }
- }
- }
-
-
- for (il=0; il<33; il++) {
- for (im=0; im<10; im++) {
- for (ik=0; ik<51; ik++) {
- fscanf(magfile, " %e ", &bz);
- fdBpz[ik][im][il]=bz;
- }
- }
- }
-
-
- for (il=0; il<32; il++) {
- for (im=0; im<2; im++) {
- for (ik=0; ik<2; ik++) {
- fscanf(magfile, " %e ", &bb);
- fdB[ik][im][il]=bb;
- }
- }
+ }
+ //
+ if (uniform) {
+ // special treatment of special MC with uniform mag field (normalized to 0.5 T)
+ // no check for scaling/polarities are done
+ map = k5kGUniform;
+ sclL3 = l3Cur/l3NominalCurrent1;
+ }
+ else {
+ if (TMath::Abs((sclL3=l3Cur/l3NominalCurrent1)-1.) < tolerance) map = k5kG;
+ else if (TMath::Abs((sclL3=l3Cur/l3NominalCurrent2)-1.) < tolerance) map = k2kG;
+ else if (l3Cur <= zero && diCur<=zero) { sclL3=0; sclDip=0; map = k5kGUniform;}
+ else {
+ AliErrorGeneral("AliMagF",Form("Wrong L3 current (%f A)!",l3Cur));
+ return 0;
+ }
+ }
+ //
+ if (sclDip!=0 && map!=k5kGUniform) {
+ if ( (l3Cur<=zero) || ((convention==kConvLHC && l3Pol!=diPol) || (convention==kConvDCS2008 && l3Pol==diPol)) ) {
+ AliErrorGeneral("AliMagF",Form("Wrong combination for L3/Dipole polarities (%c/%c) for convention %d",
+ l3Pol>0?'+':'-',diPol>0?'+':'-',GetPolarityConvention()));
+ return 0;
}
-//
- } else {
- printf("File %s not found !\n",fTitle.Data());
- exit(1);
}
+ //
+ if (l3Pol<0) sclL3 = -sclL3;
+ if (diPol<0) sclDip = -sclDip;
+ //
+ BeamType_t btype = kNoBeamField;
+ TString btypestr = beamtype;
+ btypestr.ToLower();
+ TPRegexp protonBeam("(proton|p)\\s*-?\\s*\\1");
+ TPRegexp ionBeam("(lead|pb|ion|a)\\s*-?\\s*\\1");
+ if (btypestr.Contains(ionBeam)) btype = kBeamTypeAA;
+ else if (btypestr.Contains(protonBeam)) btype = kBeamTypepp;
+ else AliInfoGeneral("AliMagF",Form("Assume no LHC magnet field for the beam type %s, ",beamtype));
+ char ttl[80];
+ sprintf(ttl,"L3: %+5d Dip: %+4d kA; %s | Polarities in %s convention",(int)TMath::Sign(l3Cur,float(sclL3)),
+ (int)TMath::Sign(diCur,float(sclDip)),uniform ? " Constant":"",
+ convention==kConvLHC ? "LHC":"DCS2008");
+ // LHC and DCS08 conventions have opposite dipole polarities
+ if ( GetPolarityConvention() != convention) sclDip = -sclDip;
+ //
+ return new AliMagF("MagneticFieldMap", ttl,sclL3,sclDip,map,btype,beamenergy,2,10.,path);
+ //
}
-//________________________________
-
-
-
-
-
+//_____________________________________________________________________________
+const char* AliMagF::GetBeamTypeText() const
+{
+ const char *beamNA = "No Beam";
+ const char *beamPP = "p-p";
+ const char *beamPbPb= "Pb-Pb";
+ switch ( fBeamType ) {
+ case kBeamTypepp : return beamPP;
+ case kBeamTypeAA : return beamPbPb;
+ case kNoBeamField:
+ default: return beamNA;
+ }
+}