StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StFgtSlowSimu_response.cxx
1 // *-- Author : J.Balewski
2 //
3 // \date July 2007
4 // $Id: StFgtSlowSimu_response.cxx,v 1.1 2011/04/07 19:31:22 balewski Exp $
5 
6 #include <TRandom3.h>
7 #include <TH2.h>
8 #include <TF1.h>
9 #include <TVector2.h>
10 
11 
12 #include "StFgtSlowSimuMaker.h"
13 #include "HexLatice.h"
14 
15 //--------------------------------------------
16 //--------------------------------------------
17 //--------------------------------------------
18 void
19 StFgtSlowSimuMaker::initFrankModel(TString fname){
20  memset(meLossTab,0,sizeof(meLossTab));
21 
22  LOG_INFO<<"::initFrankModel() load:"<<fname<< endm;
23  FILE *fd=fopen(fname,"r");
24  assert(fd);
25 
26  const int mx=1000;
27  char buf[mx];
28 
29  for (int i = 0; i <eLossDim ; i++) {
30  char * ret=fgets(buf,mx,fd);
31  assert(ret);// too short input file
32  //printf("=%s=",buf);
33  float cl1, cl2, cl3, cl4, cl5, cl6, cl7;
34  int ret1=sscanf(buf,"%f %f %f %f %f %f %f ",&cl1, &cl2, &cl3, &cl4, &cl5, &cl6, &cl7);
35  assert(ret1==7);
36  meLossTab[i] = cl4;
37  }
38  LOG_INFO<<"::initFrankModel() OK"<<endm;
39 
40 }
41 
42 
43 
44 
45 //--------------------------------------------
46 //--------------------------------------------
47 //--------------------------------------------
48 void
49 StFgtSlowSimuMaker::responseFrankModel(TVector3 Rloc, TVector3 Dloc){
50  static const double dPi=4*acos(0.);
51 
52  /* in order to simulate the energy loss for individual ionizing collisions a table from Bichsel is used.
53  This is given in figure 9 in NIM A562, 154 (2006)
54  This table gives the energy loss for a given random number (from 0 to 1 in steps of 10^-4)
55  Two files, low and high beta gamma:
56  file Low: beta gamma .31623 1.00000 3.16228 10.00000 31.62278
57  file High: beta gamma 100.00000 316.22777 1000.00000 3162.27766 10000.00000
58 
59  here use column 2 for High file
60  */
61 
62  // parameters:
63  double par_pairsPerCm = 40.; // # of primary pairs produced per cm of path (Frank: 4 pairs/mm)
64  double zLocEnd=Rloc.z()+Dloc.z(); // for transverse diffusion
65  double pathLength=Dloc.Mag(); // convert from cm to mm
66  TVector3 rv=Dloc; rv=rv.Unit(); // unit vector along the path
67  double rvT=rv.Perp(); // only for QA histos
68 // printf("|v|=%.3f x,y,z=%.3f,%.3f,%.3f, pT=%.3f\n",rv.Mag(), rv.x(),rv.y(),rv.z(),rvT);
69 
70  double totalEnergy_eV = 0;
71  double path = 0; // in mm, traveled so far
72  int nPrimPair = 0; //# primary pairs for this path
73  int nTotPair = 0; //# any pairs for this path
74 
75  double sum1=0,sum2=0; // to calculate average charge position along the tracks
76  while (1) {
77  // make a random step
78  double stepLength = - TMath::Log(mRnd->Uniform()) / par_pairsPerCm;
79  path += stepLength;
80  if (path > pathLength) break;
81  nPrimPair++;
82  // additional weight according to secondary energy distribution, according to Bichsel dist
83  int rndBin = ((int) (10000.0 * mRnd->Uniform()));
84  // Cutoff at 9992 WMZ
85  if(rndBin > par_cutoffOfBichel) rndBin = par_cutoffOfBichel;
86  double eL_eV = meLossTab[rndBin];
87  int nAnyPair = 1 + ((int) ((eL_eV-15.4)/26.)); // # of pairs for this sub-step, includes amplification
88  totalEnergy_eV += eL_eV;
89  if (nAnyPair < 0) continue; // skip electron inf absorbed
90  // add this electron as hit
91  TVector3 r=Rloc+ path*rv; // here we use cm as in the whole GSTAR
92  // printf("Loc %f %f %f Rxy=%f path=%f ns=%d\n", r.x(),r.y(),r.z(),r.Perp(),path,nAnyPair);
93  nTotPair+= nAnyPair;
94 
95  //............... transverse difusion in drift gap
96  if(par_transDiffusionPerPath>0.001) {
97  double zDrift=zLocEnd-r.z();
98 /* WMZ 10/13/09
99  Negative zDrift would happen in some events. The next line is added
100 to avoid it temporarily. Negative zDrift of hits in FGT disks (Z>0)
101 with a negative P_z is probably caused by "back-scattering" tracks.
102 Ignoring the sign of zDrift here does not seem to affect the estimation
103 of PERPENDICULAR diffusion to a hit. But, a better understanding of the
104 "back-scattering" is needed to make a permanent solution for it.
105 */
106  if(zDrift < 0) zDrift *= -1.0;
107 // cout << "Debug: zDrift = " << zDrift << endl;
108  double perpDiffRms=par_transDiffusionPerPath*sqrt(zDrift);
109  double phi=mRnd->Uniform(dPi);
110  double perp=mRnd->Gaus(0,perpDiffRms);
111  TVector3 dR; dR.SetPtThetaPhi(perp,0.,phi);
112  r+=dR; // add diffusion to current hit location
113  // printf("aaa/um %.1f %.1f --> %.1f %.1f %.1f\n", zDrift*1e4, perpDiffRms*1e4, dR.x()*1e4, dR.y()*1e4, dR.z()*1e4);
114  hA[27]->Fill(zDrift*10); // histo is in mm
115  hA[28]->Fill( dR.x()*1e4, dR.y()*1e4);
116  }
117 
118  //...............snap to the nearest hole in hexagonal GEM lattice.......
119  if(hexLat) {
120  TVector2 r2=r.XYvector(); int kU,kV;
121  TVector2 r2s= hexLat->snap(r2,kU,kV);
122  r.SetX(r2s.X()); r.SetY(r2s.Y()); // replace location of this electron
123  }
124 
125  addHit(r,nAnyPair); //position & amplitude of total ionisation caused by this primary pair
126  hA[20]->Fill(eL_eV);
127  sum1+=nAnyPair;
128  sum2+=nAnyPair*path;
129  }
130  hA[21]->Fill(nPrimPair );
131  hA[22]->Fill(totalEnergy_eV/ 1000.);
132  hA[23]->Fill(nTotPair );
133  hA[24]->Fill(path*10 ); // convert to mm
134  double meanPath=sum2/sum1;
135  double meanTpath=meanPath*rvT;
136  // printf("nAnyEle weighted meanL/mm=%.3f , rvT=%4f, meanLT/mm=%3f\n",meanPath*10, rvT,meanTpath*10);
137  hA[25]->Fill(meanPath*10);
138  hA[26]->Fill(meanTpath*10);
139 }
140 
141 
142 
143 //--------------------------------------------
144 //--------------------------------------------
145 //--------------------------------------------
146 void // linear energy loss, no fluctuations
147 StFgtSlowSimuMaker::responseLinearModel(TVector3 r1, TVector3 Dloc){
148  //r1; entrance in Local
149  // double par_dsStep=0.1;
150  //double par_amplStep=3;
151 
152  TVector3 rv=Dloc; rv.Unit(); // unit vector along the path
153  // double ds=Dloc.Mag(); // length of the path
154 
155  // now r1,r2,rv are hit entrance, exit, direction in the local reference frame
156  int ns=1; //(int)(ds/par_dsStep+0.5);
157  double ddS=0; //ds/ns; // this will be the final step for depositing energy
158  double amplS=10; //par_amplStep/par_dsStep*ddS;
159  // printf("ds=%f ns=%d ddS=%f amplS=%.1f\n",ds,ns,ddS,amplS);
160 
161  int is;
162  for(is=0;is<ns;is++) {
163  TVector3 rLoc=r1+ (is+0.5)*ddS*rv;
164  // printf("LAB %f %f %f Rxy=%f \n", rLoc.x(),rLoc.y(),rLoc.z(),rLoc.Perp());
165  addHit(rLoc,amplS);
166  }
167 }
168 
169 
170 //--------------------------------------------
171 //--------------------------------------------
172 //--------------------------------------------
173 void
174 StFgtSlowSimuMaker::addHit(TVector3 rLoc, double ampl) {
175  int par_binStep=6; // in both directions
176 
177  //printf("addH %f %f %f Rxy=%f ampl=%f\n", rLoc.x(),rLoc.y(),rLoc.z(),rLoc.Perp(), ampl);
178  float xH=fabs(rLoc.x()); // hit centroid in local ref frame
179  float yH=fabs(rLoc.y());
180  assert(xH>0);
181  assert(yH>0);
182  //digXY->Fill(xH,yH); // store just one value per hit
183 
184 
185  TAxis *axX=digXY->GetXaxis();
186  int ixH=axX->FindFixBin(xH);
187  int mxX=axX->GetNbins();
188  int ix1=ixH-par_binStep,ix2=ixH+par_binStep;
189  if(ix1<1) ix1=1;
190  if(ix1>mxX) ix1=mxX;
191  // printf("hh2x %f %d %d %d\n",xH,ixH,ix1,ix2);
192  TAxis *axY=digXY->GetYaxis();
193  int iyH=axY->FindFixBin(yH);
194  int mxY=axY->GetNbins();
195  int iy1=iyH-par_binStep,iy2=iyH+par_binStep;
196  if(iy1<1) iy1=1;
197  if(iy1>mxY) iy1=mxY;
198  // printf("hh2y %f %d %d %d\n",yH,iyH,iy1,iy2);
199 
200  float valMax=0;
201  int ix,iy;
202  for(ix=ix1;ix<=ix2;ix++) {
203  float x=axX->GetBinCenter(ix);
204  float val_x=amplF->Eval(x-xH);
205  // printf("hh3 ix=%d x=%f dx=%f, ampl_x=%f\n",ix,x,x-xH,val_x);
206  for(iy=iy1;iy<=iy2;iy++) {
207  float y=axY->GetBinCenter(iy);
208  float val_y=amplF->Eval(y-yH);
209  float val2D=ampl*val_x*val_y;
210  // printf("hh4 iy=%d y=%f dy=%f, ampl_y=%f ampl_xy=%f\n",iy,y,y-yH,val_y,val2D);
211  digXY->Fill(x,y,val2D);
212  digXYAll->Fill(x,y,val2D);
213  if(valMax<val2D) valMax=val2D;
214  }
215  }
216  // printf("hh5 valMax=%f\n",valMax);
217 
218  //- ************************
219  // testing simplified response reco :one entry per pair, ignore # of electrons
220 #if 0
221  int iPhiID, iRadID;// strip coordinates
222  int iQuad=0; // assume that
223  bool ok=geom->localXYtoStripID(iQuad,rLoc.x(),rLoc.y(),iRadID, iPhiID);
224  if (!ok) return;
225  hA[31]->Fill(iRadID);
226  hA[32]->Fill(iPhiID);
227 #endif
228 }
229 
230 
231 
234 
235 // $Log: StFgtSlowSimu_response.cxx,v $
236 // Revision 1.1 2011/04/07 19:31:22 balewski
237 // start
238 //
239 
240 
241 
242 
243