#include #include //#include #include #include #include "distrib.h"// contains the uniform, Poisson, Exponential, Normal distributions realizations double const pi=3.14159265; ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// //Parameters taken from configuration file config.txt double Z_Position; double OrientationAngle; int FiberNumber; double FiberDiameter; double Pitch; double PhotonYield; int FiberBundling; double QuantumEfficiency; double PMT_Gain; int GainDistribution; double GainSpread; int RandomGen; double Delta_Z; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// const int a=6,b=11;//define rows to be read from G4BL file: read rows only from 6 to 11 double outputdata[4096];// output file data array /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// double GetY(double y0,double z, double *pt) { double y; if(*(pt+4)>=0) { y=y0+z**(pt+25); return y; } else { y=y0-z**(pt+25); return y; } } double GetX(double x0, double z, double *pt) { double x; double tanfi=*(pt+32)/*tangent fi*/; if(*(pt+3)>=0) x=x0+z*tanfi; else x=x0-z*tanfi; return x; } /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// void SearchPosition(FILE *fp)//analizes G4BL file and searches data corresponding to concrete detector { //which is determined by Z_Position value int i,k=0,t=1; char str[200],str1[20]; double d; fgets(str,200,fp); //missing first three header non-data strings fgets(str,200,fp); fgets(str,200,fp); while(t) { for(i=0;i=FiberDiameter) { if(x>=0) z=int(floor(fabs(x)))+1; else z=-int((floor(fabs(x))+1)); if(z%2==0) number=z/2; else { if(z>=0) number=(z-1)/2; else number=(z+1)/2; } } if((Pitch>=FiberDiameter/2)&&(Pitch=0) z=int(floor(fabs(x)))+1; else z=-int((floor(fabs(x))+1)); if(z%2==0) number=z; else { if(z>=0) number=(z-1); else number=(z+1); } if(flag==1) number+=1; } return number; } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// double Degrees_to_Rad(double x)//converts degrees to radians { double y=(pi*x)*1.0/180.0; return y; } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// double* Correction(double *pt)//makes corrections before muon passes through detector's second layer { double R=FiberDiameter/2; double x=*pt,y=*(pt+1)/*y coordinate*/; *pt=GetX(x,sqrt(3)*R,pt); *(pt+1)=GetY(y,sqrt(3)*R,pt); return pt; } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// //this function rotates the fibers on the given angle relatively to initial position // and puts new coordinates in data array double* Orientation(double *data) { double x=*data, y=*(data+1),px=*(data+3),py=*(data+4); *data=x*cos(Degrees_to_Rad(OrientationAngle))+y*sin(Degrees_to_Rad(OrientationAngle)); *(data+1)=y*cos(Degrees_to_Rad(OrientationAngle))-x*sin(Degrees_to_Rad(OrientationAngle)); *(data+3)=px*cos(Degrees_to_Rad(OrientationAngle))+py*sin(Degrees_to_Rad(OrientationAngle)); *(data+4)=py*cos(Degrees_to_Rad(OrientationAngle))-px*sin(Degrees_to_Rad(OrientationAngle)); return data; } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //if detectors consists of two layers Bundling() function can form the bundle //to unite some fibers wich will correspond to the same histogram bin int Bundling(int s) { int number=s+FiberNumber/2; number=int(floor(number/FiberBundling)-ceil(0.5*FiberNumber/FiberBundling)); return number; } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //function returns absolute meaning of initial Y-coordinate of a particle //relatively to the fiber this particle is going to pass through double FractionalPart(double x, double R) { double result; int z=floor(fabs(x)); if(z%2==0) result=fabs(x)-z;//here we don't forget that we measure all distances from the center of zero-fiber else result=R-(fabs(x)-z); return result; } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// //function operates with space and momentum coordinates from G4BeamLine output file //counts muon pathlenght in fibers, simulates photon generation //simulates electron production in PMT double* GetData(double *data, int flag) { int ii, histnum/*histogram bin number*/, PhotonNumber,PhotonCounter=0,s; double x,y,z,px,py,pz,yy;//coordinates of muons double costeta, sinteta, tgteta, cosfi,sinfi;//angles shown in documentation double L; //muon pathlength thru fiber double ElectronNumber;//number of electrons produced by produced in PMT double Lenght=100.0;// effective fiber length, mm double dist,sum=0,rand; double const R=FiberDiameter/2;//fiber radius double *ptr=data;//pointer on data array x=data[0]*1000; y=data[1]*1000;/*from meters to millimeters*/ z=data[2];//space coordinates determine muon position px=data[3]; py=data[4]; pz=data[5];// momentum coordinates determine moving directions //all the angles are described in Documentations costeta=pz/sqrt((py*py+pz*pz)); data[23]=costeta; cosfi=pz/sqrt((px*px+pz*pz)); data[24]=cosfi; sinfi=sqrt(1-cosfi*cosfi); data[25]=sinfi; sinteta=sqrt(1-costeta*costeta); data[26]=sinteta; tgteta=sinteta/costeta; data[27]=tgteta; data[32]=sinfi/cosfi; y=GetY(y,Delta_Z,ptr); x=GetX(x,Delta_Z,ptr); s=HistNumber(GetY(y,R,ptr)/R,flag); if(FiberBundling==1)//means no bundling histnum=s; else histnum=Bundling(s); // if((x>=0)&&(px>=0)||((x<0)&&(px<0))) // dist=fabs(Lenght/2)-fabs(y);// distance beetween muon enter point and the ending of fiber wire // if((x>=0)&&(px<0)||((x<0)&&(px>=0))) // dist=fabs(Lenght/2)+fabs(y); if(fabs(y)>R) yy=FractionalPart(y/R,R)*R; if(fabs(y)<=R) yy=fabs(y); L=(2*R/cosfi)*sqrt((1-pow((yy-R*tgteta),2.0)/(R*R*(1+tgteta*tgteta))));//main formula, just geometry :) // if(dist=a)&&(i<=b))//stores necessary data in array { data[i-a]=p1; // printf("%f\n",data[i-a]); } if((i==b)&&(data[2]!=Z_Position)) { break; } i++; if(i==b+1)//operates with data collected at the previous step { flag=0; pt=GetData(Orientation(data),flag);//rotating and simulating if((Pitch>=FiberDiameter/2)&&(Pitch