29 #include <Riostream.h> 36 #include <TPaveText.h> 53 static Double_t
FunGauss2D(
const Double_t *
const x,
const Double_t *
const par)
57 return ( TMath::Exp(-(x[0]*x[0])/(2*par[0]*par[0]))*
58 TMath::Exp(-(x[1]*x[1])/(2*par[1]*par[1])));
62 static Double_t
FunCosh2D(
const Double_t *
const x,
const Double_t *
const par)
66 return ( 1/(TMath::CosH(3.14159*x[0]/(2*par[0]))*
67 TMath::CosH(3.14159*x[1]/(2*par[1]))));
70 static Double_t
FunGati2D(
const Double_t *
const x,
const Double_t *
const par)
75 Float_t k3R=TMath::Sqrt(k3);
76 Float_t k2=(TMath::Pi()/2)*(1-k3R/2.);
77 Float_t k1=k2*k3R/(4*TMath::ATan(k3R));
78 Float_t l=x[0]/par[0];
79 Float_t tan2=TMath::TanH(k2*l);
81 Float_t
res = k1*(1-tan2)/(1+k3*tan2);
85 k2=(TMath::Pi()/2)*(1-k3R/2.);
86 k1=k2*k3R/(4*TMath::ATan(k3R));
88 tan2=TMath::TanH(k2*l);
90 res = res*k1*(1-tan2)/(1+k3*tan2);
140 for(Int_t i=0;i<5;i++){
148 SetChevron(0.2,0.0,1.0);
150 SetInterpolationType(2,0);
188 Float_t hstep, Float_t shifty, Float_t fac)
207 Int_t i=Int_t(0.5+y);
208 if (y<0) i=Int_t(-0.5+y);
209 if ((i<0) || (i>=
fNYdiv) )
return 0;
216 if ((i<0) || (i>=
fNYdiv) )
return 0;
242 Float_t dy=y-Float_t(i);
244 res = a+b*dy+c*dy*dy+d*dy*dy*dy;
257 if ( (i>1) && ((i+2)<
fNPRF)) {
265 Float_t dx=x-Float_t(i);
266 Float_t
res = a+b*dx+c*dx*dx+d*dx*dx*dx;
286 Float_t sigmaX, Float_t sigmaY)
295 snprintf(
fType,5,
"User");
300 Double_t estimsigma =
303 if (estimsigma < 5*sigmaX) {
325 snprintf(
fType,5,
"Gauss");
335 Double_t estimsigma =
338 if (estimsigma < 5*sigmaX) {
359 snprintf(
fType,5,
"Cosh");
368 Double_t estimsigma = TMath::Sqrt(sigmaX*sigmaX+
fWidth*
fWidth*(1+TMath::Abs(
fK))/12);
369 if (estimsigma < 5*sigmaX) {
391 snprintf(
fType,5,
"Gati");
404 Double_t estimsigma = TMath::Sqrt(sigmaX*sigmaX+
fWidth*
fWidth*(1+TMath::Abs(
fK))/12);
405 if (estimsigma < 5*sigmaX) {
422 if (
fGRF == 0 )
return;
438 Int_t nx = Int_t(0.5+x2/dx);
439 Int_t ny = Int_t(0.5+y2/dy);
443 for (ix=-nx;ix<=nx;ix++)
444 for ( iy=-ny;iy<=ny;iy++)
445 dInteg+=
fGRF->Eval(Float_t(ix)*dx,Float_t(iy)*dy)*dx*dy;
471 const Double_t kprec =0.00000001;
473 for (i =0; i<
fNPRF;i++){
476 Double_t xch =
fDStep * (Double_t)(i-fNPRF/2);
485 Double_t y1 = TMath::Max((y1chev),Double_t(-
fHeightFull/2.));
490 kx = TMath::Tan(TMath::ATan(kx))+TMath::Tan(
fPadAngle*fgkDegtoRad);
493 Double_t dy = TMath::Min(fOrigSigmaY/Double_t(ny),y2-y1);
497 if (y2>(y1+kprec))
for (Double_t y = y1; y<y2+kprec;){
501 ndy = fOrigSigmaY/Double_t(ny);
504 if (ndy<kprec) ndy=2*kprec;
509 Double_t deltay = (y-y1chev);
511 Double_t xp1 = x0+deltay*kx;
514 Double_t xp3 =xp1+kx*dy;
515 Double_t xp4 =xp2+kx*dy;
517 Double_t x1 = TMath::Min(xp1,xp3);
519 Double_t x2 = TMath::Max(xp2,xp4);
524 Double_t dx = TMath::Min(fOrigSigmaX/Double_t(nx),x2-x1)/5.;
528 for (Double_t x = x1; x<x2+kprec ;){
530 nx = TMath::Max(Int_t(
fNdiv*TMath::Exp(-(x-xch)*(x-xch)/(2*fOrigSigmaX*fOrigSigmaX))),3);
531 ndx = fOrigSigmaX/Double_t(nx);
535 if ( ( (x+dx+ndx)<TMath::Max(xp3,xp1)) || ( (x+dx+ndx)>TMath::Min(xp4,xp2))) {
538 if (ndx<kprec) ndx=2*kprec;
540 Double_t ddx,ddy,dddx,dddy;
543 dddx = cos*ddx-sin*ddy;
544 dddy = sin*ddx+cos*ddy;
545 Double_t z0=
fGRF->Eval(dddx,dddy);
549 dddx = cos*ddx-sin*ddy;
550 dddy = sin*ddx+cos*ddy;
551 Double_t z1=
fGRF->Eval(dddx,dddy);
555 dddx = cos*ddx-sin*ddy;
556 dddy = sin*ddx+cos*ddy;
557 Double_t z3=
fGRF->Eval(dddx,dddy);
561 dddx = cos*ddx-sin*ddy;
562 dddy = sin*ddx+cos*ddy;
563 Double_t z2=
fGRF->Eval(dddx,dddy);
567 dddx = cos*ddx-sin*ddy;
568 dddy = sin*ddx+cos*ddy;
569 Double_t z4=
fGRF->Eval(dddx,dddy);
572 if (z0<0) {z0=0;z1=0;z2=0;z3=0;z4=0;}
574 Double_t f2x= (z3+z1-2*z0)*4.;
575 Double_t f2y= (z2+z4-2*z0)*4.;
576 Double_t f1y= (z3-z1);
578 z = (z0+f2x/6.+f2y/6.);
582 Double_t xx2 = TMath::Min(x+dx,xp1+dy*kx);
583 Double_t yy1 = y+(xx1-xp1)/kx;
584 Double_t yy2 = TMath::Min(y+(xx2-xp1)/kx,y+dy);
587 z-= z0*(y+dy-yy2)/dy;
588 z-= f1y*(xx2-xx1)*(y+dy-yy2)*(y+dy-yy2)/(2.*dx*dy);
590 z-=z0*(xx2-xx1)*(yy2-yy1)/(2*dx*dy);
596 Double_t yy1 = y+(xx1-xp2)/kx;
597 Double_t yy2 = y+(xx2-xp2)/kx;
601 z-=f1y*(xx2-xx1)*(yy1-y)*(yy1-y)/(2*dx*dy);
603 z-=z0*(xx2-xx1)*(yy2-yy1)/(2*dx*dy);
609 Double_t xx2 = TMath::Min(x+dx,xp3-dy/kx);
610 Double_t yy1 = y+(xx1-xp1)/kx;
611 Double_t yy2 = TMath::Max(y,yy1+(xx2-xx1)/kx);
614 z-= f1y*(xx2-xx1)*(yy2-y)*(yy2-y)/(2.*dx*dy);
615 z-=z0*(xx2-xx1)*(yy1-yy2)/(2*dx*dy);
618 Double_t xx1 = TMath::Max(x,xp2+dy*kx);
620 Double_t yy1 = TMath::Min(y+dy,y-(xp2-xx1)/kx);
621 Double_t yy2 = y-(xp2-xx2)/kx;
624 z-= f1y*(xx2-xx1)*(yy2-y)*(yy2-y)/(2.*dx*dy);
625 z-=z0*(xx2-xx1)*(yy1-yy2)/(2*dx*dy);
658 for (i=-1; i<=
fNYdiv; i++){
665 Float_t weight =
GetPRF(x,y);
683 void AliTPCPRF2D::Streamer(TBuffer &xRuub)
687 if (xRuub.IsReading()) {
689 Version_t xRuuv = xRuub.ReadVersion(&xRuus, &xRuuc);
690 AliTPCPRF2D::Class()->ReadBuffer(xRuub,
this, xRuuv, xRuus, xRuuc);
692 if (strncmp(
fType,
"User",3)!=0){
694 if (strncmp(
fType,
"Gauss",3)==0)
696 if (strncmp(
fType,
"Cosh",3)==0)
698 if (strncmp(
fType,
"Gati",3)==0)
706 AliTPCPRF2D::Class()->WriteBuffer(xRuub,
this);
719 snprintf(s,100,
"Pad Response Function");
720 TH1F * hPRFc =
new TH1F(
"hPRFc",s,kn+1,x1,x2);
724 for (Int_t i = 0;i<kn+1;i++)
726 x+=(x2-x1)/Float_t(kn);
730 hPRFc->SetXTitle(
"pad (cm)");
740 snprintf(s,100,
"Pad Response Function");
741 AliH2F * hPRFc =
new AliH2F(
"hPRFc",s,Nx,x1,x2,Ny,y1,y2);
742 Float_t dx=(x2-x1)/Float_t(Nx);
743 Float_t dy=(y2-y1)/Float_t(Ny) ;
747 for ( Int_t i = 0;i<=Nx;i++,x+=dx){
749 for (Int_t j = 0;j<=Ny;j++,y+=dy){
751 hPRFc->SetBinContent(hPRFc->GetBin(i,j),z);
754 hPRFc->SetXTitle(
"pad direction (cm)");
755 hPRFc->SetYTitle(
"pad row direction (cm)");
756 hPRFc->SetTitleOffset(1.5,
"X");
757 hPRFc->SetTitleOffset(1.5,
"Y");
766 const Float_t kminth=0.00001;
767 if (thr<kminth) thr=kminth;
770 snprintf(s,100,
"COG distortion of PRF (threshold=%2.2f)",thr);
771 AliH2F * hPRFDist =
new AliH2F(
"hDistortion",s,Nx,x1,x2,Ny,y1,y2);
772 Float_t dx=(x2-x1)/Float_t(Nx);
773 Float_t dy=(y2-y1)/Float_t(Ny) ;
776 for ( Int_t i = 0;i<=Nx;i++,x+=dx){
778 for(Int_t j = 0;j<=Ny;j++,y+=dy)
782 for (Int_t k=-3;k<=3;k++)
784 Float_t padx=Float_t(k)*
fWidth;
793 ddx = (x-(sumx/
sum));
796 if (TMath::Abs(ddx)<10) hPRFDist->SetBinContent(hPRFDist->GetBin(i,j),ddx);
800 hPRFDist->SetXTitle(
"pad direction (cm)");
801 hPRFDist->SetYTitle(
"pad row direction (cm)");
802 hPRFDist->SetTitleOffset(1.5,
"X");
803 hPRFDist->SetTitleOffset(1.5,
"Y");
816 TCanvas * c1 =
new TCanvas(
"PRFX",
"Pad response function",700,900);
819 TPaveText *
comment =
new TPaveText(0.05,0.02,0.95,0.20,
"NDC");
820 comment->SetTextAlign(12);
821 comment->SetFillColor(42);
826 TPad * pad2 =
new TPad(
"pPRF",
"",0.05,0.22,0.95,0.95);
827 pad2->Divide(2,(N+1)/2);
831 for (Int_t i=0;i<N;i++){
835 else y = y1+i*(y2-y1)/Float_t(N-1);
839 snprintf(ch,40,
"PRF at wire position: %2.3f",y);
842 snprintf(ch,15,
"PRF %d",i);
855 TCanvas * c1 =
new TCanvas(
"canPRF",
"Pad response function",700,900);
857 TPad * pad2 =
new TPad(
"pad2PRF",
"",0.05,0.22,0.95,0.95);
865 TPaveText *
comment =
new TPaveText(0.05,0.02,0.95,0.20,
"NDC");
866 comment->SetTextAlign(12);
867 comment->SetFillColor(42);
876 TCanvas * c1 =
new TCanvas(
"padDistortion",
"COG distortion",700,900);
878 TPad * pad1 =
new TPad(
"dist",
"",0.05,0.55,0.95,0.95,21);
880 TPad * pad2 =
new TPad(
"dist",
"",0.05,0.22,0.95,0.53,21);
888 hPRFDist->Draw(
"surf");
889 Float_t distmax =hPRFDist->GetMaximum();
890 Float_t distmin =hPRFDist->GetMinimum();
893 TH1F * dist = hPRFDist->
GetAmplitudes(distmin,distmax,distmin-1);
897 TPaveText *
comment =
new TPaveText(0.05,0.02,0.95,0.20,
"NDC");
898 comment->SetTextAlign(12);
899 comment->SetFillColor(42);
910 TText * title = comment->AddText(
"Pad Response Function parameters:");
911 title->SetTextSize(0.03);
913 snprintf(s,100,
"Height of pad: %2.2f cm",
fHeightFull);
916 snprintf(s,100,
"Width pad: %2.2f cm",
fWidth);
919 snprintf(s,100,
"Pad Angle: %2.2f ",
fPadAngle);
922 if (TMath::Abs(
fK)>0.0001){
924 snprintf(s,100,
"Height of one chevron unit h: %2.2f cm",2*
fHeightS);
927 snprintf(s,100,
"Overlap factor: %2.2f",
fK);
931 if (strncmp(
fType,
"User",3)==0){
933 snprintf(s,100,
"Charge distribution - user defined function %s ",
fGRF->GetTitle());
936 snprintf(s,100,
"Sigma x of charge distribution: %2.2f ",
fOrigSigmaX);
939 snprintf(s,100,
"Sigma y of charge distribution: %2.2f ",
fOrigSigmaY);
942 if (strncmp(
fType,
"Gauss",3)==0){
944 snprintf(s,100,
"Gauss charge distribution");
947 snprintf(s,100,
"Sigma x of charge distribution: %2.2f ",
fOrigSigmaX);
950 snprintf(s,100,
"Sigma y of charge distribution: %2.2f ",
fOrigSigmaY);
953 if (strncmp(
fType,
"Gati",3)==0){
955 snprintf(s,100,
"Gati charge distribution");
958 snprintf(s,100,
"K3X of Gati : %2.2f ",
fK3X);
961 snprintf(s,100,
"K3Y of Gati: %2.2f ",
fK3Y);
964 snprintf(s,100,
"Wire to Pad Distance: %2.2f ",
fPadDistance);
967 if (strncmp(
fType,
"Cosh",3)==0){
969 snprintf(s,100,
"Cosh charge distribution");
972 snprintf(s,100,
"Sigma x of charge distribution: %2.2f ",
fOrigSigmaX);
975 snprintf(s,100,
"Sigma y of charge distribution: %2.2f ",
fOrigSigmaY);
979 snprintf(s,100,
"Normalisation: %2.2f ",
fKNorm);
static Double_t FunGauss2D(const Double_t *const x, const Double_t *const par)
Float_t fChargeAngle
'angle' of charge distribution refernce system to pad reference system
Float_t fSigmaY
sigma Y of PAD response function
Float_t fShiftY
shift of the step
Float_t fY2
position of last virtual vire
static Double_t FunGati2D(const Double_t *const x, const Double_t *const par)
Float_t fK3X
KX parameter (only for Gati parametrization)
Int_t fNYdiv
number of wires
Float_t fDStepM1
! used in GetPRFActiv to make calculation faster
virtual void DrawPRF(Float_t x1, Float_t x2, Float_t y1, Float_t y2, Int_t Nx=20, Int_t Ny=20)
Float_t fSigmaX
sigma X of PAD response function
void DrawComment(TPaveText *comment)
static Double_t FunCosh2D(const Double_t *const x, const Double_t *const par)
virtual void UpdateSigma()
static const Double_t fgkDegtoRad
numeric constant
Float_t fOrigSigmaY
sigma of original distribution;
Int_t fNdiv
number of division to calculate integral
virtual void DrawX(Float_t x1, Float_t x2, Float_t y1, Float_t y2=0, Int_t N=1)
Float_t fDYtoWire
! used to make PRF calculation faster in GetPRF
Float_t fHeightS
height of the one step
virtual void SetGati(Float_t K3X, Float_t K3Y, Float_t padDistance, Float_t kNorm=1)
TH1F * GetAmplitudes(Float_t zmin, Float_t zmax, Float_t th=1., Float_t xmin=0, Float_t xmax=0, Float_t ymin=0, Float_t ymax=0)
Float_t fPadAngle
'angle' of the pad assymetry
virtual void DrawDist(Float_t x1, Float_t x2, Float_t y1, Float_t y2, Int_t Nx=20, Int_t Ny=20, Float_t thr=0)
virtual void SetChParam(Float_t width, Float_t height, Float_t hstep, Float_t shifty, Float_t fac)
Float_t fOrigSigmaX
sigma of original distribution;
Float_t fCurrentY
in reality we calculate PRF only for one fixed y
Float_t fK
k factor of the chewron
virtual void SetCosh(Float_t sigmaX, Float_t sigmaY, Float_t kNorm=1)
Float_t fMeanY
mean Y value
Pad response function object in two dimesions.
Float_t fPadDistance
pad anode distnce (only for Gati parametrisation)
Int_t fInterY
interpolation in Y
Float_t GetPRFActiv(Float_t xin)
virtual void SetPad(Float_t width, Float_t height)
TF2 * fGRF
charge distribution function
virtual Float_t GetPRF(Float_t xin, Float_t yin)
Float_t fY1
position of first "virtual" vire
AliH2F * GenerDrawDistHisto(Float_t x1, Float_t x2, Float_t y1, Float_t y2, Int_t Nx=20, Int_t Ny=20, Float_t thr=0)
TH1F * GenerDrawXHisto(Float_t x1, Float_t x2, Float_t y)
Float_t fMeanX
mean X value
Float_t fKNorm
normalisation factor of the charge integral
Float_t fInteg
integral of GRF on +- infinity
Float_t fK3Y
KY parameter (only for Gati parametrisation)
AliH2F * GenerDrawHisto(Float_t x1, Float_t x2, Float_t y1, Float_t y2, Int_t Nx=20, Int_t Ny=20)
void SetParam(TF2 *const GRF, Float_t kNorm, Float_t sigmaX=0, Float_t sigmaY=0)
static const Double_t fgkSQRT12
numeric constant
Float_t fHeightFull
height of the full pad
virtual void SetGauss(Float_t sigmaX, Float_t sigmaY, Float_t kNorm=1)
virtual void SetY(Float_t y1, Float_t y2, Int_t nYdiv)
virtual void SetChevron(Float_t hstep, Float_t shifty, Float_t fac)
static const Int_t fgkNPRF
default number of division
Float_t * fcharge
! field with PRF
Double_t funParam[5]
parameters of used charge function
Float_t fDStep
element step for point
Float_t fWidth
width of the pad
Float_t * fChargeArray
pointer to array of arrays
Int_t fNPRF
number of interpolations point