#include "AliTPCExB.h"
#include "TMath.h"
#include "AliMagF.h"
#include "TLinearFitter.h"
#include "AliTPCcalibDB.h"
AliTPCExB* AliTPCExB::fgInstance = 0;
TObjArray AliTPCExB::fgArray;
ClassImp(AliTPCExB)
AliTPCExB::AliTPCExB():
TObject(),
fMatBrBz(0),
fMatBrfiBz(0),
fMatBrBzI0(0),
fMatBrBzI1(0),
fMatBrfiBzI0(0),
fMatBrfiBzI1(0)
{
}
AliTPCExB::AliTPCExB(const AliTPCExB& exb):
TObject(exb),
fMatBrBz(new TVectorD(*(exb.fMatBrBz))),
fMatBrfiBz(new TVectorD(*(exb.fMatBrfiBz))),
fMatBrBzI0(new TVectorD(*(exb.fMatBrBzI0))),
fMatBrBzI1(new TVectorD(*(exb.fMatBrBzI1))),
fMatBrfiBzI0(new TVectorD(*(exb.fMatBrfiBzI0))),
fMatBrfiBzI1(new TVectorD(*(exb.fMatBrfiBzI1)))
{
}
AliTPCExB& AliTPCExB::operator=(const AliTPCExB &)
{
return *this;
}
void AliTPCExB::TestExB(const char* fileName) {
TTreeSRedirector ts(fileName);
Double_t x[3];
for (x[0]=-250.;x[0]<=250.;x[0]+=10.)
for (x[1]=-250.;x[1]<=250.;x[1]+=10.)
for (x[2]=-250.;x[2]<=250.;x[2]+=20.) {
Double_t r=TMath::Sqrt(x[0]*x[0]+x[1]*x[1]);
if (r<20) continue;
if (r>260) continue;
Double_t z = x[2];
Double_t d[3];
Correct(x,d);
Double_t rd=TMath::Sqrt(d[0]*d[0]+d[1]*d[1]);
Double_t dr=r-rd;
Double_t phi=TMath::ATan2(x[1],x[0]);
Double_t phid=TMath::ATan2(d[1],d[0]);
Double_t dphi=phi-phid;
if (dphi<0.) dphi+=TMath::TwoPi();
if (dphi>TMath::Pi()) dphi=TMath::TwoPi()-dphi;
Double_t drphi=r*dphi;
Double_t dx=x[0]-d[0];
Double_t dy=x[1]-d[1];
Double_t dz=x[2]-d[2];
Double_t bx = GetBx(r,phi,z,0);
Double_t by = GetBy(r,phi,z,0);
Double_t bz = GetBz(r,phi,z,0);
Double_t br = GetBr(r,phi,z,0);
Double_t brfi = GetBrfi(r,phi,z,0);
Double_t bxi = GetBxI(r,phi,z,0);
Double_t byi = GetByI(r,phi,z,0);
Double_t bzi = GetBzI(r,phi,z,0);
Double_t bri = GetBrI(r,phi,z,0);
Double_t brfii = GetBrfiI(r,phi,z,0);
ts<<"positions"<<
"x0="<<x[0]<<
"x1="<<x[1]<<
"x2="<<x[2]<<
"dx="<<dx<<
"dy="<<dy<<
"dz="<<dz<<
"r="<<r<<
"phi="<<phi<<
"dr="<<dr<<
"drphi="<<drphi<<
"bx="<<bx<<
"by="<<by<<
"bz="<<bz<<
"br="<< br<<
"brfi="<<brfi<<
"bxi="<<bxi<<
"byi="<<byi<<
"bzi="<<bzi<<
"bri="<< bri<<
"brfii="<<brfii<<
"\n";
}
}
Double_t AliTPCExB::GetDr(Double_t r, Double_t phi, Double_t z, Double_t bz){
AliTPCExB *exb = Instance();
if (!exb) exb = AliTPCcalibDB::GetExB(bz,kFALSE);
if (!exb) return 0;
Double_t pos0[3] = {r*TMath::Cos(phi), r*TMath::Sin(phi),z};
Double_t pos1[3];
exb->Correct(pos0,pos1);
Double_t dx=pos1[0]-pos0[0];
Double_t dy=pos1[1]-pos0[1];
Float_t dr = (dx*pos0[0]+dy*pos0[1])/r;
return dr;
}
Double_t AliTPCExB::GetDrphi(Double_t r, Double_t phi, Double_t z, Double_t bz){
AliTPCExB *exb = Instance();
if (!exb) exb = AliTPCcalibDB::GetExB(bz,kFALSE);
if (!exb) return 0;
Double_t pos0[3] = {r*TMath::Cos(phi), r*TMath::Sin(phi),z};
Double_t pos1[3];
exb->Correct(pos0,pos1);
Double_t dphi=TMath::ATan2(pos1[1],pos1[0])-TMath::ATan2(pos0[1],pos0[0]);
if (dphi>TMath::Pi()) dphi-=TMath::TwoPi();
if (dphi<-TMath::Pi()) dphi+=TMath::TwoPi();
return r*dphi;
}
Double_t AliTPCExB::GetDphi(Double_t r, Double_t phi, Double_t z, Double_t bz){
AliTPCExB *exb = Instance();
if (!exb) exb = AliTPCcalibDB::GetExB(bz,kFALSE);
if (!exb) return 0;
Double_t pos0[3] = {r*TMath::Cos(phi), r*TMath::Sin(phi),z};
Double_t pos1[3];
exb->Correct(pos0,pos1);
Double_t dphi=TMath::ATan2(pos1[1],pos1[0])-TMath::ATan2(pos0[1],pos0[0]);
return dphi;
}
Double_t AliTPCExB::GetDz(Double_t r, Double_t phi, Double_t z, Double_t bz){
AliTPCExB *exb = Instance();
if (!exb) exb = AliTPCcalibDB::GetExB(bz,kFALSE);
if (!exb) return 0;
Double_t pos0[3] = {r*TMath::Cos(phi), r*TMath::Sin(phi),z};
Double_t pos1[3];
exb->Correct(pos0,pos1);
Double_t dz=pos1[2]-pos0[2];
return dz;
}
void AliTPCExB::RegisterField(Int_t index, AliMagF * magf){
fgArray.AddAt(magf,index);
}
Double_t AliTPCExB::GetBx(Double_t r, Double_t phi, Double_t z,Int_t index){
AliMagF *mag = (AliMagF*)fgArray.At(index);
if (!mag) return 0;
Double_t xyz[3]={r*TMath::Cos(phi),r*TMath::Sin(phi),z};
Double_t bxyz[3];
mag->Field(xyz,bxyz);
return bxyz[0];
}
Double_t AliTPCExB::GetBy(Double_t r, Double_t phi, Double_t z,Int_t index){
AliMagF *mag = (AliMagF*)fgArray.At(index);
if (!mag) return 0;
Double_t xyz[3]={r*TMath::Cos(phi),r*TMath::Sin(phi),z};
Double_t bxyz[3];
mag->Field(xyz,bxyz);
return bxyz[1];
}
Double_t AliTPCExB::GetBz(Double_t r, Double_t phi, Double_t z,Int_t index){
AliMagF *mag = (AliMagF*)fgArray.At(index);
if (!mag) return 0;
Double_t xyz[3]={r*TMath::Cos(phi),r*TMath::Sin(phi),z};
Double_t bxyz[3];
mag->Field(xyz,bxyz);
return bxyz[2];
}
Double_t AliTPCExB::GetBr(Double_t r, Double_t phi, Double_t z,Int_t index){
AliMagF *mag = (AliMagF*)fgArray.At(index);
if (!mag) return 0;
Double_t xyz[3]={r*TMath::Cos(phi),r*TMath::Sin(phi),z};
Double_t bxyz[3];
mag->Field(xyz,bxyz);
if (r==0) return 0;
Double_t br = (bxyz[0]*xyz[0]+bxyz[1]*xyz[1])/r;
return br;
}
Double_t AliTPCExB::GetBrfi(Double_t r, Double_t phi, Double_t z,Int_t index){
AliMagF *mag = (AliMagF*)fgArray.At(index);
if (!mag) return 0;
Double_t xyz[3]={r*TMath::Cos(phi),r*TMath::Sin(phi),z};
Double_t bxyz[3];
mag->Field(xyz,bxyz);
if (r==0) return 0;
Double_t br = (-bxyz[0]*xyz[1]+bxyz[1]*xyz[0])/r;
return br;
}
Double_t AliTPCExB::GetBxI(Double_t r, Double_t phi, Double_t z,Int_t index)
{
Double_t sumf =0;
if (z>0 &&z<250){
for (Float_t zi=z;zi<250;zi+=5){
sumf+=GetBx(r,phi,zi,index)/GetBz(r,phi,zi,index);
}
}
if (z<0 &&z>-250){
for (Float_t zi=z;zi>-250;zi-=5){
sumf+=GetBx(r,phi,zi,index)/GetBz(r,phi,zi,index);
}
}
return sumf*5;
}
Double_t AliTPCExB::GetByI(Double_t r, Double_t phi, Double_t z,Int_t index)
{
Double_t sumf =0;
if (z>0 &&z<250){
for (Float_t zi=z;zi<250;zi+=5){
sumf+=GetBy(r,phi,zi,index)/GetBz(r,phi,zi,index);
}
}
if (z<0 &&z>-250){
for (Float_t zi=z;zi>-250;zi-=5){
sumf+=GetBy(r,phi,zi,index)/GetBz(r,phi,zi,index);
}
}
return sumf*5;
}
Double_t AliTPCExB::GetBzI(Double_t r, Double_t phi, Double_t z,Int_t index)
{
Double_t sumf =0;
if (z>0 &&z<250){
for (Float_t zi=z;zi<250;zi+=5){
sumf+=GetBz(r,phi,zi,index);
}
}
if (z<0 &&z>-250){
for (Float_t zi=z;zi>-250;zi-=5){
sumf+=GetBz(r,phi,zi,index);
}
}
return sumf*5;
}
Double_t AliTPCExB::GetBrI(Double_t r, Double_t phi, Double_t z,Int_t index)
{
Double_t sumf =0;
if (z>0 &&z<250){
for (Float_t zi=z;zi<250;zi+=5){
sumf+=GetBr(r,phi,zi,index)/GetBz(r,phi,zi,index);
}
}
if (z<0 &&z>-250){
for (Float_t zi=z;zi>-250;zi-=5){
sumf+=GetBr(r,phi,zi,index)/GetBz(r,phi,zi,index);
}
}
return sumf*5;
}
Double_t AliTPCExB::GetBrfiI(Double_t r, Double_t phi, Double_t z,Int_t index)
{
Double_t sumf =0;
if (z>0 &&z<250){
for (Float_t zi=z;zi<250;zi+=5.){
sumf+=GetBrfi(r,phi,zi,index)/GetBz(r,phi,zi,index);
}
}
if (z<0 &&z>-250){
for (Float_t zi=z;zi>-250;zi-=5){
sumf+=GetBrfi(r,phi,zi,index)/GetBz(r,phi,zi,index);
}
}
return sumf*5;
}
Double_t AliTPCExB::Eval(Int_t type, Double_t r, Double_t phi, Double_t z){
if (type==0) {
if (z>0 && fMatBrBzI0) return EvalMat(*fMatBrBzI0,r,phi,z);
if (z<0 && fMatBrBzI1) return EvalMat(*fMatBrBzI1,r,phi,z);
}
if (type==1) {
if (z>0 && fMatBrfiBzI0) return EvalMat(*fMatBrfiBzI0,r,phi,z);
if (z<0 && fMatBrfiBzI1) return EvalMat(*fMatBrfiBzI1,r,phi,z);
}
if (type==2 && fMatBrBz) return EvalMat(*fMatBrBz,r,phi,z);
if (type==3 && fMatBrfiBz) return EvalMat(*fMatBrfiBz,r,phi,z);
return 0;
}
Double_t AliTPCExB::EvalMat(const TVectorD &vec, Double_t r, Double_t phi, Double_t z){
Double_t sa = TMath::Sin(phi);
Double_t ca = TMath::Cos(phi);
Double_t sa2 = TMath::Sin(phi*2);
Double_t ca2 = TMath::Cos(phi*2);
Double_t zn = z/250.;
Double_t rn = r/250.;
Int_t ipoint=0;
Double_t res = vec[ipoint++];
res+=vec[ipoint++]*zn;
res+=vec[ipoint++]*rn;
res+=vec[ipoint++]*zn*rn;
res+=vec[ipoint++]*zn*zn;
res+=vec[ipoint++]*zn*zn*rn;
res+=vec[ipoint++]*zn*rn*rn;
res+=vec[ipoint++]*sa;
res+=vec[ipoint++]*ca;
res+=vec[ipoint++]*ca2;
res+=vec[ipoint++]*sa2;
res+=vec[ipoint++]*ca*zn;
res+=vec[ipoint++]*sa*zn;
res+=vec[ipoint++]*ca2*zn;
res+=vec[ipoint++]*sa2*zn;
res+=vec[ipoint++]*ca*zn*zn;
res+=vec[ipoint++]*sa*zn*zn;
res+=vec[ipoint++]*ca*zn*rn;
res+=vec[ipoint++]*sa*zn*rn;
return res;
}