#include "TPolyLine3D.h"
#include "KDetector.h"
#include "TFile.h"
#define ABS(x) x>0?x:-x
#define PREDZNAK(x) x>0?1:-1
#define C1(x,y,z) y3[n]=x+y+z;
#define L1(x) y2[n]=x;
#define R1(x) y4[n]=x;
#define U1(x) y5[n]=x;
#define D1(x) y6[n]=x;
#define I1(x) y7[n]=x;
#define O1(x) y8[n]=x;
#define L2(x) y2[n]=2*x;
#define R2(x) y4[n]=2*x;
#define U2(x) y5[n]=2*x;
#define D2(x) y6[n]=2*x;
#define I2(x) y7[n]=2*x;
#define O2(x) y8[n]=2*x;
#define C0 y3[n]=1.;
#define U0 y5[n]=0.;
#define D0 y6[n]=0.;
#define R0 y4[n]=0.;
#define L0 y2[n]=0.;
#define I0 y7[n]=0.;
#define O0 y8[n]=0.;
#define PI 3.1415927
#define EPS 1.0e-14
#define STEP_DET_CUR 25e-9
ClassImp(KDetector)
// #frac{d^{2}f(x)}{dx^{2}}=#frac{f(x+h1)-2*f(x+0.5(h1-h2))+f(x-h2)}{(0.5 h1+ 0.5 h2)^{2}}
// h1=h2=h
// #frac{d^{2}f(x)}{dx^{2}}=#frac{f(x+h)-2*f(x)+f(x-h)}{h^{2}}
// END_LATEX
double **a,*b,*y6,*y2,*y3,*y4,*y5,*y7,*y8;
double *dvector(long, long);
void free_dvector(double*,long,long);
double snrm(unsigned long n, double sx[], int itol)
{
unsigned long i,isamax;
double ans;
if (itol <= 3) {
ans = 0.0;
for (i=1;i<=n;i++) ans += sx[i]*sx[i];
return sqrt(ans);
} else {
isamax=1;
for (i=1;i<=n;i++) {
if (fabs(sx[i]) > fabs(sx[isamax])) isamax=i;
}
return fabs(sx[isamax]);
}
}
void atimes(unsigned long n,int dim[], double x[],double r[],int itrnsp)
{
int nx,ny,nz;
int i,j,k,q=0;
double C,L,D,O,R,U,I;
nx=dim[0]; ny=dim[1]; nz=dim[2];
for(k=1; k<=nz; k++)
for(j=1; j<=ny; j++)
for(i=1; i<=nx; i++)
{
q++;
C=y3[q]*x[q];
if(q-1>1) L=y2[q]*x[q-1]; else L=0;
if(q-nx>1) D=y6[q]*x[q-nx]; else D=0;
if((q-nx*ny)>1) I=y7[q]*x[q-ny*nx]; else I=0;
if(q+1<=n) R=y4[q]*x[q+1]; else R=0;
if(q+nx<=n) U=y5[q]*x[q+nx]; else U=0;
if((q+nx*ny)<=n) O=y8[q]*x[q+ny*nx]; else O=0;
r[q]=C+L+D+O+R+U+I;
}
if(n!=q) printf("\n Error in matrix solving!");
return;
}
void asolve(unsigned long n, double b[], double x[], int itrnsp)
{
unsigned long i;
for(i=1;i<=n;i++) x[i]=(y3[i] != 0.0 ? b[i]/y3[i] : b[i]);
}
void linbcg(unsigned long n, int dim[], double b[], double x[], int itol, double tol,
int itmax, int *iter, double *err)
{
void asolve(unsigned long n, double b[], double x[], int itrnsp);
void atimes(unsigned long n, int dim[],double x[], double r[], int itrnsp);
double snrm(unsigned long n, double sx[], int itol);
double *dvector(long, long);
void free_dvector(double *, long, long);
void nrerror(char error_text[]);
unsigned long j;
double ak,akden,bk,bkden,bknum,bnrm,dxnrm,xnrm,zm1nrm,znrm;
double *p,*pp,*r,*rr,*z,*zz;
p=dvector(1,n);
pp=dvector(1,n);
r=dvector(1,n);
rr=dvector(1,n);
z=dvector(1,n);
zz=dvector(1,n);
*iter=0;
atimes(n,dim,x,r,0);
for (j=1;j<=n;j++) {
r[j]=b[j]-r[j];
rr[j]=r[j];
}
atimes(n,dim,r,rr,0);
znrm=1.0;
if (itol == 1) bnrm=snrm(n,b,itol);
else if (itol == 2) {
asolve(n,b,z,0);
bnrm=snrm(n,z,itol);
}
else if (itol == 3 || itol == 4) {
asolve(n,b,z,0);
bnrm=snrm(n,z,itol);
asolve(n,r,z,0);
znrm=snrm(n,z,itol);
} else nrerror("illegal itol in linbcg");
asolve(n,r,z,0);
while (*iter <= itmax) {
++(*iter);
zm1nrm=znrm;
asolve(n,rr,zz,1);
for (bknum=0.0,j=1;j<=n;j++) bknum += z[j]*rr[j];
if (*iter == 1) {
for (j=1;j<=n;j++) {
p[j]=z[j];
pp[j]=zz[j];
}
}
else {
bk=bknum/bkden;
for (j=1;j<=n;j++) {
p[j]=bk*p[j]+z[j];
pp[j]=bk*pp[j]+zz[j];
}
}
bkden=bknum;
atimes(n,dim,p,z,0);
for (akden=0.0,j=1;j<=n;j++) akden += z[j]*pp[j];
ak=bknum/akden;
atimes(n,dim,pp,zz,1);
for (j=1;j<=n;j++) {
x[j] += ak*p[j];
r[j] -= ak*z[j];
rr[j] -= ak*zz[j];
}
asolve(n,r,z,0);
if (itol == 1 || itol == 2) {
znrm=1.0;
*err=snrm(n,r,itol)/bnrm;
} else if (itol == 3 || itol == 4) {
znrm=snrm(n,z,itol);
if (fabs(zm1nrm-znrm) > EPS*znrm) {
dxnrm=fabs(ak)*snrm(n,p,itol);
*err=znrm/fabs(zm1nrm-znrm)*dxnrm;
} else {
*err=znrm/bnrm;
continue;
}
xnrm=snrm(n,x,itol);
if (*err <= 0.5*xnrm) *err /= xnrm;
else {
*err=znrm/bnrm;
continue;
}
}
if(*iter==itmax) {printf("\n Number of iterations exceeded the max. value \n");
printf("iter=%4d err=%12.6f\n",*iter,*err);}
if (*err <= tol) break;
}
free_dvector(p,1,n);
free_dvector(pp,1,n);
free_dvector(r,1,n);
free_dvector(rr,1,n);
free_dvector(z,1,n);
free_dvector(zz,1,n);
}
double KDetector::V(int val, int dowhat)
{
double voltage;
int k=0;
if(dowhat==0)
{
if(val&1) voltage=0;
if(val&2) voltage=Voltage;
if(val & 32768)
voltage=Voltages[val>>16];
}
else
{
if(val&16384) voltage=10000; else voltage=0;
}
return voltage;
}
Double_t KDetector::kappa(int i,int j, int k, int dowhat )
{
Double_t x,y,z,ret;
x=EG->GetXaxis()->GetBinCenter(i);
y=EG->GetYaxis()->GetBinCenter(j);
z=EG->GetZaxis()->GetBinCenter(k);
if(DM!=NULL) KMaterial::Mat=DM->GetBinContent(i,j,k); else KMaterial::Mat=0;
if (dowhat==0)
{
if(NeffF!=NULL)
ret=(NeffF->Eval(x,y,z)*1e6*e_0)/(perm0);
if(NeffH!=NULL)
ret=(NeffH->GetBinContent(i,j,k)*1e6*e_0)/(perm0);
}
else
ret=0.;
return ret;
}
void KDetector::Declaration(Int_t dowhat)
{
Int_t i,j,k,val;
Double_t Rd,Ld,Dd,Ud,Od,Id;
Double_t PRd,PLd,PDd,PUd,POd,PId;
Double_t Xr=0,Yr=0,Zr=0;
Double_t Xc=0,Yc=0,Zc=0;
Double_t Xl=0,Yl=0,Zl=0;
Int_t ii,jj,kk;
Double_t fac;
long n=0;
Int_t num=nx*ny*nz;
for (k=1;k<=nz;k++)
for (j=1;j<=ny;j++)
for(i=1;i<=nx;i++)
{
n=(k-1)*nx*ny+(j-1)*nx+i;
if(j-1<1) jj=1; else jj=j-1;
if(i-1<1) ii=1; else ii=i-1;
if(k-1<1) kk=1; else kk=k-1;
Rd=fabs(EG->GetXaxis()->GetBinCenter(i+1)-EG->GetXaxis()->GetBinCenter(i));
Ld=fabs(EG->GetXaxis()->GetBinCenter(i)-EG->GetXaxis()->GetBinCenter(i-1));
if(i+1>nx) Rd=Ld; if(i-1<1) Ld=Rd;
PRd=Perm(DM->GetBinContent(i,j,k))+Perm(DM->GetBinContent(i,jj,k));
if(nz!=1)
{
PRd+=Perm(DM->GetBinContent(i,j,kk))+Perm(DM->GetBinContent(i,jj,kk));
PRd/=4;
} else PRd/=2;
PLd=Perm(DM->GetBinContent(ii,j,k))+Perm(DM->GetBinContent(ii,jj,k));
if(nz!=1)
{
PLd+=Perm(DM->GetBinContent(ii,j,kk))+Perm(DM->GetBinContent(ii,jj,kk));
PLd/=4;
} else PLd/=2;
Ud=fabs(EG->GetYaxis()->GetBinCenter(j+1)-EG->GetYaxis()->GetBinCenter(j));
Dd=fabs(EG->GetYaxis()->GetBinCenter(j)-EG->GetYaxis()->GetBinCenter(j-1));
if(j+1>ny) Ud=Dd; if(j-1<1) Dd=Ud;
PUd=Perm(DM->GetBinContent(i,j,k)) +Perm(DM->GetBinContent(ii,j,k));
if(nz!=1)
{
PUd+=Perm(DM->GetBinContent(i,j,kk))+Perm(DM->GetBinContent(ii,j,kk));
PUd/=4;
} else PUd/=2;
PDd=Perm(DM->GetBinContent(i,jj,k))+Perm(DM->GetBinContent(ii,jj,k));
if(nz!=1)
{
PDd+=Perm(DM->GetBinContent(i,jj,kk))+Perm(DM->GetBinContent(ii,jj,kk));
PDd/=4;
} else PDd/=2;
Od=fabs(EG->GetZaxis()->GetBinCenter(k+1)-EG->GetZaxis()->GetBinCenter(k));
Id=fabs(EG->GetZaxis()->GetBinCenter(k)-EG->GetZaxis()->GetBinCenter(k-1));
if(k+1>nz) Od=Id; if(k-1<1) Id=Od;
if(nz!=1)
{
POd=Perm(DM->GetBinContent(i,jj,k))+Perm(DM->GetBinContent(i,j,k))+
Perm(DM->GetBinContent(ii,j,k))+Perm(DM->GetBinContent(ii,jj,k));
PId=Perm(DM->GetBinContent(i,jj,kk))+Perm(DM->GetBinContent(i,j,kk))+
Perm(DM->GetBinContent(ii,j,kk))+Perm(DM->GetBinContent(ii,jj,kk));
POd/=4;
PId/=4;
}
if(dowhat==1) {PRd=1; PLd=1; PUd=1; PDd=1; POd=1; PId=1;}
Xr=PRd/(0.5*Rd*(Rd+Ld));
Xl=PLd/(0.5*Ld*(Rd+Ld)); Xc=-(Xr+Xl);
Yr=PUd/(0.5*Ud*(Ud+Dd));
Yl=PDd/(0.5*Dd*(Ud+Dd)); Yc=-(Yr+Yl);
if(nz!=1)
{
Zr=POd/(0.5*Od*(Od+Id));
Zl=PId/(0.5*Id*(Od+Id)); Zc=-(Zr+Zl);
}
b[n]=0.;
val=EG->GetBinContent(i,j,k);
if(nz==1) { C1(Xc,Yc,0) I0 O0 }
else { C1(Xc,Yc,Zc) I1(Zl) O1(Zr) }
R1(Xr) U1(Yr) L1(Xl) D1(Yl)
if(val&4) {D0 b[n]-=V(EG->GetBinContent(i,j-1,k),dowhat)*Yl;}
if(val&8) {U0 b[n]-=V(EG->GetBinContent(i,j+1,k),dowhat)*Yr;}
if(val&16) {L0 b[n]-=V(EG->GetBinContent(i-1,j,k),dowhat)*Xl;}
if(val&32) {R0 b[n]-=V(EG->GetBinContent(i+1,j,k),dowhat)*Xr;}
if(val&1024) {I0 b[n]-=V(EG->GetBinContent(i,j,k-1),dowhat)*Zl;}
if(val&2048) {O0 b[n]-=V(EG->GetBinContent(i,j,k+1),dowhat)*Zr;}
if(val&64) {U2(Yr) D0 if(val&8) {U0 b[n]-=V(EG->GetBinContent(i,j+1,k),dowhat)*Yr;}}
if(val&128) {D2(Yl) U0 if(val&4) {D0 b[n]-=V(EG->GetBinContent(i,j-1,k),dowhat)*Yl;}}
if(val&256) {R2(Xr) L0 if(val&32) {R0 b[n]-=V(EG->GetBinContent(i+1,j,k),dowhat)*Xr;}}
if(val&512) {L2(Xl) R0 if(val&16) {L0 b[n]-=V(EG->GetBinContent(i-1,j,k),dowhat)*Xl;}}
if(val&4096) {O2(Zr) I0 if(val&2048) {O0 b[n]-=V(EG->GetBinContent(i,j,k+1),dowhat)*Zr;}}
if(val&8192) {I2(Zl) O0 if(val&1024) {I0 b[n]-=V(EG->GetBinContent(i,j,k-1),dowhat)*Zl;}}
b[n]-=kappa(i,j,k,dowhat);
if(val&1 || val&2 || val>=32768) {U0 D0 L0 R0 C0 O0 I0 b[n]=V(val,dowhat);}
}
}
void KDetector::CalField(Int_t what)
{
double err;
int iteracije,i;
int num=nx*ny*nz,dim[3];
Double_t *x;
b=dvector(1,num); y6=dvector(1,num); y2=dvector(1,num);
y3=dvector(1,num); y4=dvector(1,num); y5=dvector(1,num);
y7=dvector(1,num); y8=dvector(1,num);
x=dvector(1,num);
printf("Setting up matrix ... \n");
Declaration(what);
printf("Solving matrix ...\n");
for(i=1;i<=num;i++) x[i]=1.;
dim[0]=nx; dim[1]=ny; dim[2]=nz;
linbcg(num,dim,b,x,1,CalErr,MaxIter,&iteracije,&err);
if(!what)
{
Real->U=MapToGeometry(x);
Real->CalField();
}
else
{
Ramo->U=MapToGeometry(x,1e-4);
Ramo->CalField();
}
free_dvector(x, 1,num); free_dvector(b, 1,num); free_dvector(y2, 1,num);
free_dvector(y3, 1,num); free_dvector(y4, 1,num); free_dvector(y5, 1,num);
free_dvector(y6, 1,num); free_dvector(y7, 1,num); free_dvector(y8, 1,num);
}
void KDetector::Drift(Double_t sx, Double_t sy, Double_t sz, Float_t charg, KStruct *seg, Double_t t0)
{
Double_t Stime=0;
Double_t difx=0,dify=0,difz=0;
Double_t sigma;
Float_t *xcv,*ycv,*zcv,*time,*charge;
Double_t cx=0,cy=0,cz=0;
Double_t vel=0;
Double_t t=0;
Double_t sumc=0;
Double_t ncx=0,ncy=0,ncz=0;
Double_t deltacx,deltacy,deltacz;
Int_t st=0;
Int_t ishit=0;
TVector3 *EE;
TVector3 *EEN;
TVector3 FF;
Float_t pathlen=0;
Float_t WPot;
TVector3 BB(B);
Float_t muhe=1650;
Float_t muhh=310;
t=t0;
xcv=seg->Xtrack;
ycv=seg->Ytrack;
zcv=seg->Ztrack;
time=seg->Time;
charge=seg->Charge;
seg->Clear();
seg->PCharge=(Int_t) charg;
cx=sx; cy=sy; cz=sz;
xcv[st]=cx; ycv[st]=cy; zcv[st]=cz;
time[st]=t; charge[st]=0;
EE=Real->CalFieldXYZ(cx,cy,cz);
seg->Efield[st]=EE->Mag();
do
{
st++;
if(charg>0)
FF=(*EE)+muhh*EE->Cross(BB); else
FF=(*EE)-muhe*EE->Cross(BB);
if(FF.Mag()!=0)
{
deltacy=-SStep*charg*FF.y()/FF.Mag();
deltacx=-SStep*charg*FF.x()/FF.Mag();
deltacz=-SStep*charg*FF.z()/FF.Mag();
}
else { deltacx=0; deltacy=0; deltacz=0; }
if(DM!=NULL)
KMaterial::Mat=DM->GetBinContent(DM->FindBin(cx,cy,cz));
else KMaterial::Mat=0;
EEN=Real->CalFieldXYZ(cx+deltacx,cy+deltacy,cz+deltacz);
vel=Real->DriftVelocity( (EEN->Mag()+EE->Mag())/2,charg,Temperature,TMath::Abs(NeffF->Eval(cx,cy,cz)),MobMod());
if(vel==0) {
deltacx=0; deltacy=0; deltacz=0;
difx=0; dify=0; difz=0;
ishit=9;
}
else
if(diff)
{
Stime=SStep*1e-4/vel;
sigma=TMath::Sqrt(2*Kboltz*Real->Mobility(EE->Mag(),Temperature,charg,TMath::Abs(NeffF->Eval(cx,cy,cz)),MobMod())*Temperature*Stime);
dify=ran->Gaus(0,sigma)*1e4;
difx=ran->Gaus(0,sigma)*1e4;
if(nz!=1) difz=ran->Gaus(0,sigma)*1e4; else difz=0;
}
if((cx+deltacx+difx)>=GetUpEdge(0)) ncx=GetUpEdge(0); else
if((cx+deltacx+difx)<GetLowEdge(0)) ncx=GetLowEdge(0); else
ncx=cx+(deltacx+difx);;
if((cy+deltacy+dify)>=GetUpEdge(1)) ncy=GetUpEdge(1); else
if((cy+deltacy+dify)<GetLowEdge(1)) ncy=GetLowEdge(1); else
ncy=cy+(deltacy+dify);
if((cz+deltacz+difz)>=GetUpEdge(2)) ncz=GetUpEdge(2); else
if((cz+deltacz+difz)<GetLowEdge(2)) ncz=GetLowEdge(2); else
ncz=cz+(deltacz+difz);
if(Debug) printf("%d %f E=%e: x:%f->%f y:%f->%f z:%f->%f (%f %f %f): Mat=%d :: ",st,charg,EEN->Mag(),cx,ncx,cy,ncy,cz,ncz,deltacx,deltacy,deltacz, KMaterial::Mat);
charge[st]=charg*(Ramo->CalPotXYZ(ncx,ncy,ncz)-Ramo->CalPotXYZ(cx,cy,cz));
cx=ncx; cy=ncy; cz=ncz;
sumc+=charge[st];
if(vel!=0)
{
t=t+SStep*1e-4/vel;
pathlen+=SStep;
}
xcv[st]=cx;
ycv[st]=cy;
zcv[st]=cz;
time[st]=t;
EE=Real->CalFieldXYZ(cx,cy,cz);
seg->Efield[st]=EE->Mag();
WPot=Ramo->CalPotXYZ(cx,cy,cz);
if(WPot>(1-Deps)) ishit=1;
if(cx<= GetLowEdge(0)) ishit=3;
if(cx>= GetUpEdge(0)) ishit=4;
if(cy<= GetLowEdge(1)) ishit=5;
if(cy>= GetUpEdge(1)) ishit=6;
if(cz<= GetLowEdge(2)) ishit=7;
if(cz>= GetUpEdge(2)) ishit=8;
if(st>=MAXPOINT-1) ishit=10;
if(Debug) printf("(t=%e, vel=%e) [Ch=%f ChInt=%f] Ishit=%d \n",t,vel,charge[st],sumc,ishit);
} while (!ishit);
(*seg).Xlenght=pathlen; (*seg).Ylenght=pathlen;
(*seg).TTime=t; (*seg).TCharge=sumc; (*seg).Steps=st;
delete EE; delete EEN;
return;
}
TH1F *KDetector::Draw1D(Char_t *option, Float_t proj,Int_t axis,Float_t pos)
{
TH2F *his=Draw(option,proj);
Int_t iter,*x,*y,i,j;
Float_t low,up;
if(axis==0)
{
iter=his->GetNbinsX();
up=his->GetXaxis()->GetBinUpEdge(iter);
low=his->GetXaxis()->GetBinLowEdge(1);
}
else
{
iter=his->GetNbinsY();
up=his->GetYaxis()->GetBinUpEdge(iter);
low=his->GetYaxis()->GetBinLowEdge(1);
}
TH1F *his1D=new TH1F("Projection","Projection",iter,low,up);
for(i=1;i<=iter;i++)
{
if(axis==0) his1D->SetBinContent(i, his->GetBinContent(i,his->GetYaxis()->FindBin(pos)));
else
his1D->SetBinContent(i, his->GetBinContent( his->GetXaxis()->FindBin(pos),i));
}
return his1D;
}
TH2F *KDetector::Draw(Char_t *option, Float_t proj)
{
KField *cf;
TH3F *ch;
TH2F *histo=new TH2F();
TString opt(option);
Int_t i=0;
Int_t iproj=0;
Int_t What=1;
Int_t Which=0;
Int_t Which3D=3;
if(opt.Contains("N")) What=5;
if(opt.Contains("M")) What=4;
if(opt.Contains("G")) What=3;
if(opt.Contains("W")) What=2;
if(opt.Contains("E")) What=1;
if(nz>1)
{
if(opt.Contains("xy")) Which3D=3;
if(opt.Contains("xz")) Which3D=2;
if(opt.Contains("yz")) Which3D=1;
}
if(opt.Contains("P")) Which=0;
if(opt.Contains("F")) Which=1;
if(opt.Contains("X")) Which=2;
if(opt.Contains("Y")) Which=3;
if(opt.Contains("Z")) Which=4;
if(What<=2)
{
if(What==2) cf=Ramo; else cf=Real;
switch(Which)
{
case 0: ch=cf->U; break;
case 1: ch=cf->E; break;
case 2: ch=cf->Ex; break;
case 3: ch=cf->Ey; break;
case 4: ch=cf->Ez; break;
default: ch=cf->U; break;
}
}
else
{
if(What==3) ch=(TH3F *)EG;
if(What==4) ch=(TH3F *)DM;
if(What==5) ch=(TH3F *)NeffH;
}
if(nz==1) histo=KHisProject(ch,3,1);
else
{
switch(Which3D)
{
case 3: iproj=ch->GetZaxis()->FindBin(proj); break;
case 2: iproj=ch->GetYaxis()->FindBin(proj); break;
case 1: iproj=ch->GetXaxis()->FindBin(proj); break;
}
histo=KHisProject(ch,Which3D,iproj);
}
return histo;
}
void KDetector::MipIR(Int_t div, Float_t lambda)
{
Double_t data[4];
Float_t sp[3];
Float_t Io,len=0,lent=0,lenlam,scalef=0,pscalef=0,mule,mulh;
int i,j,k,e;
KStruct seg,segmul;
TH1F *histop = new TH1F("ch-","charge+",pos->GetNbinsX(),pos->GetXaxis()->GetXmin(),pos->GetXaxis()->GetXmax());
TH1F *histon = new TH1F("ch+","charge-",neg->GetNbinsX(),neg->GetXaxis()->GetXmin(),neg->GetXaxis()->GetXmax());
sum->Reset(); pos->Reset(); neg->Reset();
if(lambda!=0)
{
for(k=0;k<3;k++) lent+=TMath::Power(exp[k]-enp[k],2); lent=TMath::Sqrt(lent);
lenlam=lent/lambda;
Io=div/(lambda*(1-TMath::Exp(-lenlam)));
}
for(i=0;i<div;i++)
{
for(j=0;j<3;j++) {sp[j]=((exp[j]-enp[j])/div)*i+enp[j]+(exp[j]-enp[j])/(2*div);}
for(j=0;j<average;j++)
{
Drift(sp[0],sp[1],sp[2],1,&seg);
seg.GetCH(histop,1,1,tauh);
Drift(sp[0],sp[1],sp[2],-1,&seg);
if(MTresh>1)
{
mule=seg.GetCHMult(histon,1,1,taue);
}
else
seg.GetCH(histon,1,1,taue);
if(mule>MTresh && MTresh>1)
{
for(e=1;e<seg.Steps+1;e++)
{
Drift(seg.Xtrack[e],seg.Ytrack[e],seg.Ztrack[e],1,&segmul,seg.Time[e]);
mulh=segmul.GetCHMult(histop,1,seg.MulCar[e],tauh);
if(mulh>BDTresh) {printf("HOLE MULTIPLICATION - BREAKDOWN\n"); BreakDown=1;}
}
}
}
histop->Scale(1/((Float_t)average)); histon->Scale(1/((Float_t)average));
if(lambda!=0)
{
len=0; for(k=0;k<3;k++) len+=TMath::Power(sp[k]-enp[k],2); len=TMath::Sqrt(len);
scalef=Io*TMath::Exp(-len/lambda);
histon->Scale(scalef); histop->Scale(scalef);
pscalef+=scalef;
histop->Scale(lent/div); histon->Scale(lent/div);
}
pos->Add(histop);neg->Add(histon);
histop->Reset();
histon->Reset();
}
sum->Add(neg);
sum->Add(pos);
delete histop;
delete histon;
}
void KDetector::ShowMipIR(Int_t div, Int_t color,Int_t how)
{
TGraph *gr;
TPolyLine3D *gr3D;
Float_t sp[3];
int i,j;
KStruct seg;
TLine *line;
if(EG!=NULL)
{
if(nz==1) KHisProject(EG,3,how)->Draw("COL");
else
{
TH3F *hh=GetGeom();
hh->SetFillColor(color);
hh->Draw("iso");
}
}
for(i=0;i<div;i++)
{
for(j=0;j<3;j++) {sp[j]=((exp[j]-enp[j])/div)*i+enp[j]+(exp[j]-enp[j])/(2*div);}
if(Debug) printf("Entry Point: %f %f %f \n",sp[0],sp[1],sp[2]);
Drift(sp[0],sp[1],sp[2],1,&seg);
if(nz==1)
gr=new TGraph(seg.Steps,&seg.Xtrack[1],&seg.Ytrack[1]);
else
gr3D=new TPolyLine3D(seg.Steps,&seg.Xtrack[1],&seg.Ytrack[1],&seg.Ztrack[1]);
if(nz==1)
{
gr->SetLineColor(2);
gr->SetLineStyle(1);
gr->Draw("L");
}
else
{
gr3D->SetLineStyle(1);
gr3D->SetLineColor(2);
gr3D->Draw("SAME");
}
Drift(sp[0],sp[1],sp[2],-1,&seg);
if(nz==1)
gr=new TGraph(seg.Steps,&seg.Xtrack[1],&seg.Ytrack[1]);
else
gr3D=new TPolyLine3D(seg.Steps,&seg.Xtrack[1],&seg.Ytrack[1],&seg.Ztrack[1]);
if(nz==1)
{
gr->SetLineColor(4);
gr->SetLineStyle(3);
gr->Draw("L");
}
else
{
gr3D->SetLineStyle(1);
gr3D->SetLineColor(4);
gr3D->Draw("SAME");
}
}
}
KDetector::KDetector()
{
NeffF=new TF3("Profile","x[0]*x[1]*x[2]*0+[0]",0,1000,0,1000,0,1000);
NeffF->SetParameter(0,0);
NeffH=NULL;
for(Int_t i=0;i<3;i++) B[i]=0;
ran=new TRandom(33);
CalErr=1e-6;
MaxIter=2000;
pos=NULL; neg=NULL; sum=NULL;
SetDriftHisto(25e-9);
taue=-1;
tauh=-1;
MTresh=-1;
BDTresh=-1;
Deps=1e-5;
average=1;
diff=0;
SStep=1;
Temperature=263;
BreakDown=0;
Debug=0;
Voltage2=0;
Ramo=new KField();
Real=new KField();
}
KDetector::~KDetector()
{
if(NeffF!=NULL) delete NeffF;
if(NeffH!=NULL) delete NeffH;
if(ran!=NULL) delete ran;
if(pos!=NULL) delete pos;
if(neg!=NULL) delete neg;
if(sum!=NULL) delete sum;
}
void KDetector::CalM(KStruct *seg, Double_t *data, Int_t CarrierType)
{
Int_t i,j,numreg=0;
Double_t *M=new Double_t [seg->Steps+1];
Double_t *DIF=new Double_t [seg->Steps+1];
Double_t dx,dy,sum=1.,sum2=0,sum1=0,dif,dif1,dif2;
for(i=1; i<seg->Steps;i++)
{
dx=TMath::Sqrt(TMath::Power((seg->Xtrack[i+1]-seg->Xtrack[i]),2)+TMath::Power((seg->Ytrack[i+1]-seg->Ytrack[i]),2));
if(CarrierType<0)
dif=Real->alpha(0.5*(seg->Efield[i+1]+seg->Efield[i]));
else
dif=Real->beta(0.5*(seg->Efield[i+1]+seg->Efield[i]));
sum*=(1+dif*dx);
DIF[i]=sum;
}
data[0]=DIF[seg->Steps-1]; data[1]=0; data[2]=0; data[3]=0;
for(i=1;i<seg->Steps;i++)
{
if((DIF[i]-1)/(data[0]-1)>0.8 && DIF[i]>1.02)
{
data[1]+=seg->Xtrack[i]; data[2]+=seg->Ytrack[i];
data[3]+=seg->Time[i]; numreg++;
}
}
if(numreg!=0) {data[1]/=numreg; data[2]/=numreg; data[3]/=numreg;}
}
void KDetector::SetDriftHisto(Float_t x, Int_t numbins)
{
if(x<0 || x>10000e-9)
printf("Selected time range out of scope !\n");
else
{
if(pos!=NULL) delete pos;
pos = new TH1F("charge+","Positive Charge",numbins,0,x);
if(neg!=NULL) delete neg;
neg = new TH1F("charge-","Negative Charge",numbins,0,x);
if(sum!=NULL) delete sum;
sum = new TH1F("charge","Total Charge",numbins,0,x);
sum->SetXTitle("t [s]"); neg->SetXTitle("t [s]"); pos->SetXTitle("t [s]");
sum->SetYTitle("I [arb.]");neg->SetYTitle("I [arb.]");pos->SetYTitle("I [arb.]");
sum->GetYaxis()->SetTitleOffset(1.4); neg->GetYaxis()->SetTitleOffset(1.4); pos->GetYaxis()->SetTitleOffset(1.4);
pos->SetLineColor(2);
neg->SetLineColor(4);
sum->SetLineColor(1);
}
}
void KDetector::Save(Char_t *name,Char_t *file)
{
Char_t str[100];
TFile *fn=new TFile(file,"UPDATE");
sprintf(str,"E_%s",name);
if(Real->U!=NULL) Real->U->Write(str); else {printf("Histogram U (Electric) does not exist!\n"); return;}
sprintf(str,"W_%s",name);
if(Ramo->U!=NULL) Ramo->U->Write(str); else {printf("Histogram U (Ramo) does not exist!\n"); return;}
sprintf(str,"G_%s",name);
if(EG!=NULL) EG->Write(str); else {printf("Histogram Geometry does not exist!\n"); return;}
sprintf(str,"M_%s",name);
if(DM!=NULL) DM->Write(str); else {printf("Histogram Material does not exist!\n"); return;}
fn->Close();
}
TFile *KDetector::Read(Char_t *name,Char_t *file)
{
Char_t str[100];
TFile *fn=new TFile(file);
if(Real->U==NULL) Real->U=new TH3F();
if(Ramo->U==NULL) Ramo->U=new TH3F();
if(EG==NULL) EG=new TH3I();
if(DM==NULL) DM=new TH3I();
sprintf(str,"E_%s",name); Real->U->Read(str);
sprintf(str,"W_%s",name); Ramo->U->Read(str);
sprintf(str,"G_%s",name); EG->Read(str);
sprintf(str,"M_%s",name); DM->Read(str);
nx=EG->GetNbinsX();
ny=EG->GetNbinsY();
nz=EG->GetNbinsZ();
Real->CalField();
Ramo->CalField();
return fn;
}
void KDetector::GaussBeam(Int_t div, Float_t Lambda, Float_t w0, Float_t CellX, Float_t B, Float_t lambda)
{
Double_t data[4];
Float_t sp[3];
Float_t Io,len=0,lent=0,lenlam,scalef=0,pscalef=0,mule,mulh;
Int_t i,j,k,e,l,Kint,KAint;
KStruct seg,segmul;
Float_t pi,w,X,xr,K,KA,PenDepth;
PenDepth=1014;
pi=TMath::Pi();
xr=pi/(Lambda/3.54)*TMath::Power(w0,2);
X=enp[0]-CellX*.5;
w=w0*TMath::Power(1+TMath::Power(X/xr,2),0.5);
K=2*w/(CellX/div);
Kint=int(K);
KAint=Kint;
TH1F *histop = new TH1F("ch-","charge+",pos->GetNbinsX(),pos->GetXaxis()->GetXmin(),pos->GetXaxis()->GetXmax());
TH1F *histon = new TH1F("ch+","charge-",neg->GetNbinsX(),neg->GetXaxis()->GetXmin(),neg->GetXaxis()->GetXmax());
sum->Reset(); pos->Reset(); neg->Reset();
if(lambda!=0)
{
for(k=0;k<3;k++) lent+=TMath::Power(exp[k]-enp[k],2);
lent=TMath::Sqrt(lent);
lenlam=lent/lambda;
Io=div/(lambda*(1-TMath::Exp(-lenlam)));
}
for(i=0;i<div;i++)
for(l=0;l<=KAint;l++)
{
for(j=0;j<3;j++) {
if ((KAint>0) && ((j==0) || (j==2)) ) {sp[j]=((exp[j]-enp[j])/div)*i+enp[j]+(exp[j]-enp[j])/(2*div);}
else if ((KAint>0) && (j==1))
{
KA=K*TMath::Exp(-sp[0]/PenDepth);
KAint=int(KA);
X=sp[0]-CellX*.5;
w=w0*TMath::Power(1+TMath::Power(X/xr,2),0.5);
if (KAint>0) {sp[j]=((exp[j]-enp[j])/div)*i+enp[j]+(exp[j]-enp[j])/(2*div)-w+w/(.5*KAint)*l;}
}
else { KAint=-1; div=-1; }
}
for(j=0;j<average;j++)
{
Drift(sp[0],sp[1],sp[2],1,&seg);
seg.GetCH(histop,1,1,tauh);
Drift(sp[0],sp[1],sp[2],-1,&seg);
if(MTresh>1)
mule=seg.GetCHMult(histon,1,1,taue);
else
seg.GetCH(histon,1,1,taue);
if(mule>MTresh && MTresh>1)
{
for(e=1;e<seg.Steps+1;e++)
{
Drift(seg.Xtrack[e],seg.Ytrack[e],seg.Ztrack[e],1,&segmul,seg.Time[e]);
mulh=segmul.GetCHMult(histop,1,seg.MulCar[e],tauh);
if(mulh>BDTresh) {printf("HOLE MULTIPLICATION - BREAKDOWN\n"); BreakDown=1;}
}
}
}
histop->Scale(1/((Float_t)average)); histon->Scale(1/((Float_t)average));
if(lambda!=0)
{
len=0;
for(k=0;k<3;k++) len+=TMath::Power(sp[k]-enp[k],2); len=TMath::Sqrt(len);
scalef=Io*TMath::Exp(-len/lambda);
histon->Scale(scalef); histop->Scale(scalef);
pscalef+=scalef;
histop->Scale(lent/div); histon->Scale(lent/div);
}
pos->Add(histop);neg->Add(histon);
histop->Reset();
histon->Reset();
}
sum->Add(neg);
sum->Add(pos);
delete histop;
delete histon;
}
void KDetector::ShowGaussBeam(Int_t div, Float_t Lambda, Float_t w0, Float_t CellX, Int_t color,Int_t how)
{
TGraph *gr;
TPolyLine3D *gr3D;
Float_t sp[3];
int i,j,Kint,KAint;
KStruct seg;
TLine *line;
Float_t pi,w,X,xr,l,K,KA,PenDepth;
PenDepth=1014;
pi=TMath::Pi();
xr=pi/(Lambda/3.54)*TMath::Power(w0,2);
X=enp[0]-CellX*.5;
w=w0*TMath::Power(1+TMath::Power(X/xr,2),0.5);
K=2*w/(CellX/div);
Kint=int(K);
KAint=Kint;
if(EG!=NULL)
{
if(nz==1) KHisProject(EG,3,how)->Draw("COL");
else
{
TH3F *hh=GetGeom();
hh->SetFillColor(color);
hh->Draw("iso");
}
}
for(i=0;i<div;i++)
for(l=0;l<=KAint;l++)
{
for(j=0;j<3;j++) {
if ((KAint>0) && ((j==0) || (j==2)) ) {sp[j]=((exp[j]-enp[j])/div)*i+enp[j]+(exp[j]-enp[j])/(2*div);}
else if ((KAint>0) && (j==1))
{
KA=K*TMath::Exp(-sp[0]/PenDepth);
KAint=int(KA);
X=sp[0]-CellX*.5;
w=w0*TMath::Power(1+TMath::Power(X/xr,2),0.5);
if (KAint>0) {sp[j]=((exp[j]-enp[j])/div)*i+enp[j]+(exp[j]-enp[j])/(2*div)-w+w/(.5*KAint)*l;}
}
else { KAint=-1; div=-1; }
}
if(Debug) printf("Entry Point: %f %f %f \n",sp[0],sp[1],sp[2]);
Drift(sp[0],sp[1],sp[2],1,&seg);
if(nz==1)
gr=new TGraph(seg.Steps,&seg.Xtrack[1],&seg.Ytrack[1]);
else
gr3D=new TPolyLine3D(seg.Steps,&seg.Xtrack[1],&seg.Ytrack[1],&seg.Ztrack[1]);
if(nz==1)
{
gr->SetLineColor(2);
gr->SetLineStyle(1);
gr->Draw("L");
}
else
{
gr3D->SetLineStyle(1);
gr3D->SetLineColor(2);
gr3D->Draw("SAME");
}
Drift(sp[0],sp[1],sp[2],-1,&seg);
if(nz==1)
gr=new TGraph(seg.Steps,&seg.Xtrack[1],&seg.Ytrack[1]);
else
gr3D=new TPolyLine3D(seg.Steps,&seg.Xtrack[1],&seg.Ytrack[1],&seg.Ztrack[1]);
if(nz==1)
{
gr->SetLineColor(4);
gr->SetLineStyle(3);
gr->Draw("L");
}
else
{
gr3D->SetLineStyle(1);
gr3D->SetLineColor(4);
gr3D->Draw("SAME");
}
}
}