// ------------------------------------------------------------------------- // ----- CbmBsField source file ----- // ----- Created 12/05/06 by E.I.Litvinenko ----- // ------------------------------------------------------------------------- #include "CbmBsField.h" #include "TFile.h" #include "TSystem.h" #include "TArrayF.h" #include #include #include using std::cout; using std::cerr; using std::endl; using std::fabs; using std::ifstream; Int_t checked_index_max(Int_t suggested_index,Int_t array_size) { if (suggested_indexSetName(pBsName); this->SetTitle(pBsName); } CbmBsField::CbmBsField() : CbmFieldMap(), NDIM(0), LL1(0), LL2(0), LL3(0), II1(0), II2(0), II3(0), fBsBx(NULL), fBsBy(NULL), fBsBz(NULL), fX(NULL), fY(NULL), fZ(NULL), UX1(NULL), UX2(NULL), UX3(NULL), F0(NULL), G0(NULL), U0(NULL), fBsName("") { fType = 0; } // ------------- Constructor from CbmFieldPar ------------------------- CbmBsField::CbmBsField(CbmFieldPar* fieldPar) : CbmFieldMap(fieldPar), NDIM(0), LL1(0), LL2(0), LL3(0), II1(0), II2(0), II3(0), fBsBx(NULL), fBsBy(NULL), fBsBz(NULL), fX(NULL), fY(NULL), fZ(NULL), UX1(NULL), UX2(NULL), UX3(NULL), F0(NULL), G0(NULL), U0(NULL), fBsName("") { fType = 6; } CbmBsField::~CbmBsField() { delete fX; delete fY; delete fY; delete fBsBx; delete fBsBy; delete fBsBz; delete (FairField*)this; } void CbmBsField::Init() { TString tmp_FileName; TString dir = gSystem->Getenv("VMCWORKDIR"); // getenv("VMCWORKDIR"); tmp_FileName = dir + "/input/" + fBsName+".root"; readBsRootfile (tmp_FileName); } void CbmBsField::CalculateMapFromBs(Int_t pNx, Int_t pNy, Int_t pNz) { Double_t po[3],B[3], sm=100; fNx = (pNx<=0)? fX->GetSize()-3 : pNx; fNy = (pNy<=0)? fY->GetSize()-3 : pNy; fNz = (pNz<=0)? fZ->GetSize()-3 : pNz; if ((fNx<2)||(fNy<2)||(fNz<2)) { cout << "CalculateMapFromBs ERROR [Ns]: " << fNx << " " << fNy << " " << fNz << endl; return; } fXmin = (fX->GetArray())[3] *sm; fYmin = (fY->GetArray())[3] *sm; fZmin = (fZ->GetArray())[3] *sm; fXmax = (fX->GetArray())[fX->GetSize()-1] *sm; fYmax = (fY->GetArray())[fY->GetSize()-1] *sm; fZmax = (fZ->GetArray())[fZ->GetSize()-1] *sm; fXstep = ( fXmax - fXmin ) / Double_t( fNx - 1 ); fYstep = ( fYmax - fYmin ) / Double_t( fNy - 1 ); fZstep = ( fZmax - fZmin ) / Double_t( fNz - 1 ); if ( fBx ) delete fBx; if ( fBy ) delete fBy; if ( fBz ) delete fBz; fBx = new TArrayF(fNx * fNy * fNz); fBy = new TArrayF(fNx * fNy * fNz); fBz = new TArrayF(fNx * fNy * fNz); cout << "CalculateMapFromBs [Ns]: " << fNx << " " << fNy << " " << fNz << endl; cout << "CalculateMapFromBs [MINs]: " << fXmin << " " << fYmin << " " << fZmin << endl; cout << "CalculateMapFromBs [MAXs]: " << fXmax << " " << fYmax << " " << fZmax << endl; cout << "CalculateMapFromBs [STEPs]: " << fXstep << " " << fYstep << " " << fZstep << endl; cout << "CalculateMapFromBs [POSs]: " << fPosX << " " << fPosY << " " << fPosZ << endl; // GetFieldValue (without conversion from kG to T) Int_t index = 0; for (Int_t ix=0; ixWrite(); f->Close(); if(oldfile) oldfile->cd(); } void CbmBsField::readBsRootfile (const char *name) // Read Field Splined { TFile *oldfile=gFile; TFile *f=new TFile(name, "READ"); if (f->IsZombie()) { cout << "-E- CbmBsField::readBsRootfile: can not read from file: " << endl; Fatal("CbmBsField::readBsRootfile:","Can not read from input file"); } const char *bsname=fBsName.Data(); CbmBsField *fnew=new CbmBsField(bsname); cout << "-I- CbmBsField Reading splined field : " << bsname << " from root file : "<< name << endl; f->GetObject(bsname, fnew); if(fBsBx) delete fBsBx; if(fBsBy) delete fBsBy; if(fBsBz) delete fBsBz; fBsBx=new TArrayF(*fnew->GetBsBx()); fBsBy=new TArrayF(*fnew->GetBsBy()); fBsBz=new TArrayF(*fnew->GetBsBz()); if(fX) delete fX; if(fY) delete fY; if(fZ) delete fZ; fX=new TArrayF(*fnew->GetX()); fY=new TArrayF(*fnew->GetY()); fZ=new TArrayF(*fnew->GetZ()); f->Close(); if(oldfile) oldfile->cd(); UX1 = fX->GetArray(); UX2 = fY->GetArray(); UX3 = fZ->GetArray(); F0 = fBsBx->GetArray(); G0 = fBsBy->GetArray(); U0 = fBsBz->GetArray(); LL1 = fX->GetSize(); LL2 = fY->GetSize(); LL3 = fZ->GetSize(); NDIM = fBsBx->GetSize(); II1 = LL1-1; II2 = LL2-1; II3 = LL3-1; } void CbmBsField::GetFieldValue(const Double_t Point[3], Double_t *Bfield) { Double_t XX,YY,ZZ,X,Y,Z,FX,FY,FZ,pfScale; Float_t fHemiX = 1., fHemiY = 1.,fHemiZ = 1; X=Point[0]-fPosX; Y=Point[1]-fPosY; Z=Point[2]-fPosZ; XX=fabs(X); YY=fabs(Y); ZZ=fabs(Z); FX=0.0; FY=0.0; FZ=0.0; PALC0(XX*0.01,YY*0.01,ZZ*0.01,&FX,&FY,&FZ); // position for PALC0 should be in meters pfScale=fScale*10; // usually fScale=1; FX=FX*pfScale; FY=FY*pfScale; FZ=FZ*pfScale; if (fType) // 3 or 2 { if ( X < 0. ) fHemiX = -1.; if ( Y < 0. ) fHemiY = -1.; FX = FX * fHemiX * fHemiY; if ((fType==3)&&(Z<0.)) // 3 fHemiZ = -1.; FZ= FZ* fHemiY * fHemiZ; } Bfield[0]=FX; Bfield[1]=FY; Bfield[2]=FZ; return; } Double_t CbmBsField::GetBx(Double_t x, Double_t y, Double_t z) { Double_t Point[3]; Double_t Bfield[3]; Point[0]=x; Point[1]=y; Point[2]=z; GetFieldValue(Point, Bfield); return (Bfield[0]); } Double_t CbmBsField::GetBy(Double_t x, Double_t y, Double_t z) { Double_t Point[3]; Double_t Bfield[3]; Point[0]=x; Point[1]=y; Point[2]=z; GetFieldValue(Point, Bfield); return (Bfield[1]); } Double_t CbmBsField::GetBz(Double_t x, Double_t y, Double_t z) { Double_t Point[3]; Double_t Bfield[3]; Point[0]=x; Point[1]=y; Point[2]=z; GetFieldValue(Point, Bfield); return (Bfield[2]); } void CbmBsField::readFortranAsciifiles(const char *BsFortranAsciiFileName1,const char *BsFortranAsciiFileName2, const char *BsFortranAsciiFileName3) { Float_t val; Int_t i; TString fileNam1 = BsFortranAsciiFileName1; ifstream fBsFortranAscii1(fileNam1); if ( ! fBsFortranAscii1.is_open() ) { cerr << "ERROR: File " <> NDIM >> LL1 >> LL2 >> LL3 >> II1 >> II2 >> II3; fX=new TArrayF(LL1); UX1 = fX->GetArray(); for(i=0; i> val; fX->AddAt(val,i); } fBsBx = new TArrayF(NDIM); F0 = fBsBx->GetArray(); for(i=0; i> val; fBsBx->AddAt(val,i); } fBsFortranAscii1.close(); } TString fileNam2 = BsFortranAsciiFileName2; ifstream fBsFortranAscii2(fileNam2); if ( ! fBsFortranAscii2.is_open() ) { cerr << "ERROR: File " <> NDIM >> LL1 >> LL2 >> LL3 >> II1 >> II2 >> II3; fY=new TArrayF(LL2); UX2 = fY->GetArray(); for(i=0; i> val; fY->AddAt(val,i); } fBsBy = new TArrayF(NDIM); G0 = fBsBy->GetArray(); for(i=0; i> val; fBsBy->AddAt(val,i); } fBsFortranAscii2.close(); } TString fileNam3 = BsFortranAsciiFileName3; ifstream fBsFortranAscii3(fileNam3); if ( ! fBsFortranAscii3.is_open() ) { cerr << "ERROR: File " <> NDIM >> LL1 >> LL2 >> LL3 >> II1 >> II2 >> II3; fZ=new TArrayF(LL3); UX3 = fZ->GetArray(); for(i=0; i> val; fZ->AddAt(val,i); } fBsBz = new TArrayF(NDIM); U0 = fBsBz->GetArray(); for(i=0; i> val; fBsBz->AddAt(val,i); } fBsFortranAscii3.close(); } } void CbmBsField::PALC0(Double_t X,Double_t Y,Double_t Z,Double_t *BX,Double_t *BY,Double_t *BZ) { Double_t UX[4],UY[4],UZ[4],X0,X1,X2,X3,X4,X5,X6,X7,Y0,Y1,Y2,Y3,Y4,Y5,Y6,Y7,VX0,VX1,VX2,VX3,VX4,VX5,VX6,VX7; Long64_t INT1[4],INT2[4],INT3[4],KK,K1,K2,K3,KK1,KK2,KK3,NN0,I1,JJ0,I2,JJ1,I3,JJ2; Double_t EPS=1.0e-7, XRZYX,YRZYX,ZRZYX,XRZY,YRZY,ZRZY,XRZ,YRZ,ZRZ,SS3,SS2,SS1; Int_t izero4=3, izero5=4; if (X<(UX1[izero4]-EPS)) goto m100 ; for (KK=izero5;KKX4)goto n100; C0=X4-X0; W0=(X1-X0)*(X2-X0)*(X3-X0)*(X4-X0); TT=T-X0; RR=C0/W0; TPL=RR*(TT*TT*TT); W1=(X0-X1)*(X2-X1)*(X3-X1)*(X4-X1); TT=T-X1; RR=C0/W1; TPL=RR*(TT*TT*TT)+TPL; W2=(X0-X2)*(X1-X2)*(X3-X2)*(X4-X2); TT=T-X2; RR=C0/W2; TPL=RR*(TT*TT*TT)+TPL; W3=(X0-X3)*(X1-X3)*(X2-X3)*(X4-X3); TT=T-X3; RR=C0/W3; value_SPL0=RR*(TT*TT*TT)+TPL; return ((Float_t)value_SPL0); n200: C0=X4-X0; W0=(X1-X0)*(X2-X0)*(X3-X0)*(X4-X0); TT=T-X0; RR=C0/W0; value_SPL0=RR*(TT*TT*TT); return ((Float_t)value_SPL0); n300: C0=X4-X0; W0=(X1-X0)*(X2-X0)*(X3-X0)*(X4-X0); TT=T-X0; RR=C0/W0; TPL=RR*(TT*TT*TT); W1=(X0-X1)*(X2-X1)*(X3-X1)*(X4-X1); TT=T-X1; RR=C0/W1; value_SPL0=RR*(TT*TT*TT)+TPL; return ((Float_t)value_SPL0); n400: C0=X4-X0; W0=(X1-X0)*(X2-X0)*(X3-X0)*(X4-X0); TT=T-X0; RR=C0/W0; TPL=RR*(TT*TT*TT); W1=(X0-X1)*(X2-X1)*(X3-X1)*(X4-X1); TT=T-X1; RR=C0/W1; TPL=RR*(TT*TT*TT)+TPL; W2=(X0-X2)*(X1-X2)*(X3-X2)*(X4-X2); TT=T-X2; RR=C0/W2; value_SPL0=RR*(TT*TT*TT)+TPL; return ((Float_t)value_SPL0); n100: value_SPL0=0.0; return ((Float_t)value_SPL0) ; }