ACTARSim
ACTAR TPC Simulation Reference Guide
digit.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////
2 //*-- AUTHOR : Hector Alvarez-Pol
3 //*-- Date: 06/2006
4 //*-- Last Update: 28/10/15
5 //*-- Copyright: GENP (Univ. Santiago de Compostela)
6 //
7 // --------------------------------------------------------------
8 //
9 // --------------------------------------------------------------
10 // Technical details...
11 // diffusion: gaussian with sigma = sqrt(2Dx/w)
12 // where D is the field dependent diff. coefficient, w the drift
13 // velocity and x the distance
14 // as described in A. Peisert and F. Sauli CERN84-08 (1984)
15 //
16 // --------------------------------------------------------------
17 // How to run this program:
18 // 1 - Run the simulation
19 // actarsim batch1.mac
20 // 2 - Open a root session
21 // root -l
22 // 3 - Run this macro inside root
23 // gSystem->Load("libactar.sl");
24 // .L digitizationMacro.C+;
25 //
26 // thePadsGeometry.SetGeometryValues(Int_t geometryType,
27 // Int_t padType,
28 // Int_t layout,
29 // Double_t xLength,
30 // Double_t yLength,
31 // Double_t zLength,
32 // Double_t xBeamShift,
33 // Double_t yBeamShift,
34 // Double_t radius,
35 // Double_t padSize);
36 // where all distances are in mm
37 //
38 // or use a predefined geometry
39 // thePadsGeometry.SetGeometryValues("ActarTPCDemo")
40 //
41 // theDriftManager.SetDriftVelocity(Double_t velocity); in mm/ns
42 // theDriftManager.SetDiffusionParameters(Double_t long,
43 // Double_t trans); in mm^2/ns
44 // theDriftManager.SetMagneticField(Double_t mag); NOT WORKING YET
45 // theDriftManager.SetLorentzAngle(Double_t lor); in radians
46 //
47 // theAmplificationManager.SetIsWireOn(); for a MAYA-like ACtive TARget
48 // theAmplificationManager.SetWireAmplificationParameters(ra,s,h);
49 //
50 // ra: radius of amplification wire: 5, 10, and 20 mu
51 // s: spacing between two amplification wires: 2 or 2.3 mm
52 // h: distance between the amplification wire and induction pads: 10 mm
53 //
54 // (Optionally you can set theAmplificationManager.SetOldChargeCalculation(); for old Style calculations)
55 // digitEvents(inputFile, outputFile, run#, numberOfEvents);
56 //
57 // the number within brackets means:
58 // the geometryType (0 for a box, 1 for cylinder)
59 // the padType (0 for square, 1 for hexagonal)
60 // the layout, only effective for hexagonal pads, (0, MAYA-type, 1: rotated 90 degrees)
61 // the radius is the radius if the cylinder
62 // the xLength is the half-length of the box along x
63 // the yLength is the half-length of the box along y
64 // the zLength is the half-length of the box along z
65 // the xBeamShift is the distance between beam axis and GasBox center along x
66 // the yBeamShift is the distance between beam axis and GasBox center along y
67 // the padSize is the square or hexagonal pad side
68 // the velocity is the drift velocity in the gas
69 // the long and trans are the longitudinal and transversal diffusion
70 // coefficients in the gas
71 // the mag is the magnetic field inside the gas
72 // the inputFile (output of the simulation)
73 // the outputFile (output of the digitization)
74 // the run numbers (begin in 0)
75 ///////////////////////////////////////////////////////////////////////
76 //
77 // NOTE: it is possible to digitize over the endcaps of a cylinder
78 // using the following method:
79 //
80 // 1) simulate in GEANT the reaction on a cylinder. Use the typical
81 // GEANT4 directions and conventions
82 // 2) run this digitization macro following the previous instructions,
83 // with the following details:
84 // a)use a box in when selecting the geometry with xlength and zlength
85 // equal to the radius, and yLength equal to the tube length
86 // b)call the function
87 // thePadsGeometry.SetEndCapModeOn()
88 // This will change the data of your track... the direction Z will
89 // be converted to Y and Y will be -X. Then, the typical box-like
90 // projection on plane XZ will be equivalent to a projection on the
91 // end cup of the cylinder.
92 //
93 
94 #include <TObject.h>
95 #include <TVector3.h>
98 #include <TTree.h>
99 #include <TF2.h>
100 #include <cmath>
101 #include <fstream>
102 #include <iostream>
103 #include <TMath.h>
104 #include <TClonesArray.h>
105 #include <TString.h>
106 #include <TRandom.h>
107 
108 using namespace std;
109 
110 Int_t DIGI_DEBUG=0; //A global DEBUG variable:
111  //0 absolutly no output (quiet)
112  //1 minimum output when trouble, status or warnings
113  //2 tracking the functions behavior
114  //3 tracking with increased verbosity
115  //4 full verbosity
116 
117 class ActarPadSignal;
119 class padsGeometry;
121 class driftManager;
122 
123 Float_t Polya(Float_t param=3.2){
124  //
125  // Gain distribution according to a Polya function
126  // The first time this function is called, the integral of the Polya function,
127  // [ taken from Bellazzini et al NIMA 581 (2007) 246 ]
128  // is calculated (with N=1).
129  // Returns a random gain according to the gain distribution.
130  //
131  static Short_t firstcall=0;
132  static Float_t integral[1000];
133 
134  Int_t check=0;
135  Int_t i=0;
136 
137  Float_t f,buff[1000];
138  Float_t lambda;
139  Float_t step=0.01;
140  Float_t shift=0.005;
141  Float_t pran=0;
142 
143  if(firstcall==0){
144  for(i=0;i<1000;i++){
145  lambda=i*step+shift; //gain: number of electrons produced for a single incoming electron
146  buff[i]=pow(param,param)/TMath::Gamma(param)*pow(lambda,param-1)*exp(-param*lambda);
147  if(i>0)
148  integral[i]=integral[i-1]+buff[i];
149  else
150  integral[i]=buff[i];
151  }
152  firstcall=1;
153  }
154  while(check==0){
155  f=gRandom->Rndm();
156  if(f>0.0001 && f<0.9999) check=1;
157  }
158 
159  i=0;
160  while(i<1000){
161  if(f<integral[i]/integral[999]){
162  pran=i*step+shift;
163  break;
164  }
165  i++;
166  }
167  return pran;
168 }
169 
170 
171 class ActarPadSignal : public TObject {
172  private:
173  //Basic Pad information
174  Int_t padNumber; //pad control number
175  Int_t padRow; //pad address: row
176  Int_t padColumn; //pad address: column
177 
178  Int_t numberOfStrides; //number of strides on the pad
179 
180  //TIME CONTENT IS GOING TO BE SOON MODIFIED TO REPRODUCE A GET SIGNAL
181  Double_t initTime; //first induction time
182  Double_t finalTime; //last induction time
183  Double_t sigmaTime; //sigma in induction time
184 
185  Double_t chargeDeposited; //charge deposited
186 
187  Int_t eventID;
188  Int_t runID;
189 
190  public:
191  ActarPadSignal();
192  ~ActarPadSignal();
193 
194  void Reset(void);
195 
196  ActarPadSignal& operator=(const ActarPadSignal &right);
197 
198  Int_t GetPadNumber(){return padNumber;}
199  Int_t GetPadRow(){return padRow;}
200  Int_t GetPadColumn(){return padColumn;}
201 
202  Int_t GetNumberOfStrides(){return numberOfStrides;}
203 
204  Double_t GetInitTime(){return initTime;}
205  Double_t GetFinalTime(){return finalTime;}
206  Double_t GetSigmaTime(){return sigmaTime;}
207  Double_t GetChargeDeposited(){return chargeDeposited;}
208 
209  Int_t GetEventID(){return eventID;}
210  Int_t GetRunID(){return runID;}
211 
212  void SetPadNumber(Int_t pad){padNumber=pad;}
213  void SetPadRow(Int_t pad){padRow=pad;}
214  void SetPadColumn(Int_t pad){padColumn=pad;}
215 
216  void SetNumberOfStrides(Int_t num){numberOfStrides=num;}
217 
218  void SetInitTime(Double_t time){initTime=time;}
219  void SetFinalTime(Double_t time){finalTime=time;}
220  void SetSigmaTime(Double_t time){sigmaTime=time;}
221  void SetChargeDeposited(Double_t cha){chargeDeposited = cha;}
222 
223  void SetEventID(Int_t id){eventID=id;}
224  void SetRunID(Int_t id){runID=id;}
225 
226  ClassDef(ActarPadSignal,1);
227 };
228 
230  if(DIGI_DEBUG>3) cout << "Enters ActarPadSignal::ActarPadSignal()" << endl;
231  padNumber=0; padRow=0; padColumn=0;
232  numberOfStrides=0;
233  initTime=0.; finalTime=0.; sigmaTime=0.;
234  chargeDeposited=0.;
235  eventID=0; runID=0;
236  if(DIGI_DEBUG>3) cout << "Exits ActarPadSignal::ActarPadSignal()" << endl;
237 }
238 
240 }
241 
243  // clearing to defaults
244  if(DIGI_DEBUG>3) cout << "Enters ActarPadSignal::Reset()" << endl;
245  padNumber=0; padRow=0; padColumn=0;
246  numberOfStrides=0;
247  initTime=0.; finalTime=0.; sigmaTime=0.;
248  chargeDeposited=0.;
249  eventID=0; runID=0;
250  if(DIGI_DEBUG>3) cout << "Exits ActarPadSignal::Reset()" << endl;
251 }
252 
254  // overloading the copy operator, similar as it in the ActarSimSimpleTrack class
255  if(DIGI_DEBUG>3) cout << "Enters ActarPadSignal::operator=()" << endl;
256  if(this != &right){
257  padNumber = right.padNumber;
258  padRow = right.padRow;
259  padColumn = right.padColumn;
260  numberOfStrides = right.numberOfStrides;
261  initTime = right.initTime;
262  finalTime = right.finalTime;
263  sigmaTime = right.sigmaTime;
264  chargeDeposited = right.chargeDeposited;
265  eventID = right.eventID;
266  runID = right.runID;
267  }
268  if(DIGI_DEBUG>3) cout << "Exits ActarPadSignal::operator=()" << endl;
269  return *this;
270 }
271 
272 
274 
275  private:
276  ActarSimSimpleTrack* track; //the track to be projected
277  TVector3* pre; //projection of the initial point
278  TVector3* post; //projection of the final point
279  Double_t timePre; //drift time of the initial point
280  Double_t timePost; //drift time of the final point
281 
282  Double_t sigmaLongAtPadPlane; //spatial spread at the pad plane
283  Double_t sigmaTransvAtPadPlane; //time spread at the pad plane
284 
285  Int_t position; //0 still not calculated
286  //1 if any point is closer to the (0,0,z) than a delta (rho<delta)
287  //2 else if both points lies within the limits of the beamShielding
288  //3 else if one point is within the limits of the beamShielding
289  //4 else if both point lie in the gas outside the beamShielding
290  //5 if any point lies outside of the gas volume
291  public:
293  virtual ~projectionOnPadPlane();
294 
295  ActarSimSimpleTrack* GetTrack(){return track;}
296  TVector3* GetPre(){return pre;}
297  TVector3* GetPost(){return post;}
298  Double_t GetTimePre(){return timePre;}
299  Double_t GetTimePost(){return timePost;}
300  Double_t GetSigmaLongAtPadPlane(){return sigmaLongAtPadPlane;}
301  Double_t GetSigmaTransvAtPadPlane(){return sigmaTransvAtPadPlane;}
302  Int_t GetPosition(){return position;}
303 
304  void SetTrack(ActarSimSimpleTrack* tr){track = tr;}
305  void SetPre(TVector3* ve){pre = ve;}
306  void SetPost(TVector3* ve){post = ve;}
307  void SetTimePre(Double_t time){timePre = time;}
308  void SetTimePost(Double_t time){timePost = time;}
309  void SetSigmaLongAtPadPlane(Double_t del){sigmaLongAtPadPlane = del;}
310  void SetSigmaTransvAtPadPlane(Double_t del){sigmaTransvAtPadPlane = del;}
311  void SetPosition(Int_t pos){position=pos;}
312 
313  ClassDef(projectionOnPadPlane,1);
314 };
315 
317  if(DIGI_DEBUG>3) cout << "Enters projectionOnPadPlane::projectionOnPadPlane()" << endl;
318  track=0; pre=new TVector3(1,1,1); post=new TVector3(1,1,1);
319  timePre=-1.; timePost=-1.;
320  sigmaLongAtPadPlane=-1.; sigmaTransvAtPadPlane=-1.;
321  position=0;
322  if(DIGI_DEBUG>3) cout << "Exits projectionOnPadPlane::projectionOnPadPlane()" << endl;
323 }
325  if(DIGI_DEBUG>3) cout << "Enters projectionOnPadPlane::~projectionOnPadPlane()" << endl;
326  delete pre;
327  delete post;
328  if(DIGI_DEBUG>3) cout << "Exits projectionOnPadPlane::~projectionOnPadPlane()" << endl;
329 }
330 
331 
333 
334  private:
335  Int_t numberOfColumns; //columns: determined by the Z length
336  Int_t numberOfRows; //rows: determined by the sizes of pads and ACTAR
337  Int_t numberOfPads; //number of pads in the detector
338  //PADS, ROWS & COLUMNS begin in 1
339  //(if numberOfRows=80, then there are rows from 1 to 80).
340  Int_t geoType; //geometry type (0 box, 1 tube)
341  Int_t padType; //pad type (0 square, 1 hexagon)
342  Int_t padLayout; // layout pattern for hexagon pads
343  // (0: MAYA like, 1: rotated MAYA-like)
344  Double_t padSize; //pads size (square side or hexagon side)
345  Double_t rHexagon; //for hexagon only, the apothem
346 
347  Double_t radius; // cylinder: radius
348  Double_t xLength; //all are half-length! dimension for the box case
349  Double_t yLength;
350  Double_t zLength;
351 
352  Double_t xBeamShift; //distance between beam axis and GasBox center along x
353  Double_t yBeamShift; //distance between beam axis and GasBox center along y
354 
355  Double_t sideBlankSpaceX; // length of blank space between the GasBox and the Pad (both side in X direction)
356  Double_t sideBlankSpaceZ; // length of blank space between the GasBox and the Pad (both side in Z direction)
357 
358  Double_t deltaProximityBeam; //to avoid strides to close to the beam
359  Double_t sizeBeamShielding; //radius of the beam shielding cylinder
360 
361  Int_t endCapMode; //set to 1 for projection on the end cups
362 
363  public:
364  padsGeometry();
365  virtual ~padsGeometry();
366 
367  void SetPadsGeometry(void);
368 
369 
370  void SetGeometryValues(Int_t geo, Int_t pad, Int_t layout, Double_t x, Double_t y, Double_t z, Double_t xBeam, Double_t yBeam,
371  Double_t ra, Double_t psi, Double_t gapx, Double_t gapz){
372  if(DIGI_DEBUG>3) cout << "Enters padsGeometry::SetGeometryValues()" << endl;
373  geoType=geo; padType=pad; padLayout=layout;
374  xLength = x; yLength = y; zLength = z;
375  xBeamShift = xBeam; yBeamShift = yBeam;
376  radius=ra; padSize=psi;
377  if(padType == 1)rHexagon = 0.8660254037844386467868626478 * padSize;
378  else rHexagon=0;
379  sideBlankSpaceX = gapx; sideBlankSpaceZ = gapz;
380  SetPadsGeometry();
381  if(DIGI_DEBUG>3) cout << "Exits padsGeometry::SetGeometryValues()" << endl;
382  }
383 
384  void SetGeometryValues(TString DetectorConfig){
385 
386  if(DetectorConfig=="ActarTPCDemo"){
387  geoType=0; padType=0; padLayout=0;
388  radius=0.; padSize=2.;
389  xLength = 37.; yLength = 85.; zLength = 69.;
390  xBeamShift = 0.; yBeamShift = 15.;
391  sideBlankSpaceX=5.; sideBlankSpaceZ=5.;
392  }
393  if(DetectorConfig=="ActarTPC"){
394  geoType=0; padType=0; padLayout=0;
395  radius=0.; padSize=2.;
396  xLength = 133.; yLength = 85.; zLength = 133.;
397  xBeamShift = 0.; yBeamShift = 15.;
398  sideBlankSpaceX=5.; sideBlankSpaceZ=5.;
399  }
400 
401  SetPadsGeometry();
402  if(DIGI_DEBUG>3) cout << "Exits padsGeometry::SetGeometryValues()" << endl;
403  }
404 
405 
406  void SetNumberOfColumns(Int_t col){numberOfColumns=col;}
407  void SetNumberOfRows(Int_t row){numberOfRows=row;}
408  void SetNumberOfPads(Int_t pad){numberOfPads=pad;}
409  void SetGeoType(Int_t type){geoType=type;}
410  void SetPadType(Int_t type){padType=type;}
411  void SetPadLayout(Int_t layout){padLayout=layout;}
412  void SetPadSize(Double_t si){padSize=si;}
413  void SetRHexagon(Double_t si){rHexagon=si;}
414  void SetXLength(Double_t x){xLength=x;}
415  void SetYLength(Double_t y){yLength=y;}
416  void SetZLength(Double_t z){zLength=z;}
417  void SetXBeamShift(Double_t xBeam){xBeamShift=xBeam;}
418  void SetYBeamShift(Double_t yBeam){yBeamShift=yBeam;}
419  void SetSideBlankSpaceX(Double_t gapx){sideBlankSpaceX=gapx;}
420  void SetSideBlankSpaceZ(Double_t gapz){sideBlankSpaceZ=gapz;}
421  void SetRadius(Double_t ra){radius=ra;}
422  void SetDeltaProximityBeam(Double_t de){deltaProximityBeam=de;}
423  void SetSizeBeamShielding(Double_t le){sizeBeamShielding=le;}
424  void SetEndCapModeOn(){endCapMode=1;}
425  void SetEndCapModeOff(){endCapMode=0;}
426 
427  Int_t GetNumberOfColumns(void){return numberOfColumns;}
428  Int_t GetNumberOfRows(void){return numberOfRows;}
429  Int_t GetNumberOfPads(void){return numberOfPads;}
430  Int_t GetGeoType(void){return geoType;}
431  Int_t GetPadType(void){return padType;}
432  Int_t GetPadLayout(void){return padLayout;}
433  Double_t GetPadSize(void){return padSize;}
434  Double_t GetRHexagon(void){return rHexagon;}
435  Double_t GetXLength(void){return xLength;}
436  Double_t GetYLength(void){return yLength;}
437  Double_t GetZLength(void){return zLength;}
438  Double_t GetXBeamShift(void){return xBeamShift;}
439  Double_t GetYBeamShift(void){return yBeamShift;}
440  Double_t GetSideBlankSpaceX(void){return sideBlankSpaceX;}
441  Double_t GetSideBlankSpaceZ(void){return sideBlankSpaceZ;}
442  Double_t GetRadius(void){return radius;}
443  Double_t GetDeltaProximityBeam(void){return deltaProximityBeam;}
444  Double_t GetSizeBeamShielding(void){return sizeBeamShielding;}
445  Int_t GetEndCapMode(void){return endCapMode;}
446 
447  TVector3 CoordinatesCenterOfPad(Int_t pad);
448  Int_t IsInPadNumber(TVector3* point);
449  Int_t GetPadColumnFromXZValue(Double_t x, Double_t z);
450  Int_t GetPadRowFromXZValue(Double_t x, Double_t z);
451 
452  Int_t CalculatePad(Int_t r, Int_t c){
453  //Pad number calculation from row and column (PADS, ROWS & COLUMNS begin in 1)
454  if(DIGI_DEBUG>3) cout << "Enters padsGeometry::CalculatePad()" << endl;
455  if(r<=0 || r>numberOfRows || c<=0 || c>numberOfColumns){
456  if(DIGI_DEBUG>4) {
457  cout << "WARNING: padsGeometry:CalculatePad(" << r << "," << c
458  <<"): row or column number out of range!" << " row=" << r << ", col=" << c << endl;
459  }
460  return 0;
461  }
462  else return ((r-1) * numberOfColumns + (c-1) + 1);
463  }
464 
465  Int_t CalculateColumn(Int_t p){
466  //Column calculation from pad (PADS, ROWS & COLUMNS begin in 1)
467  if(DIGI_DEBUG>3) cout << "Enters padsGeometry::CalculateColumn()" << endl;
468  if(p>numberOfPads || p==0) return 0;
469  if(p%numberOfColumns==0) return numberOfColumns;
470  else return p%numberOfColumns;
471  }
472 
473  Int_t CalculateRow(Int_t p){
474  //Row calculation from pad (PADS, ROWS & COLUMNS begin in 1)
475  if(DIGI_DEBUG>3) cout << "Enters padsGeometry::CalculateRow()" << endl;
476  if(p>numberOfPads || p==0) return 0;
477  else return (Int_t)(((p-1)/numberOfColumns)+1);}
478 
479  ClassDef(padsGeometry,1);
480 };
481 
483  if(DIGI_DEBUG>3) cout << "Enters padsGeometry::padsGeometry()" << endl;
484  numberOfColumns=0; numberOfRows=0; numberOfPads=0;
485  geoType=999; padType=999; padLayout=0;
486  padSize=0.; rHexagon=0.;
487  xLength=0; yLength=0; zLength=0;
488  sideBlankSpaceX=0.; sideBlankSpaceZ=0.;
489  radius=0.;
490  deltaProximityBeam=0.; sizeBeamShielding=0.;
491  endCapMode=0;
492  if(DIGI_DEBUG>3) cout << "Exits padsGeometry::padsGeometry()" << endl;
493 }
494 
496 }
497 
499  // the pads geometry should be calculated using this function
500  // from the sizes and types of ACTAR geometry and pads geometry
501  if(DIGI_DEBUG>3) cout << "Enters padsGeometry::SetPadsGeometry()" << endl;
502  if(DIGI_DEBUG)
503  cout << "________________________________________________________" << endl
504  << "In padsGeometry::SetPadsGeometry() " << endl
505  << "Note that the calculation of the pads geometry could "<< endl
506  << "modify slightly the size of the pad you have introduced." << endl;
507  if(geoType == 0 && padType == 0){ //box and square pad
508  numberOfRows = (Int_t) (2*(xLength-sideBlankSpaceX)/padSize);
509  if(DIGI_DEBUG)
510  cout << "User selected a box with square pads" << endl
511  << "User selected a padSize = " << padSize;
512  padSize = (2*(xLength-sideBlankSpaceX)) / numberOfRows;
513  if(DIGI_DEBUG)
514  cout << " after the calculation: padSize = " << padSize <<endl;
515  numberOfColumns = ((Int_t) (2*(zLength-sideBlankSpaceZ) / padSize)) - 1;
516  if((numberOfColumns+1)*padSize <= 2*(zLength-sideBlankSpaceZ)) numberOfColumns++;
517  numberOfPads = numberOfRows*numberOfColumns;
518  if(DIGI_DEBUG)
519  cout << "________________________________________________________" << endl
520  << " Output of padsGeometry::SetPadsGeometry() " << endl
521  << " numberOfRows = "<< numberOfRows
522  << ", numberOfColumns = " << numberOfColumns << endl
523  << "________________________________________________________"<< endl;
524  }
525  else if(geoType == 0 && padType == 1 && padLayout==0){ //box and hexagonal pad with MAYA-type layout
526  numberOfColumns = (Int_t) (zLength/rHexagon);
527  if(DIGI_DEBUG)
528  cout << "User selected a box with hexagonal pads (MAYA-type)" << endl
529  << "User selected a padSize = " << padSize
530  << " and therefore a rHexagon = " << rHexagon<< endl;
531  rHexagon = zLength / numberOfColumns;
532  padSize = 1.154700538379251529013 * rHexagon;
533  if(DIGI_DEBUG)
534  cout << " after the calculation: padSize = " << padSize
535  << " and therefore a rHexagon = " << rHexagon << endl;
536  numberOfRows = (Int_t) ((2.*xLength-2.*padSize)/(1.5*padSize))+1;
537  sideBlankSpaceX = (2.*xLength-(numberOfRows-1)*1.5*padSize-2.*padSize )/2.;
538  numberOfPads = numberOfRows*numberOfColumns;
539  if(DIGI_DEBUG)
540  cout << "________________________________________________________" << endl
541  << " Output of padsGeometry::SetPadsGeometry() " << endl
542  << " numberOfRows = "<< numberOfRows
543  << ", numberOfColumns = " << numberOfColumns << endl
544  << "________________________________________________________"<< endl;
545  }
546  else if(geoType == 0 && padType == 1 && padLayout==1){ //box and hexagonal pad
547  numberOfRows = (Int_t) (xLength/rHexagon);
548  if(DIGI_DEBUG)
549  cout << "User selected a box with hexagonal pads (rotated wrt MAYA-type)" << endl
550  << "User selected a padSize = " << padSize
551  << " and therefore a rHexagon = " << rHexagon<< endl;
552  rHexagon = xLength / numberOfRows;
553  padSize = 1.154700538379251529013 * rHexagon;
554  if(DIGI_DEBUG)
555  cout << " after the calculation: padSize = " << padSize
556  << " and therefore a rHexagon = " << rHexagon << endl;
557  numberOfColumns = (Int_t) ((2.*zLength-2.*padSize)/(1.5*padSize)) + 1;
558  sideBlankSpaceZ = (2.*zLength -(numberOfColumns-1)*1.5*padSize-2.*padSize)/2.;
559  numberOfPads = numberOfRows*numberOfColumns;
560  if(DIGI_DEBUG)
561  cout << "________________________________________________________" << endl
562  << " Output of padsGeometry::SetPadsGeometry() " << endl
563  << " numberOfRows = "<< numberOfRows
564  << ", numberOfColumns = " << numberOfColumns << endl
565  << "________________________________________________________"<< endl;
566  }
567  else if(geoType == 1 && padType == 0){ //cylinder and square pad
568  numberOfRows = (Int_t) (2*TMath::Pi()*radius / padSize);
569  if(DIGI_DEBUG)
570  cout << "User selected a cylinder with square pads (on the cylindrical walls)" << endl
571  << "User selected a padSize = " << padSize;
572  padSize = 2*TMath::Pi()*radius / numberOfRows;
573  if(DIGI_DEBUG)
574  cout << " after the calculation: padSize = " << padSize <<endl;
575  numberOfColumns = ((Int_t) (2*zLength / padSize)) - 1;
576  if( (numberOfColumns+1)*padSize <= 2*zLength ) numberOfColumns++;
577  numberOfPads = numberOfRows*numberOfColumns;
578  if(DIGI_DEBUG)
579  cout << "________________________________________________________" << endl
580  << " Output of padsGeometry::SetPadsGeometry() " << endl
581  << " numberOfRows = "<< numberOfRows
582  << ", numberOfColumns = " << numberOfColumns << endl
583  << "________________________________________________________"<< endl;
584  }
585  else if(geoType == 1 && padType == 1){ //cylinder and hexagonal pad
586  numberOfRows = (Int_t) (TMath::Pi()*radius / rHexagon);
587  if(DIGI_DEBUG)
588  cout << "User selected a cylinder with hexagonal pads" << endl
589  << "User selected a padSize = " << padSize
590  << " and therefore a rHexagon = " << rHexagon<< endl;
591  rHexagon = TMath::Pi()*radius / numberOfRows;
592  padSize = 1.154700538379251529013 * rHexagon;
593  if(DIGI_DEBUG)
594  cout << " after the calculation: padSize = " << padSize
595  << " and therefore a rHexagon = " << rHexagon << endl;
596  numberOfColumns = ((Int_t) (2*zLength / (1.5*padSize))) - 1;
597  if( (numberOfColumns+1)*1.5*padSize <= 2*zLength ) numberOfColumns++;
598  numberOfPads = numberOfRows*numberOfColumns;
599  if(DIGI_DEBUG)
600  cout << "________________________________________________________" << endl
601  << " Output of padsGeometry::SetPadsGeometry() " << endl
602  << " numberOfRows = "<< numberOfRows
603  << ", numberOfColumns = " << numberOfColumns << endl
604  << "________________________________________________________"<< endl;
605  }
606  else {
607  if(DIGI_DEBUG)
608  cout << "ERROR: No valid geometry... Have you called "
609  << "SetGeometryValues() with valid arguments?" << endl << endl;
610  }
611  if(DIGI_DEBUG>3) cout << "Exits padsGeometry::SetPadsGeometry()" << endl;
612 }
613 
614 Int_t padsGeometry::IsInPadNumber(TVector3* point){
615  //calculates the pad number where the point is
616  if(DIGI_DEBUG>3) cout << "Enters padsGeometry::IsInPadNumber()" << endl;
617  Int_t column; Int_t row;
618  if(geoType == 0 && padType == 0) { //box and square pad
619  row = (Int_t) (((point->X() - sideBlankSpaceX + xLength)/ padSize) + 1);
620  //column = (Int_t) (((point->Z() - sideBlankSpaceZ)/ padSize)+1);
621  column = (Int_t) (((point->Z() - sideBlankSpaceZ + zLength)/ padSize)+1);//Piotr : Now that origin is at the middle of the GasBox
622  if(column > 0 && column < numberOfColumns+1
623  && row > 0 && row < numberOfRows+1) {
624  if(DIGI_DEBUG>2)
625  cout << "In padsGeometry::IsInPadNumber()" << endl
626  << " Pad (" << row << "," << column << ") for point "
627  << point->X() << ","<< point->Y() << ","<< point->Z()<< endl;
628  return CalculatePad(row,column);
629  }
630  else{
631  if(DIGI_DEBUG)
632  cout << "ERROR: in padsGeometry::IsInPadNumber()" << endl
633  << " Invalid pad returned from requested point "
634  << " sideBlankSpaceZ "<<sideBlankSpaceZ <<" Pad (" << row << "," << column << ") for point "
635  << point->X() << ","<< point->Y() << ","<< point->Z()<< endl;
636  return 0;
637  }
638  }
639  else if(geoType == 0 && padType == 1 && padLayout == 0){ //box and hexagonal pad and MAYA-type layout
640  //if(point->X()< -xLength || point->X()>xLength || point->Z()< 0 || point->Z()>2*zLength) {
641  if(point->X()< -xLength || point->X()>xLength || point->Z()< -zLength || point->Z()>zLength) {//Piotr : Now that origin is at the middle of the GasBox
642  if(DIGI_DEBUG)
643  cout << "ERROR: in padsGeometry::IsInPadNumber()" << endl
644  << " Invalid pad returned from requested point "
645  << point->X() << ","<< point->Y() << ","<< point->Z()<< endl;
646  return 0;
647  }
648  row = (Int_t) ((point->X() + xLength - sideBlankSpaceX)/(1.5*padSize))+1;
649  column = (Int_t) (point->Z()/ (2*rHexagon)) + 1;
650  Double_t shorterDist = padSize; Int_t candidate=0; point->SetY(-yLength);
651  for(Int_t i=0;i<2;i++){ //checking if it is on the next column
652  for(Int_t j=-1;j<1;j++){ //checking if it is on the previous row
653  if((column+i)>numberOfColumns || (row+j)<1 || (row+j)>numberOfRows) continue;
654  TVector3 distance = *point - CoordinatesCenterOfPad(CalculatePad(row+j,column+i));
655  if (distance.Mag() <= rHexagon){
656  return CalculatePad(row+j,column+i);
657  }
658  if(distance.Mag() <= shorterDist) {
659  shorterDist = distance.Mag();
660  candidate = CalculatePad(row+j,column+i);
661  }
662  }
663  }
664  if(DIGI_DEBUG>2)
665  cout << "In padsGeometry::IsInPadNumber()" << endl
666  << " Pad (" << row << "," << column << ") for point "
667  << point->X() << ","<< point->Y() << ","<< point->Z()<< endl;
668  return candidate;
669  }
670  else if(geoType == 0 && padType == 1 && padLayout == 1){ //box and hexagonal pad
671  //if(point->X()< -xLength || point->X()>xLength || point->Z()< 0 || point->Z()>2*zLength) {
672  if(point->X()< -xLength || point->X()>xLength || point->Z()< -zLength || point->Z()>zLength) {//Piotr : Now that origin is at the middle of the GasBox
673  if(DIGI_DEBUG)
674  cout << "ERROR: in padsGeometry::IsInPadNumber()" << endl
675  << " Invalid pad returned from requested point "
676  << point->X() << ","<< point->Y() << ","<< point->Z()<< endl;
677  return 0;
678  }
679  row = (Int_t) (((point->X() + xLength)/ (2*rHexagon)) + 1);
680  //column = (Int_t) (((point->Z()-sideBlankSpaceZ)/(1.5*padSize))+1);
681  column = (Int_t) (((point->Z() - sideBlankSpaceZ + xLength)/(1.5*padSize))+1);//Piotr : Now that origin is at the middle of the GasBox
682  Double_t shorterDist = padSize; Int_t candidate=0; point->SetY(-yLength);
683  for(Int_t i=0;i<2;i++){ //checking if it is on the next row
684  for(Int_t j=-1;j<1;j++){ //checking if it is on the previous column
685  if(row+i>numberOfRows || column+j<1 || column+j>numberOfColumns) continue;
686  TVector3 distance = *point - CoordinatesCenterOfPad(CalculatePad(row+i,column+j));
687  if (distance.Mag() <= rHexagon) return CalculatePad(row+i,column+j);
688  if( distance.Mag() <= shorterDist ) {
689  shorterDist = distance.Mag();
690  candidate = CalculatePad(row+i,column+j);
691  }
692  }
693  }
694  if(DIGI_DEBUG>2)
695  cout << "In padsGeometry::IsInPadNumber()" << endl
696  << " Pad (" << row << "," << column << ") for point "
697  << point->X() << ","<< point->Y() << ","<< point->Z()<< endl;
698  return candidate;
699  }
700  else if(geoType == 1 && padType == 0){ //cylinder and square pad
701  if(point->Phi()>=0) row =(Int_t)(numberOfRows * (point->Phi()) / (2*TMath::Pi())) +1;
702  else row =(Int_t)(numberOfRows * ( point->Phi() + (2*TMath::Pi())) / (2*TMath::Pi())) +1;
703  column = (Int_t) ((point->Z() / padSize)+1);
704  if(column > 0 && column < numberOfColumns+1 &&
705  row > 0 && row < numberOfRows+1) {
706  if(DIGI_DEBUG>2)
707  cout << "In padsGeometry::IsInPadNumber()" << endl
708  << " Pad (" << row << "," << column << ") for point "
709  << point->X() << ","<< point->Y() << ","<< point->Z()<< endl;
710  return CalculatePad(row,column);
711  }
712  else{
713  if(DIGI_DEBUG)
714  cout << "ERROR: in padsGeometry::IsInPadNumber()" << endl
715  << " Invalid pad returned from requested point "
716  << point->X() << ","<< point->Y() << ","<< point->Z()<< endl;
717  return 0;
718  }
719  }
720  else if(geoType == 1 && padType == 1){ //cylinder and hexagonal pad
721  if(point->Z()<0 || point->Z()>2*zLength) {
722  if(DIGI_DEBUG)
723  cout << "ERROR: in padsGeometry::IsInPadNumber()" << endl
724  << " Invalid pad returned from requested point "
725  << point->X() << ","<< point->Y() << ","<< point->Z()<< endl;
726  return 0;
727  }
728  if(point->Phi()>=0) row= (Int_t)(numberOfRows * (point->Phi()) / (2*TMath::Pi())) + 1;
729  else row= (Int_t)(numberOfRows * (point->Phi()+(2*TMath::Pi())) / (2*TMath::Pi())) + 1;
730  column = (Int_t)((point->Z()/(1.5*padSize))+1);
731  Double_t shorterDist = padSize; Int_t candidate=0; point->SetPerp(radius);
732  for(Int_t i=0;i<2;i++){ //checking if it is on the next row
733  for(Int_t j=-1;j<1;j++){ //checking if it is on the previous column
734  if(row+i>numberOfRows || column+j<1 || column+j>numberOfColumns) continue;
735  TVector3 distance = *point - CoordinatesCenterOfPad(CalculatePad(row+i,column+j));
736  if( distance.Mag() <= shorterDist ) {
737  shorterDist = distance.Mag();
738  candidate = CalculatePad(row+i,column+j);
739  }
740  }
741  }
742  if(DIGI_DEBUG>2)
743  cout << "In padsGeometry::IsInPadNumber()" << endl
744  << " Pad (" << row << "," << column << ") for point "
745  << point->X() << ","<< point->Y() << ","<< point->Z()<< endl;
746  return candidate;
747  }
748  else {
749  if(DIGI_DEBUG)
750  cout << "No valid geometry... Have you called "
751  <<"SetGeometryValues() with valid arguments?" <<endl<<endl;
752  return 0;
753  }
754 }
755 
756 Int_t padsGeometry::GetPadColumnFromXZValue(Double_t x, Double_t z){
757  //calculates the pad column number by x, z-values of a point
758  // NOTE: column number here start from 1
759  // column number returned here is allowed to be out of the range of the chamber
760  //if(DIGI_DEBUG>3) cout << "Enters padsGeometry::GetPadColumnFromXZValue()" << endl;
761  TVector3 point(x, -yBeamShift-yLength, z);
762  TVector3 vec;
763  Int_t column=0, row=0;
764  if(geoType == 0 && padType == 0){ //box and square pad
765  //column = (Int_t) (((z - sideBlankSpaceZ) / padSize)+1);
766  column = (Int_t) numberOfColumns/2.+ ((z / padSize)+1);//Piotr : Now that origin is at the middle of the GasBox
767  return column;
768  }
769  else if(geoType == 0 && padType == 1 && padLayout == 0){ //box and hexagonal pad with MAYA-type layout
770  column = (Int_t) ((point.Z()/(2*rHexagon))+1);
771  return column;
772  }
773  else if(geoType == 0 && padType == 1 && padLayout == 1){ //box and hexagonal pad
774  row = (Int_t) (((point.X() + xLength)/ (2*rHexagon)) + 1);
775  column = (Int_t) (((point.Z()-sideBlankSpaceZ)/(1.5*padSize))+1);
776  Double_t shorterDist = padSize; Int_t candidate=0; point.SetY(-yBeamShift-yLength);
777  for(Int_t i=0;i<2;i++){ //checking if it is on the next row
778  for(Int_t j=-1;j<1;j++){ //checking if it is on the previous column
779  vec.SetXYZ(-xLength + ((2*(row+i))-1)*rHexagon,
780  -yBeamShift-yLength,
781  padSize*((column+j)*1.5-0.5)+sideBlankSpaceZ);
782  if((column+j)%2==0) vec.SetX(vec.X()-rHexagon);
783  TVector3 distance = point - vec;
784  if (distance.Mag() <= rHexagon) return column+j;
785  if( distance.Mag() <= shorterDist ) {
786  shorterDist = distance.Mag();
787  candidate = column+j;
788  }
789  }
790  }
791  if(DIGI_DEBUG>2)
792  cout << "In padsGeometry::IsInPadNumber()" << endl
793  << " Pad (" << row << "," << column << ") for point "
794  << point.X() << ","<< point.Y() << ","<< point.Z()<< endl;
795  return candidate;
796  }
797  else {
798  cout << "No valid geometry... Have you called "
799  <<"SetGeometryValues() with valid arguments?" <<endl<<endl;
800  return 0;
801  }
802 }
803 
804 Int_t padsGeometry::GetPadRowFromXZValue(Double_t x, Double_t z){
805  //calculates the pad column number by x, z-values of a point
806  // NOTE: column number here start from 1
807  // column number returned here is allowed to be out of the range of the chamber
808  //if(DIGI_DEBUG>3) cout << "Enters padsGeometry::GetPadRowFromXZValue()" << endl;
809  TVector3 point(x, -yBeamShift-yLength, z);
810  TVector3 vec;
811 
812  Int_t column=0, row=0;
813  if(geoType == 0 && padType == 0){ //box and square pad
814  row = (Int_t) numberOfRows/2.+ ((x / padSize)+1);
815  return row;
816  }
817  else {
818  cout << "No valid geometry... Have you called"
819  <<"SetGeometryValues() with valid arguments?" <<endl<<endl;
820  return 0;
821  }
822 }
823 
825  if(DIGI_DEBUG>3) cout << "Enters padsGeometry::CoordinatesCenterOfPad()" << endl;
826  if(pad==0 || pad> numberOfPads) {
827  if(DIGI_DEBUG)
828  cout << "ERROR in padsGeometry::CoordinatesCenterOfPad() " << endl
829  << " Invalid pad number " << pad
830  << " (0 or larger than maximum pad number)" << endl;
831  TVector3 vec(0,0,0); //HAPOL IS THIS RIGHT? SHOULD IT BE FAR AWAY?
832  return vec;
833  }
834  Int_t row = CalculateRow(pad);
835  Int_t column = CalculateColumn(pad);
836  if(geoType == 0 && padType == 0){ //box and square pad
837  //TVector3 vec(-xLength + (row-0.5)*padSize, -yLength,(column-0.5)*padSize);
838  TVector3 vec(-xLength + (row-0.5)*padSize, -yBeamShift-yLength,-zLength + (column-0.5)*padSize);//Piotr : Now that origin is at the middle of the GasBox
839  if(DIGI_DEBUG>2)
840  cout << "________________________________________________________" << endl
841  << " Output of padsGeometry::CoordinatesCenterOfPad(" << pad << ") " << endl
842  << " row = "<< row << ", column = " << column << endl
843  << " x = "<< vec.x() << ", y = " << vec.y() << ", z = " << vec.z() << endl
844  << "________________________________________________________"<< endl;
845  return vec;
846  }
847  else if(geoType == 0 && padType == 1 && padLayout == 0){ //box and hexagonal pad with MAYA-type layout
848  TVector3 vec(-xLength + sideBlankSpaceX + padSize*((row*1.5)-0.5),
849  -yBeamShift-yLength,
850  (2*column-1)*rHexagon);
851  if(row%2==0) vec.SetZ(vec.Z()-rHexagon);
852  if(DIGI_DEBUG>2)
853  cout << "________________________________________________________" << endl
854  << " Output of padsGeometry::CoordinatesCenterOfPad(" << pad << ") " << endl
855  << " row = "<< row << ", column = " << column << endl
856  << " x = "<< vec.x() << ", y = " << vec.y() << ", z = " << vec.z() << endl
857  << "________________________________________________________"<< endl;
858  return vec;
859  }
860  else if(geoType == 0 && padType == 1 && padLayout == 1){ //box and hexagonal pad
861  TVector3 vec(-xLength + ((2*row)-1)*rHexagon,
862  -yBeamShift-yLength,
863  padSize*((column*1.5)-0.5)+sideBlankSpaceZ);
864  if(column%2==0) vec.SetX(vec.X()-rHexagon);
865  if(DIGI_DEBUG>2)
866  cout << "________________________________________________________" << endl
867  << " Output of padsGeometry::CoordinatesCenterOfPad(" << pad << ") " << endl
868  << " row = "<< row << ", column = " << column << endl
869  << " x = "<< vec.x() << ", y = " << vec.y() << ", z = " << vec.z() << endl
870  << "________________________________________________________"<< endl;
871  return vec;
872  }
873  else if(geoType == 1 && padType == 0){ //cylinder and square pad
874  TVector3 vec(radius, radius, (column-0.5)*padSize);
875  vec.SetPerp(radius);
876  vec.SetPhi( (row-0.5) * 2 * TMath::Pi() / numberOfRows );
877  if(DIGI_DEBUG>2)
878  cout << "________________________________________________________" << endl
879  << " Output of padsGeometry::CoordinatesCenterOfPad(" << pad << ") " << endl
880  << " row = "<< row << ", column = " << column << endl
881  << " x = "<< vec.x() << ", y = " << vec.y() << ", z = " << vec.z() << endl
882  << "________________________________________________________"<< endl;
883  return vec;
884  }
885  else if(geoType == 1 && padType == 1){ //cylinder and hexagonal pad
886  TVector3 vec(radius, radius, padSize*((column*1.5)-0.5));
887  vec.SetPerp(radius);
888  if(column%2==1) vec.SetPhi( (row-0.5) * 2 * TMath::Pi() / numberOfRows ) ;
889  else vec.SetPhi( (row-1) * 2 * TMath::Pi() / numberOfRows);
890  if(DIGI_DEBUG>2)
891  cout << "________________________________________________________" << endl
892  << " Output of padsGeometry::CoordinatesCenterOfPad(" << pad << ") " << endl
893  << " row = "<< row << ", column = " << column << endl
894  << " x = "<< vec.x() << ", y = " << vec.y() << ", z = " << vec.z() << endl
895  << "________________________________________________________"<< endl;
896  return vec;
897  }
898  else {
899  if(DIGI_DEBUG)
900  cout << "No valid geometry... Have you called "
901  <<"SetGeometryValues() with valid arguments?" <<endl<<endl;
902  TVector3 vec3(1.,1.,1.); //HAPOL IS THIS RIGHT? SHOULD IT BE FAR AWAY?
903  return vec3;
904  }
905 }
906 
907 
909 
910  private:
911  Int_t isWire;
912  Double_t radiusOfAmpliWire; // radius of amplification wire (ra in Mathieson)
913  Double_t pitchOfAmpliWire; // distance between two neighbouring amplification wires, (s in Mathieson)
914  Double_t ACseparation; // anode (Wire) and cathode (pads) separation, (h in Mathieson)
915  Double_t K1P, K2P, K3P; // K1, K2, and K3 in Mathieson, NIMA270(1988)602 for X directions
916  Double_t K1N, K2N, K3N; // K1, K2, and K3 for Y direction
917  Double_t lambdaP, lambdaN; // lambda in Mathieson, NIMA270(1988)602,
918  // for x (parallel to the wire) and
919  // y (perpendicular to the wire), respectively
920  Double_t rhoP, rhoN; // relative induction charge, rho in Mathieson, for X and Y
921 
922  public:
924  virtual ~amplificationManager();
925 
926  void SetIsWireOn(){
927  isWire=1;
928  }
929 
930  void SetIsWireOff(){
931  isWire=0;
932  }
933 
934  Int_t GetIsWire(){
935  return isWire;
936  }
937 
938  void SetWireAmplificationParameters(Double_t ra, Double_t s, Double_t h);
939 
940  void SetRadiusOfAmpliWire(Double_t ra) {radiusOfAmpliWire = ra;}
941  void SetPitchOfAmpliWire(Double_t s) {pitchOfAmpliWire = s;}
942  void SetACseparation(Double_t h) {ACseparation = h;}
943  void SetMathiesonFactorK1P(Double_t k1p) {K1P = k1p;}
944  void SetMathiesonFactorK2P(Double_t k2p) {K2P = k2p;}
945  void SetMathiesonFactorK3P(Double_t k3p) {K3P = k3p;}
946  void SetMathiesonFactorK1N(Double_t k1n) {K1N = k1n;}
947  void SetMathiesonFactorK2N(Double_t k2n) {K2N = k2n;}
948  void SetMathiesonFactorK3N(Double_t k3n) {K3N = k3n;}
949 
950  Double_t GetRadiusOfAmpliWire() {return radiusOfAmpliWire;}
951  Double_t GetPitchOfAmpliWire() {return pitchOfAmpliWire;}
952  Double_t GetACseparation() {return ACseparation;}
953  Double_t GetMathiesonFactorK1P() {return K1P;}
954  Double_t GetMathiesonFactorK2P() {return K2P;}
955  Double_t GetMathiesonFactorK3P() {return K3P;}
956  Double_t GetMathiesonFactorK1N() {return K1N;}
957  Double_t GetMathiesonFactorK2N() {return K2N;}
958  Double_t GetMathiesonFactorK3N() {return K3N;}
959 
960  Double_t CalculateRhoP(Double_t x){
961  //calculation of the relative induction charge for X (see Mathieson paper)
962  if(DIGI_DEBUG>3) cout << "Enters amplificationManager::CalculateRhoP()" << endl;
963  lambdaP= x/ACseparation;
964  Double_t commonFactor=tanh(K2P*lambdaP)*tanh(K2P*lambdaP);
965  rhoP=K1P*(1.-commonFactor)/(1.+K3P*commonFactor);
966  return rhoP;
967  }
968 
969  Double_t CalculateRhoN(Double_t y){
970  //calculation of the relative induction charge for Y (see Mathieson paper)
971  if(DIGI_DEBUG>3) cout << "Enters amplificationManager::CalculateRhoN()" << endl;
972  lambdaN= y/ACseparation;
973  Double_t commonFactor=tanh(K2N*lambdaN)*tanh(K2N*lambdaN);
974  rhoN=K1N*(1.-commonFactor)/(1.+K3N*commonFactor);
975  return rhoN;
976  }
977  ClassDef(amplificationManager,1);
978 };
979 
981  if(DIGI_DEBUG>3) cout << "Enters amplificationManager::amplificationManager()" << endl;
982  isWire=0;
983  radiusOfAmpliWire=0.02; // 20 mu
984  pitchOfAmpliWire=2.0; // 2 mm
985  ACseparation=10.0; // 10 mm
986  K1P=1.; K2P=1.; K3P=1.; // K1, K2, and K3 in Mathieson, NIMA270(1988)602 for X directions
987  K1N=1.; K2N=1.; K3N=1.; // K1, K2, and K3 for Y direction
988  lambdaP=1.; lambdaN=1.; // lambda in Mathieson, NIMA270(1988)602,
989  // for x (parallel to the wire) and
990  // y (perpendicular to the wire), respectively
991  rhoP=0.; rhoN=0.; // relative induction charge, rho in Mathieson, for X and Y
992  if(DIGI_DEBUG>3) cout << "Exits amplificationManager::amplificationManager()" << endl;
993 }
995 }
996 
997 void amplificationManager::SetWireAmplificationParameters(Double_t ra, Double_t s, Double_t h){
998  // radiusOfAmpliWire = ra;
999  // pitchOfAmpliWire = s;
1000  // ACseparation = h;
1001  if(DIGI_DEBUG>3) cout << "Enters amplificationManager::SetWireAmplificationParameters()" << endl;
1002  Double_t k1p=0.0, k2p=0.0, k3p=0.0, k1n=0.0, k2n=0.0, k3n=0.0;
1003 
1004  Double_t ras=ra/s;
1005  Double_t ras1=1.5e-3, ras2=2.5e-3, ras3=3.75e-3, ras4=5.25e-3, ras5=7.5e-3;
1006 
1007  Double_t ras01=ras -ras1, ras02=ras -ras2, ras03=ras -ras3, ras04=ras -ras4, ras05=ras -ras5;
1008  Double_t ras12=ras1-ras2, ras13=ras1-ras3, ras14=ras1-ras4, ras15=ras1-ras5;
1009  Double_t ras21=ras2-ras1, ras23=ras2-ras3, ras24=ras2-ras4, ras25=ras2-ras5;
1010  Double_t ras31=ras3-ras1, ras32=ras3-ras2, ras34=ras3-ras4, ras35=ras3-ras5;
1011  Double_t ras41=ras4-ras1, ras42=ras4-ras2, ras43=ras4-ras3, ras45=ras4-ras5;
1012  Double_t ras51=ras5-ras1, ras52=ras5-ras2, ras53=ras5-ras3, ras54=ras5-ras4;
1013 
1014  Double_t hs = h/s;
1015 
1016  if(hs <= 1.40){ // K3 factor for direction parallel to wire or normal to wire are different
1017  // calculate K3P
1018  Double_t a14 = -0.26171, a13 = 1.0914, a12 = -1.61916, a11 = 0.765601, a10 = 0.602428;
1019  Double_t a24 = -0.287172,a23 = 1.20289,a22 = -1.79557, a21 = 0.876833, a20 = 0.547614;
1020  Double_t a34 = -0.356592,a33 = 1.45366,a32 = -2.1068, a31 = 1.02757, a30 =0.492266;
1021  Double_t a44 = -0.398035,a43 = 1.62109,a42 = -2.34602, a41 = 1.17147, a40 =0.433379;
1022  Double_t a54 = -0.449798,a53 = 1.83572,a52 = -2.66741, a51 = 1.37198, a50 =0.355622;
1023 
1024  Double_t K3P1=a14*pow(hs,4.)+a13*pow(hs,3.)+a12*hs*hs+a11*hs+a10;
1025  Double_t K3P2=a24*pow(hs,4.)+a23*pow(hs,3.)+a22*hs*hs+a21*hs+a20;
1026  Double_t K3P3=a34*pow(hs,4.)+a33*pow(hs,3.)+a32*hs*hs+a31*hs+a30;
1027  Double_t K3P4=a44*pow(hs,4.)+a43*pow(hs,3.)+a42*hs*hs+a41*hs+a40;
1028  Double_t K3P5=a54*pow(hs,4.)+a53*pow(hs,3.)+a52*hs*hs+a51*hs+a50;
1029 
1030  k3p=K3P1*(ras02*ras03*ras04*ras05)/(ras12*ras13*ras14*ras15)+
1031  K3P2*(ras01*ras03*ras04*ras05)/(ras21*ras23*ras24*ras25)+
1032  K3P3*(ras01*ras02*ras04*ras05)/(ras31*ras32*ras34*ras35)+
1033  K3P4*(ras01*ras02*ras03*ras05)/(ras41*ras42*ras43*ras45)+
1034  K3P5*(ras01*ras02*ras03*ras04)/(ras51*ras52*ras53*ras54);
1035 
1036  // calculate K3N
1037  a14 =-0.56927 ;a13 =2.15238; a12 =-2.68646; a11 =0.815535; a10 =0.929974;
1038  a24 =-0.601139;a23 =2.2645; a22 =-2.80946; a21 =0.828462; a20 =0.932558;
1039  a34 =-0.615971;a33 =2.34445; a32 =-2.92218; a31 =0.844926; a30 =0.935198;
1040  a44 =-0.79293 ;a43 =2.94533; a42 =-3.58834; a41 = 1.08576; a40 =0.908493;
1041  a54 =-0.841875;a53 =3.10651; a52 =-3.74454; a51 =1.09552; a50 =0.914561;
1042 
1043  Double_t K3N1=a14*pow(hs,4.)+a13*pow(hs,3.)+a12*hs*hs+a11*hs+a10;
1044  Double_t K3N2=a24*pow(hs,4.)+a23*pow(hs,3.)+a22*hs*hs+a21*hs+a20;
1045  Double_t K3N3=a34*pow(hs,4.)+a33*pow(hs,3.)+a32*hs*hs+a31*hs+a30;
1046  Double_t K3N4=a44*pow(hs,4.)+a43*pow(hs,3.)+a42*hs*hs+a41*hs+a40;
1047  Double_t K3N5=a54*pow(hs,4.)+a53*pow(hs,3.)+a52*hs*hs+a51*hs+a50;
1048 
1049  k3n=K3N1*(ras02*ras03*ras04*ras05)/(ras12*ras13*ras14*ras15)+
1050  K3N2*(ras01*ras03*ras04*ras05)/(ras21*ras23*ras24*ras25)+
1051  K3N3*(ras01*ras02*ras04*ras05)/(ras31*ras32*ras34*ras35)+
1052  K3N4*(ras01*ras02*ras03*ras05)/(ras41*ras42*ras43*ras45)+
1053  K3N5*(ras01*ras02*ras03*ras04)/(ras51*ras52*ras53*ras54);
1054  }
1055  else if(hs > 1.40){ // K3 factor for direction parallel to wire or normal to wire are the same
1056  Double_t a13 = -0.003152, a12 = 0.05202, a11 = -0.3206, a10 = 0.8442;
1057  Double_t a23 = -0.003285, a22 = 0.05351, a21 = -0.3215, a20 = 0.8072;
1058  Double_t a33 = -0.003576, a32 = 0.05678, a31 = -0.3279, a30 = 0.7774;
1059  Double_t a43 = -0.003753, a42 = 0.05816, a41 = -0.3257, a40 = 0.7409;
1060  Double_t a53 = -0.003850, a52 = 0.05845, a51 = -0.3184, a50 = 0.6947;
1061 
1062  Double_t K3P1=a13*pow(hs,3.)+a12*hs*hs+a11*hs+a10;
1063  Double_t K3P2=a23*pow(hs,3.)+a22*hs*hs+a21*hs+a20;
1064  Double_t K3P3=a33*pow(hs,3.)+a32*hs*hs+a31*hs+a30;
1065  Double_t K3P4=a43*pow(hs,3.)+a42*hs*hs+a41*hs+a40;
1066  Double_t K3P5=a53*pow(hs,3.)+a52*hs*hs+a51*hs+a50;
1067 
1068  k3p=K3P1*(ras02*ras03*ras04*ras05)/(ras12*ras13*ras14*ras15)+
1069  K3P2*(ras01*ras03*ras04*ras05)/(ras21*ras23*ras24*ras25)+
1070  K3P3*(ras01*ras02*ras04*ras05)/(ras31*ras32*ras34*ras35)+
1071  K3P4*(ras01*ras02*ras03*ras05)/(ras41*ras42*ras43*ras45)+
1072  K3P5*(ras01*ras02*ras03*ras04)/(ras51*ras52*ras53*ras54);
1073 
1074  k3n=k3p;
1075  }
1076 
1077  // calculate K1 and K2
1078  Double_t sqrtK3P = sqrt(k3p);
1079  Double_t sqrtK3N = sqrt(k3n);
1080 
1081  // K2=PI*(1-sqrt(K3)/2)/2, PI/2=1.571
1082  k2p=1.571*(1.0-sqrtK3P/2.0);
1083  k2n=1.571*(1.0-sqrtK3N/2.0);
1084 
1085  // K1=K2*sqrt(K3)/(4.*atan(sqrt(K3)))
1086  k1p=k2p*sqrtK3P/(4.*atan(sqrtK3P));
1087  k1n=k2n*sqrtK3N/(4.*atan(sqrtK3N));
1088 
1089  SetRadiusOfAmpliWire(ra);
1090  SetPitchOfAmpliWire(s);
1091  SetACseparation(h);
1092  SetMathiesonFactorK1P(k1p);
1093  SetMathiesonFactorK2P(k2p);
1094  SetMathiesonFactorK3P(k3p);
1095  SetMathiesonFactorK1N(k1n);
1096  SetMathiesonFactorK2N(k2n);
1097  SetMathiesonFactorK3N(k3n);
1098  if(DIGI_DEBUG>3) cout << "Exits amplificationManager::SetWireAmplificationParameters()" << endl;
1099 }
1100 
1101 
1103 
1104  private:
1105  padsGeometry* padsGeo; //ACTAR pads geometry class
1107  Double_t longitudinalDiffusion; //gas longitudinal diff. for e-
1108  Double_t transversalDiffusion; //gas transversal diff. for e-
1109  Double_t driftVelocity; //gas drift velocity for e
1110  Double_t lorentzAngle;
1111 
1112  Double_t magneticField; //magnetic field (T)
1113  //for a box: normal to E
1114  //for a cylinder: parallel to Z
1115  //creo que si pongo diffusion y drift no deberia poner campo magnetico
1116  //sino parameters de deriva asociados al campo magnetico...
1117 
1118  Double_t padPlaneRadius;
1119  Double_t gasWvalue; //The W-value is defined as the average energy lost by
1120  //the incident particle per ion pair formed. Due to the
1121  //competing mechanism of the energy loss, i.e. excitation,
1122  //W-value is always greater than the ionization energy.
1123  //It runs from 25 to 45 eV for most gases of interest.
1124 
1125  Bool_t oldChargeCalculation; //Make it True if you want to test the old style of calculation
1126 
1127  public:
1128  driftManager();
1129  virtual ~driftManager();
1130 
1131  void SetDiffusionParameters(Double_t lon, Double_t tra){
1132  longitudinalDiffusion = lon;
1133  transversalDiffusion = tra;
1134  }
1135 
1136  void SetDriftParameters(Double_t voltage, Double_t height, Double_t pressure, TString gasName);
1137 
1138  void SetDriftVelocity(Double_t vel){driftVelocity=vel;}
1139  void SetLorentzAngle(Double_t vel){lorentzAngle=vel;}
1140  void SetMagneticField(Double_t vel){magneticField=vel;}
1141  void SetGasWvalue(Double_t value){gasWvalue=value;}
1142  void SetOldChargeCalculation(void){oldChargeCalculation=kTRUE;}
1143  void SetNewChargeCalculation(void){oldChargeCalculation=kFALSE;}
1144 
1145  Double_t GetLongitudinalDiffusion(void){return longitudinalDiffusion;}
1146  Double_t GetTransversalDiffusion(void){return transversalDiffusion;}
1147  Double_t GetDriftVelocity(void){return driftVelocity;}
1148  Double_t GetLorentzAngle(void){return lorentzAngle;}
1149  Double_t GetMagneticField(void){return magneticField;}
1150  Double_t GetGasWvalue(void){return gasWvalue;}
1151  Bool_t GetOldChargeCalculation(void){return oldChargeCalculation;}
1152 
1153  void GetStatus(void);
1154 
1155  void ConnectToGeometry(padsGeometry* pad){padsGeo = pad;}
1157  Int_t CalculatePositionAfterDrift(projectionOnPadPlane* pro);
1158  void CalculatePadsWithCharge(projectionOnPadPlane* pro, TClonesArray* clo, Int_t &numberOfPadsBeforeThisLoopStarted);
1159  void CalculatePadsWithCharge_oldStyle(Double_t k1p, Double_t k2p, Double_t k3p,
1160  Double_t k1n, Double_t k2n, Double_t k3n,
1161  projectionOnPadPlane* pro, TClonesArray* clo);
1162  ClassDef(driftManager,1);
1163 };
1164 
1166  padsGeo=0;
1167  ampManager=0;
1168  longitudinalDiffusion=0.;
1169  transversalDiffusion=0.;
1170  driftVelocity=0.;
1171  lorentzAngle=0.;magneticField=0.;
1172  gasWvalue=30.;
1173  oldChargeCalculation=kFALSE;
1174 }
1175 
1177 }
1178 
1179 void driftManager::SetDriftParameters(Double_t voltage, Double_t height, Double_t pressure, TString gasName){
1180  // units: voltage: volts, for MAYA, this is the voltage between the upper cathode and the Frish grid
1181  // height: mm, for MAYA, this is the distance between the upper cathode and the Frish grid
1182  // pressure: mbar, pressure of the active gas
1183  // cf: simulation report of D.Y. Pang
1184  if(DIGI_DEBUG>3) cout << "Enters driftManager::SetDriftParameters()" << endl;
1185  if(gasName=="deuterium"){
1186  Double_t fieldStrength= voltage/(height/10.); // E=V/D, in volts/cm
1187  Double_t eOverP = fieldStrength/(pressure*0.75006); // E/P, in volts cm^-1 torr^-1
1188  Double_t a0=13.759, a1=0.480, a2=0.0242, a3=0.0126; // coefficients for velocity (W)
1189  Double_t velocity = exp(a0+a1*log(eOverP)+a2*pow(log(eOverP),2)+a3*pow(log(eOverP),3)); // in cm/s
1190  a0=-1.314, a1=0.710, a2=-0.0497, a3=-0.00582; // coefficients for diffusion (D/mu)
1191  Double_t a4=0.00732, a5=0.000901;
1192  Double_t dOverMu = exp(a0+a1*log(eOverP)+a2*pow(log(eOverP),2)+a3*pow(log(eOverP),3)
1193  +a4*pow(log(eOverP),4)+a5*pow(log(eOverP),5)); // in volts
1194  Double_t diffusion = dOverMu*(velocity/fieldStrength); // in cm^2/s
1195  velocity = velocity*1.0e-8; // in mm/ns
1196  diffusion = diffusion*1.0e-7; // in mm^2/ns
1197  SetDriftVelocity(velocity); // in mm/ns
1198  SetDiffusionParameters(diffusion,diffusion); // we assume longitudinalDiffusion==transversalDiffusion
1199  if(DIGI_DEBUG) cout << "For voltage=" << voltage << " V, pressure=" << pressure
1200  << " mbar, and " << gasName << " gas" << endl;
1201  if(DIGI_DEBUG) cout << "drift velocity=" << velocity << " mm/ns, diffusion parameter is "
1202  << diffusion << " mm^2/ns" << endl;
1203  }
1204  else if(gasName=="isobutane"){
1205  Double_t fieldStrength = (voltage/1000.)/(height/10.); // E=V/D, in kV/cm
1206  Double_t eOverP = fieldStrength/(pressure*0.0009869); // E/P, in kV/(cm atm).
1207  if(eOverP<0.1 || eOverP >1.8) cout << "**** NOTE: drift parameters calculated in an extrapolated region! ****" << endl;
1208  Double_t a0=-0.1441, a1=2.981, a2=0.6421, a3=-0.5853; // coefficients for velocity
1209  Double_t velocity = a0 + a1*eOverP + a2*pow(eOverP,2) + a3*pow(eOverP,3); // in cm/mus
1210  a0=1.2948, a1=-1.7737, a2=0.1617, a3=-0.003537;
1211  fieldStrength = fieldStrength*1000.; // for sigma, E is in V/cm
1212  Double_t logE= log(fieldStrength);
1213  Double_t sigma0x = exp(a0+a1*logE+a2*pow(logE,2)+a3*pow(logE,3)); // in cm^{1/2}
1214  Double_t diffusion = 0.5*velocity*pow(sigma0x,2); // D=W*sigma0x^2/2, in cm^2/mus
1215  velocity = velocity/100.; // in mm/ns
1216  diffusion= diffusion/10.; // in mm^2/ns
1217  SetDriftVelocity(velocity); // in mm/ns
1218  SetDiffusionParameters(diffusion,diffusion); // we assume longitudinalDiffusion==transversalDiffusion
1219  if(DIGI_DEBUG) cout << "For voltage=" << voltage << " V, pressure=" << pressure
1220  << " mbar, and " << gasName << " gas" << endl;
1221  if(DIGI_DEBUG) cout << "drift velocity=" << velocity << " mm/ns, diffusion parameter is "
1222  << diffusion << " mm^2/ns" << endl;
1223  }
1224  else{
1225  if(DIGI_DEBUG) cout << endl << "drift and diffusion parameters for this gas are not implemented yet!" << endl << endl;
1226  }
1227  if(DIGI_DEBUG>3) cout << "Exits driftManager::SetDriftParameters()" << endl;
1228 }
1229 
1231  // calculates the position on the pads plane after the electron swarm drift
1232  if(DIGI_DEBUG>3) cout << "Enters driftManager::CalculatePositionAfterDrift()" << endl;
1233  Double_t driftDistPre=0.;
1234  Double_t driftDistPost=0.;
1235  Double_t rhoPre = sqrt(pro->GetTrack()->GetYPre()*
1236  pro->GetTrack()->GetYPre() +
1237  pro->GetTrack()->GetXPre()*
1238  pro->GetTrack()->GetXPre());
1239  Double_t rhoPost = sqrt(pro->GetTrack()->GetYPost()*
1240  pro->GetTrack()->GetYPost() +
1241  pro->GetTrack()->GetXPost()*
1242  pro->GetTrack()->GetXPost());
1243 
1244  TRandom *random=new TRandom();
1245  random->SetSeed(0);
1246 
1247  if(padsGeo->GetEndCapMode()==1) ;
1248  else{
1249  // steps on the border (ie Transportation) are taken into account
1250  if(pro->GetTrack()->GetZPre() < -padsGeo->GetZLength() ||
1251  pro->GetTrack()->GetZPre() > padsGeo->GetZLength() ||
1252  pro->GetTrack()->GetZPost() < -padsGeo->GetZLength() ||
1253  pro->GetTrack()->GetZPost() > padsGeo->GetZLength()) pro->SetPosition(5); // out of range
1254  else if(rhoPre < padsGeo->GetDeltaProximityBeam() ||
1255  rhoPost < padsGeo->GetDeltaProximityBeam()) pro->SetPosition(1); //if any point is closer to the (0,0,z) than a delta
1256  else if(rhoPre < padsGeo->GetSizeBeamShielding() &&
1257  rhoPost < padsGeo->GetSizeBeamShielding()) pro->SetPosition(2); //if both points lies within the beamShielding
1258  else if(rhoPre < padsGeo->GetSizeBeamShielding() ||
1259  rhoPost < padsGeo->GetSizeBeamShielding()) pro->SetPosition(3); //if one point is within the beamShielding
1260  else pro->SetPosition(4); //if both points lie outside of beamShielding, still to be checked after as a function of geoType
1261  }
1262 
1263  if(padsGeo->GetGeoType()==1) { //cylinder
1264  if(pro->GetPosition() == 4 &&
1265  rhoPre <= padsGeo->GetRadius() &&
1266  rhoPost <= padsGeo->GetRadius()) pro->SetPosition(4);
1267  else pro->SetPosition(5);
1268  //if the pads goes out of the gas chamber
1269  if( pro->GetPosition()==5 ) return 0;
1270  Double_t phiPre = atan2(pro->GetTrack()->GetYPre(),
1271  pro->GetTrack()->GetXPre());
1272  Double_t phiPost = atan2(pro->GetTrack()->GetYPost(),
1273  pro->GetTrack()->GetXPost());
1274  driftDistPre = padsGeo->GetRadius() - rhoPre;
1275  if(lorentzAngle==0.) {
1276  //
1277  //if no magnetic field, the cloud limits drift to the same point in
1278  // phiZ plane. The drift time is obtained from the differences in rho
1279  //
1280  pro->GetPre()->SetPerp(padsGeo->GetRadius()); //rho is the pad plane rho
1281  pro->GetPre()->SetPhi(phiPre); //phi is not changed
1282  pro->GetPre()->SetZ(pro->GetTrack()->GetZPre()); //Z is not changed
1283  pro->SetTimePre(pro->GetTrack()->GetTimePre() + driftDistPre / driftVelocity);
1284  pro->GetPost()->SetPerp(padsGeo->GetRadius()); //rho is the pad plane rho
1285  pro->GetPost()->SetPhi(phiPost); //phi is not changed
1286  pro->GetPost()->SetZ(pro->GetTrack()->GetZPost()); //Z is not changed
1287  pro->SetTimePost(pro->GetTrack()->GetTimePost() + (padsGeo->GetRadius() - rhoPost) / driftVelocity);
1288  }
1289  else{
1290  // THIS CASE REQUIRES RETHINKING: B IS USUALLY PARALLEL TO E IN THIS CASE
1291  // BASICALLY AFFECTS TO THE DRIFT PARAMETERS WITHOUT A LORENTZ ANGLE
1292  // IS NECCESARY A B NORMAL TO E CASE IN CYLINDRICAL GEOMETRY??
1293  //if the magnetic field is set, the displacement is more complex...
1294  //NOT YET DONE... SIMPLY COPYING THE PREVIOUS CASE
1295  //if(DIGI_DEBUG)
1296  if(DIGI_DEBUG)
1297  cout << "________________________________________________________" << endl
1298  << " Output of driftManager::CalculatePositionAfterDrift()" << endl
1299  << " NOT YET INTRODUCED A CYLINDRIC ACTAR WITH MAGNETIC FIELD!" << endl;
1300  pro->GetPre()->SetPerp(padsGeo->GetRadius()); //rho is the pad plane rho
1301  pro->GetPre()->SetPhi(phiPre); //phi is not changed
1302  pro->GetPre()->SetZ(pro->GetTrack()->GetZPre()); //Z is not changed
1303  pro->SetTimePre(pro->GetTrack()->GetTimePre() + driftDistPre / driftVelocity);
1304  pro->GetPost()->SetPerp(padsGeo->GetRadius()); //rho is the pad plane rho
1305  pro->GetPost()->SetPhi(phiPost); //phi is not changed
1306  pro->GetPost()->SetZ(pro->GetTrack()->GetZPost()); //Z is not changed
1307  pro->SetTimePost(pro->GetTrack()->GetTimePost() + (padsGeo->GetRadius() - rhoPost) / driftVelocity);
1308  }
1309  }
1310 
1311  if(padsGeo->GetGeoType()==0){ //box
1312  if(padsGeo->GetEndCapMode()==1){
1313  Double_t tempY = pro->GetTrack()->GetYPre(); //storing old Y
1314  pro->GetTrack()->SetYPre(pro->GetTrack()->GetZPre()-2*padsGeo->GetYLength()); //move Z to Y
1315  pro->GetTrack()->SetZPre(-tempY+padsGeo->GetZLength()); //move Y to Z
1316  tempY= pro->GetTrack()->GetYPost();
1317  pro->GetTrack()->SetYPost(pro->GetTrack()->GetZPost()-2*padsGeo->GetYLength());
1318  pro->GetTrack()->SetZPost(-tempY+padsGeo->GetZLength());
1319  pro->SetPosition(5);
1320  //repeating here the general position selection rules after the change of
1321  //coordinates required to project on the endcaps
1322  //if(pro->GetTrack()->GetZPre() <= 0 ||
1323  // pro->GetTrack()->GetZPre() >= 2 * padsGeo->GetZLength() ||
1324  // pro->GetTrack()->GetZPost() <= 0 ||
1325  // pro->GetTrack()->GetZPost() >= 2 * padsGeo->GetZLength()) pro->SetPosition(5);
1326  if(pro->GetTrack()->GetZPre() <= -padsGeo->GetZLength() ||
1327  pro->GetTrack()->GetZPre() >= padsGeo->GetZLength() ||
1328  pro->GetTrack()->GetZPost() <= -padsGeo->GetZLength() ||
1329  pro->GetTrack()->GetZPost() >= padsGeo->GetZLength()) pro->SetPosition(5); // out of range
1330  else if(rhoPre < padsGeo->GetDeltaProximityBeam() ||
1331  rhoPost <padsGeo->GetDeltaProximityBeam()) pro->SetPosition(1);
1332  else if(rhoPre < padsGeo->GetSizeBeamShielding() &&
1333  rhoPost < padsGeo->GetSizeBeamShielding()) pro->SetPosition(2);
1334  else if(rhoPre < padsGeo->GetSizeBeamShielding() ||
1335  rhoPost < padsGeo->GetSizeBeamShielding()) pro->SetPosition(3);
1336  else pro->SetPosition(4); //still to be checked after as a function of the geoType
1337  }
1338  //Correcting the Y position: it is defined at the center of gaschamber
1339  if( pro->GetPosition() == 4 &&
1340  pro->GetTrack()->GetYPost() <= padsGeo->GetYLength() - padsGeo->GetYBeamShift() &&
1341  pro->GetTrack()->GetYPost() >= (padsGeo->GetYBeamShift() - padsGeo->GetYLength()) &&
1342  pro->GetTrack()->GetXPost() <= padsGeo->GetXLength() &&
1343  pro->GetTrack()->GetXPost() >= (-padsGeo->GetXLength()) ) pro->SetPosition(4);
1344  else pro->SetPosition(5);
1345 
1346  //if the pads goes out of the gas chamber
1347  if(pro->GetPosition()==5) return 0;
1348 
1349  //Correcting the Y position: it is defined at the center of gaschamber
1350  driftDistPre = padsGeo->GetYBeamShift() + padsGeo->GetYLength() + pro->GetTrack()->GetYPre();
1351  driftDistPost= padsGeo->GetYBeamShift() + padsGeo->GetYLength() + pro->GetTrack()->GetYPost();
1352 
1353  if(lorentzAngle==0.) {
1354  //if no magnetic field, the cloud limits drift to the same point in
1355  // XZ space. The drift time is obtained from the differences in Y
1356  pro->SetSigmaTransvAtPadPlane(sqrt(driftDistPre*2*transversalDiffusion/driftVelocity));
1357 
1358  pro->GetPre()->SetX(pro->GetTrack()->GetXPre()); //X is not changed
1359  pro->GetPre()->SetY(-padsGeo->GetYLength()); //Correcting! Y is the pad plane
1360  pro->GetPre()->SetZ(pro->GetTrack()->GetZPre()); //Z is not changed
1361  pro->SetTimePre(pro->GetTrack()->GetTimePre() + driftDistPre / driftVelocity);
1362  pro->GetPost()->SetX(pro->GetTrack()->GetXPost());
1363  pro->GetPost()->SetY(-padsGeo->GetYLength()); //Correcting! Y is the pad plane
1364  pro->GetPost()->SetZ(pro->GetTrack()->GetZPost());
1365  pro->SetTimePost(pro->GetTrack()->GetTimePost()+driftDistPost/ driftVelocity);
1366  }
1367  else{
1368  //if the magnetic field is set, the displacement is more complex...
1369  driftDistPre = driftDistPre / cos(lorentzAngle);
1370  Double_t newX = pro->GetTrack()->GetXPre() +
1371  (pro->GetTrack()->GetYPre()) * tan(lorentzAngle);
1372  pro->GetPre()->SetX(newX); //X is changed by Lorentz angle
1373  pro->GetPre()->SetY(0.); //Y is the pad plane
1374  pro->GetPre()->SetZ(pro->GetTrack()->GetZPre()); //Z is not changed
1375  pro->SetTimePre(pro->GetTrack()->GetTimePre() + driftDistPre / driftVelocity);
1376  newX= pro->GetTrack()->GetXPost() +
1377  (pro->GetTrack()->GetYPost()) * tan(lorentzAngle);
1378  pro->GetPost()->SetX(newX); //X is changed by Lorentz angle
1379  pro->GetPost()->SetY(0.);
1380  pro->GetPost()->SetZ(pro->GetTrack()->GetZPost()); //Z is not changed
1381  pro->SetTimePost(pro->GetTrack()->GetTimePost() +
1382  (pro->GetTrack()->GetYPost()/cos(lorentzAngle))/driftVelocity);
1383  }
1384  }
1385  pro->SetSigmaLongAtPadPlane(sqrt(driftDistPre*2*longitudinalDiffusion/driftVelocity));
1386  pro->SetSigmaTransvAtPadPlane(sqrt(driftDistPre*2*transversalDiffusion/driftVelocity));
1387 
1388  if(DIGI_DEBUG>1)
1389  cout << "________________________________________________________" << endl
1390  << " Output of driftManager::CalculatePositionAfterDrift()" << endl
1391  << "pre = (" << pro->GetTrack()->GetXPre() << ","
1392  << pro->GetTrack()->GetYPre() << ","
1393  << pro->GetTrack()->GetZPre() << ")" << endl
1394  << " post = (" << pro->GetTrack()->GetXPost() << ","
1395  << pro->GetTrack()->GetYPost() << ","
1396  << pro->GetTrack()->GetZPost() << ")" << endl
1397  << " pre Projected = (" << pro->GetPre()->X() << ","
1398  << pro->GetPre()->Y() << ","
1399  << pro->GetPre()->Z() << ") timePre = " << pro->GetTimePre() << endl
1400  << " post Projected = (" << pro->GetPost()->X() << ","
1401  << pro->GetPost()->Y() << ","
1402  << pro->GetPost()->Z() << ") timePost = " << pro->GetTimePost() << endl
1403  << "________________________________________________________"<< endl;
1404 
1405  return 1;
1406 }
1407 
1408 void driftManager::CalculatePadsWithCharge(projectionOnPadPlane* pro, TClonesArray* clo, Int_t &numberOfPadsBeforeThisLoopStarted) {
1409  //
1410  // Calculates the pads with charge after the electron swarm drift
1411  //
1412  if(DIGI_DEBUG>3) cout << "Enters driftManager::CalculatePadsWithCharge()" << endl;
1413 
1414  Double_t halfPadSize = padsGeo->GetPadSize()/2.;
1415  Double_t rHexagon = padsGeo->GetRHexagon();
1416  TVector3* preOfThisProjection = pro->GetPre();
1417  TVector3* postOfThisProjection = pro->GetPost();
1418  Double_t preOfThisProjectionX = preOfThisProjection->X();
1419  Double_t preOfThisProjectionZ = preOfThisProjection->Z();
1420  Double_t postOfThisProjectionX = postOfThisProjection->X();
1421  Double_t postOfThisProjectionZ = postOfThisProjection->Z();
1422  Int_t initPad = padsGeo->IsInPadNumber(preOfThisProjection);
1423  Int_t finalPad = padsGeo->IsInPadNumber(postOfThisProjection);
1424  Int_t initColumn = padsGeo->CalculateColumn(initPad);
1425  Int_t initRow = padsGeo->CalculateRow(initPad);
1426  Int_t finalColumn = padsGeo->CalculateColumn(finalPad);
1427  Int_t finalRow = padsGeo->CalculateRow(finalPad);
1428  //Int_t numberofpoints=0;
1429  //TH2F *hist=new TH2F("h2","Padplane",151,0,300,151,-150,150);
1430  //TGraph *g=new TGraph();
1431  //TCanvas *c=new TCanvas();
1432 
1433  Double_t strideLength=pro->GetTrack()->GetStrideLength();
1434  Double_t energyStride=pro->GetTrack()->GetEnergyStride();
1435 
1436  if(DIGI_DEBUG>2)
1437  cout << "________________________________________________________" << endl
1438  << " Output of driftManager::CalculatePadsWithCharge()" << endl
1439  << " From (pre) " << initPad << " (" << initRow << "," << initColumn
1440  << ") to (post) " << finalPad << " (" << finalRow << ","
1441  << finalColumn << ")" << endl
1442  << " Stride Length " << strideLength << " mm, Energy "
1443  << 1000*energyStride << " keV" << endl
1444  << " Initial pos " << preOfThisProjectionX << " "
1445  << preOfThisProjectionZ << endl
1446  << " Final pos " << postOfThisProjectionX << " "
1447  << postOfThisProjectionZ << endl;
1448 
1449  Double_t energyPerPair=GetGasWvalue(); // W value in eV
1450 
1451  //Calculating electrons produced every 0.5 mm
1452  Int_t nsteps=strideLength/0.5; //0 if below 0.5, ...
1453  Double_t sigmaTrans=pro->GetSigmaTransvAtPadPlane();
1454  Double_t sigmaLong=pro->GetSigmaLongAtPadPlane();
1455 
1456  Double_t *Xstep = new Double_t[nsteps+2];
1457  Double_t *Zstep = new Double_t[nsteps+2];
1458  Double_t *EnergyStep= new Double_t[nsteps+2];
1459  Int_t *NumberOfElectrons=new Int_t[nsteps+2];
1460 
1461  Int_t numberOfRows=padsGeo->GetNumberOfRows();
1462  Int_t numberOfColumns=padsGeo->GetNumberOfColumns();
1463 
1464  //HAPOL HARDCODED! SOLVE IT! ->HINT: Create a TClonesArray of an object with the data
1465  Int_t chargeOnPads[151][151]={0};
1466  Int_t chargeOnPadsAmplified[151][151]={0};
1467  Int_t chargeOnPadsTotalAmplified[151][151]={0};
1468 
1469  /* Int_t **chargeOnPads; */
1470  /* chargeOnPads=new Int_t*[numberOfRows]; */
1471  /* Int_t **chargeOnPadsAmplified=new Int_t*[numberOfRows]; */
1472  /* Int_t **chargeOnPadsTotalAmplified=new Int_t*[numberOfRows]; */
1473  /* for(Int_t nrows=0;nrows<numberOfRows;nrows++){ */
1474  /* chargeOnPads[nrows]=new Int_t[numberOfColumns]; */
1475  /* chargeOnPadsAmplified[nrows]=new Int_t[numberOfColumns]; */
1476  /* chargeOnPadsTotalAmplified[nrows]=new Int_t[numberOfColumns]; */
1477  /* } */
1478 
1479  Int_t *rowList=new Int_t[4000];
1480  Int_t *columnList=new Int_t[4000];
1481  //for(Int_t u=0;u<numberOfRows;u++){
1482  // for(Int_t k=0;k<numberOfColumns;k++)
1483  // chargeOnPads[u][k]=0.;
1484  //}
1485 
1486  Double_t sumX=0;
1487  Double_t sumZ=0;
1488  Int_t electrons_lost=0;
1489 
1490  for(Int_t k=0;k<=(nsteps+1);k++){ //NOTE: a = was missing here before...
1491  //the step is the strideLength if below 0.5 mm and is between 0.5 mm and 1 mm otherwise
1492  Double_t stepx=(postOfThisProjectionX-preOfThisProjectionX)/(nsteps+1);
1493  Double_t stepz=(postOfThisProjectionZ-preOfThisProjectionZ)/(nsteps+1);
1494  Xstep[k]=preOfThisProjectionX+k*stepx;
1495  Zstep[k]=preOfThisProjectionZ+k*stepz;
1496  EnergyStep[k]=energyStride/(nsteps+1);
1497  Int_t electrons = 1e6 * EnergyStep[k] / energyPerPair;
1498  NumberOfElectrons[k]=gRandom->Poisson(electrons);
1499  }
1500 
1501  Double_t electron_posX = 0;
1502  Double_t electron_posZ = 0;
1503  Int_t padRow = 0;
1504  Int_t padColumn = 0;
1505  for(Int_t istep=0;istep<=nsteps;istep++){
1506  for(Int_t u=0;u<numberOfRows;u++){
1507  for(Int_t k=0;k<numberOfColumns;k++){
1508  chargeOnPads[u][k]=0.;//Reset electrons on each step
1509  chargeOnPadsAmplified[u][k]=0;
1510  }
1511  }
1512  Double_t strideCenterX = (Xstep[istep+1]+Xstep[istep])/2.;
1513  Double_t strideCenterZ = (Zstep[istep+1]+Zstep[istep])/2.;
1514 
1515  //g->SetPoint(numberofpoints,strideCenterZ,strideCenterX);
1516  //numberofpoints++;
1517 
1518  Double_t energyStride=EnergyStep[istep];
1519  for(Int_t ielectron=0;ielectron<NumberOfElectrons[istep]; ielectron++){
1520  electron_posX = gRandom->Gaus(strideCenterX,sigmaTrans); //HAPOL Better if we also random starting position
1521  electron_posZ = gRandom->Gaus(strideCenterZ,sigmaTrans);
1522  padRow = padsGeo->GetPadRowFromXZValue(electron_posX,electron_posZ);
1523  padColumn = padsGeo->GetPadColumnFromXZValue(electron_posX,electron_posZ);
1524 
1525  if(padRow>0 && padColumn>0 && padRow<152 && padColumn<152 ){ //HAPOL SOLVE THE HARDCODED DATA
1526  chargeOnPads[padRow-1][padColumn-1]++;
1527  chargeOnPadsAmplified[padRow-1][padColumn-1]+=1000*Polya();
1528  }
1529  else electrons_lost++;
1530  }
1531 
1532  for(Int_t u=0;u<numberOfRows;u++){
1533  for(Int_t k=0;k<numberOfColumns;k++){
1534  if(chargeOnPads[u][k]>0){
1535  chargeOnPadsTotalAmplified[u][k]+=chargeOnPadsAmplified[u][k];
1536  }
1537  }
1538  }
1539  }//End of Loop on steps
1540 
1541  Int_t padsWithSignal=0;
1542  for(Int_t u=0;u<numberOfRows;u++){
1543  for(Int_t k=0;k<numberOfColumns;k++){
1544  if(chargeOnPadsTotalAmplified[u][k]>0){
1545  rowList[padsWithSignal]=u+1;
1546  columnList[padsWithSignal]=k+1;
1547  padsWithSignal++;
1548  }
1549  }
1550  }
1551 
1552  Int_t padUnderTest;
1553  TVector3 centerPad;
1554 
1555  if(padsWithSignal>0) {
1556  Float_t total_charge=0;
1557  ActarPadSignal** thePadSignal;
1558  thePadSignal = new ActarPadSignal*[padsWithSignal];
1559 
1560  for(Int_t iterOnPads=0;iterOnPads<padsWithSignal;iterOnPads++){
1561  padUnderTest = padsGeo->CalculatePad(rowList[iterOnPads],columnList[iterOnPads]);
1562 
1563  Float_t charge=chargeOnPadsTotalAmplified[rowList[iterOnPads]-1][columnList[iterOnPads]-1];
1564 
1565  total_charge+=charge;
1566  if(DIGI_DEBUG>1)
1567  cout << rowList[iterOnPads] << " " << columnList[iterOnPads]
1568  << " ====================>Charge " << charge << endl;
1569  //hist->SetBinContent(columnList[iterOnPads],rowList[iterOnPads],charge);
1570 
1571  if(DIGI_DEBUG && (rowList[iterOnPads]<0 || columnList[iterOnPads]<0))
1572  cout << "something WRONG: (row, column) = (" << rowList[iterOnPads] << "," << columnList[iterOnPads]
1573  << ")" << ", CHARGE=" << charge << "iterOnPads=" << iterOnPads << endl;
1574 
1575  //Let us create and fill as many padSignals as pads in the event
1576  thePadSignal[iterOnPads] = new ActarPadSignal();
1577  thePadSignal[iterOnPads]->SetPadNumber(padUnderTest);
1578  thePadSignal[iterOnPads]->SetPadRow(rowList[iterOnPads]);
1579  thePadSignal[iterOnPads]->SetPadColumn(columnList[iterOnPads]);
1580  thePadSignal[iterOnPads]->SetNumberOfStrides(1); //to solve
1581  thePadSignal[iterOnPads]->SetInitTime(pro->GetTimePre());
1582  thePadSignal[iterOnPads]->SetFinalTime(pro->GetTimePost());
1583  //thePadSignal[iterOnPads]->SetSigmaTime(pro->GetSigmaLongAtPadPlane()); //in mm
1584  thePadSignal[iterOnPads]->SetSigmaTime(pro->GetSigmaLongAtPadPlane()/driftVelocity); //in ns
1585  //cout<<thePadSignal[iterOnPads]->GetSigmaTime()<<endl;
1586  thePadSignal[iterOnPads]->SetChargeDeposited(charge);
1587  thePadSignal[iterOnPads]->SetEventID(pro->GetTrack()->GetEventID());
1588  thePadSignal[iterOnPads]->SetRunID(pro->GetTrack()->GetRunID());
1589 
1590  new((*clo)[iterOnPads+numberOfPadsBeforeThisLoopStarted])ActarPadSignal(*thePadSignal[iterOnPads]); //numberOfPadsBeforeThisLoopStarted was missing
1591  thePadSignal[iterOnPads]->Reset();
1592  }
1593 
1594  numberOfPadsBeforeThisLoopStarted+=padsWithSignal;
1595  //hist->Draw("colz");
1596  //g->Draw("*same");
1597  //c->Update();
1598  //c->WaitPrimitive();
1599  if(DIGI_DEBUG>1){
1600  cout<<"total charge-->"<<total_charge<<" "<<total_charge/(pro->GetTrack()->GetEnergyStride()*1000)*100<<"% of total"<<endl;
1601  cout<<"Number Of Pads With Signal: "<<padsWithSignal<<endl;
1602  }
1603  for (Int_t i=0;i<padsWithSignal;i++) delete thePadSignal[i];
1604  delete thePadSignal;
1605 
1606  }//if numberOfPadsWith Signal>0
1607 
1608  delete[] EnergyStep;
1609  delete[] NumberOfElectrons;
1610  delete[] rowList;
1611  delete[] columnList;
1612  //delete c;
1613  //delete hist;
1614  //delete out;
1615  //numberOfRows=72;
1616  /* for (Int_t jj=0; jj<numberOfRows; jj++){ */
1617  /* cout<<numberOfRows<<" "<<jj<<" Deleting chargeOnPads ..."<<endl; */
1618  /* delete[](chargeOnPads[jj]); */
1619  /* } */
1620  /* for (Int_t jj=0; jj<numberOfRows; jj++){ */
1621  /* cout<<numberOfRows<<" "<<jj<<" Deleting chargeOnPadsAmplified..."<<endl; */
1622  /* delete[](chargeOnPadsAmplified[jj]); */
1623  /* } */
1624  /* for (Int_t jj=0; jj<numberOfRows; jj++){ */
1625  /* cout<<numberOfRows<<" "<<jj<<" Deleting chargeOnPadsTotalAmplified..."<<endl; */
1626  /* delete[](chargeOnPadsTotalAmplified[jj]); */
1627  /* } */
1628  //cout<<"HERE!!"<<endl;
1629  /* delete[] chargeOnPads; */
1630  /* delete[] chargeOnPadsAmplified; */
1631  /* delete[] chargeOnPadsTotalAmplified; */
1632  //cout<<"HERE!!"<<endl;
1633  if(DIGI_DEBUG>3) cout << "Exits driftManager::CalculatePadsWithCharge()" << endl;
1634 }
1635 
1636 void driftManager::CalculatePadsWithCharge_oldStyle(Double_t k1p, Double_t k2p, Double_t k3p,
1637  Double_t k1n, Double_t k2n, Double_t k3n,
1638  projectionOnPadPlane* pro,
1639  TClonesArray* clo) {
1640  //TClonesArray* clo, TTree* tree) {
1641  // calculates the pads with charge after the electron swarm drift
1642  //
1643  if(DIGI_DEBUG>3) cout << "Enters driftManager::CalculatePadsWithCharge_oldStyle()" << endl;
1644 
1645  Double_t halfPadSize = padsGeo->GetPadSize()/2.;
1646  Double_t rHexagon = padsGeo->GetRHexagon();
1647 
1648  TVector3* preOfThisProjection = pro->GetPre();
1649  TVector3* postOfThisProjection = pro->GetPost();
1650  Double_t preOfThisProjectionX = preOfThisProjection->X();
1651  Double_t preOfThisProjectionZ = preOfThisProjection->Z();
1652  Double_t postOfThisProjectionX = postOfThisProjection->X();
1653  Double_t postOfThisProjectionZ = postOfThisProjection->Z();
1654 
1655  Int_t initPad = padsGeo->IsInPadNumber(preOfThisProjection); //init pad
1656  Int_t finalPad = padsGeo->IsInPadNumber(postOfThisProjection); //final pad
1657  /* Int_t initPad = 1;
1658  Int_t finalPad = 10201; // for the purpose of range resolution calculation, remove it afterward!*/
1659  Int_t initColumn = padsGeo->CalculateColumn(initPad);
1660  Int_t initRow = padsGeo->CalculateRow(initPad);
1661  Int_t finalColumn = padsGeo->CalculateColumn(finalPad);
1662  Int_t finalRow = padsGeo->CalculateRow(finalPad);
1663 
1664  Double_t strideCenterX=(preOfThisProjectionX+postOfThisProjectionX)/2.;
1665  Double_t strideCenterZ=(preOfThisProjectionZ+postOfThisProjectionZ)/2.;
1666 
1667  if(DIGI_DEBUG)
1668  cout << "________________________________________________________" << endl
1669  << " Output of driftManager::CalculatePadsWithCharge()" << endl
1670  << " From (pre) " << initPad << " (" << initRow << "," << initColumn
1671  << ") to (post) " << finalPad << " (" << finalRow << ","
1672  << finalColumn << ")" << endl;
1673 
1674  //calculate the vector between pre and post projections
1675  TVector3 strideOnPadPlane = *postOfThisProjection - *preOfThisProjection;
1676  Double_t alpha = 0; char buffer[1000];
1677  Double_t sigma = pro->GetSigmaTransvAtPadPlane();
1678 
1679  if(padsGeo->GetGeoType()==0) {//box
1680  //first, avoid the strides with points with rho<delta which are not
1681  //well defined in this situation
1682  if(padsGeo->GetSizeBeamShielding() == 0. ) {
1683  if( pro->GetPosition() == 5 || pro->GetPosition() == 0) return;
1684  }
1685  else
1686  if( pro->GetPosition() != 4) return;
1687 
1688  alpha = atan2(strideOnPadPlane.X(),strideOnPadPlane.Z());
1689  }
1690  else if (padsGeo->GetGeoType()==1) {//cylinder
1691  //first, avoid the strides with points with rho<delta which are not
1692  //well defined in this situation
1693  if( pro->GetPosition() != 4 ) return;
1694  //In this case we will use the differences of alpha in the pseudoplane [mu,Z]
1695  //where mu = phi * side
1696  padPlaneRadius = padsGeo->GetRadius();
1697  alpha = atan2((postOfThisProjection->Phi()-preOfThisProjection->Phi())*padPlaneRadius,
1698  strideOnPadPlane.Z());
1699  }
1700 
1701 
1702  if(DIGI_DEBUG) {
1703  cout << "______________________________TF2__________________________" << endl
1704  << " Output of driftManager::CalculatePadsWithCharge()" << endl
1705  << " strideOnPadPlane coordinates (" << strideOnPadPlane.x() << ","
1706  << strideOnPadPlane.y() << "," << strideOnPadPlane.z() << endl
1707  << ") with distance " << strideOnPadPlane.Mag()
1708  << " and angle w.r.t. Z axis " << alpha << endl;
1709  if(padsGeo->GetGeoType()==1)
1710  cout << "[the angle is calculated from differences in Phi] "<< endl;
1711  }
1712 
1713  if(padsGeo->GetGeoType()==0) {//box
1714  if(ampManager->GetIsWire()==0) {
1715  /* sprintf(buffer,
1716  "(%f/(2.50663*%f))*exp((-((x-%f)*%f-(y-%f)*%f)*((x-%f)*%f-(y-%f)*%f))/(2*%f*%f))",
1717  pro->GetTrack()->GetEnergyStride()*1000,sigma,
1718  pro->GetPre()->Z(),sin(alpha),pro->GetPre()->X(),cos(alpha),
1719  pro->GetPre()->Z(),sin(alpha),pro->GetPre()->X(),cos(alpha),
1720  sigma,sigma);*/
1721  sprintf(buffer,
1722  "(%f/(2.50663*%f))*exp(-((x-%f)*(x-%f)+(y-%f)*(y-%f))/(2*%f*%f))",
1723  pro->GetTrack()->GetEnergyStride()*1000,sigma,
1724  strideCenterZ, strideCenterZ, strideCenterX, strideCenterX,
1725  sigma,sigma);
1726  }
1727  else if(ampManager->GetIsWire()==1){
1728 
1729  Double_t pitchWire = ampManager->GetPitchOfAmpliWire();
1730  Double_t L = ampManager->GetACseparation(); // distance between wire and pads plane
1731  Double_t zWire = (preOfThisProjectionZ + postOfThisProjectionZ)/2.;
1732  Double_t xWire = Int_t(((preOfThisProjectionX + postOfThisProjectionX)/2.)/pitchWire+0.5)*pitchWire;
1733 
1734  // cout << "end point z=" << pro->GetPost()->Z() << ", x=" << pro->GetPost()->X()
1735  // << ", y=" << pro->GetPost()->Y() << ", removable diagnoisis output, dypang 09051627" << endl;
1736 
1737  sprintf(buffer,
1738  "%f*%f*((1.-pow(tanh(%f*abs(%f-x)/%f),2.))/(1.+%f*pow(tanh(%f*abs(%f-x)/%f),2.)))*%f*((1.-pow(tanh(%f*abs(%f-y)/%f),2.))/(1.+%f*pow(tanh(%f*abs(%f-y)/%f),2.)))",
1739  pro->GetTrack()->GetEnergyStride()*100.,
1740  k1p, k2p, zWire, L, k3p, k2p, zWire, L,
1741  k1n, k2n, xWire, L, k3n, k2n, xWire, L
1742  ); // formula of E. Mathieson
1743  // sprintf(buffer,
1744  // "%f*(%f/pow(%f*%f+(%f-x)*(%f-x)+(%f-y)*(%f-y),1.5)-(3.*%f)/pow( 9.*%f*%f+(%f-x)*(%f-x)+(%f-y)*(%f-y),1.5)+(5.*%f)/pow(25.*%f*%f+(%f-x)*(%f-x)+(%f-y)*(%f-y),1.5)-(7.*%f)/pow(49.*%f*%f+(%f-x)*(%f-x)+(%f-y)*(%f-y),1.5)+(9.*%f)/pow(81.*%f*%f+(%f-x)*(%f-x)+(%f-y)*(%f-y),1.5)+(11.*%f)/pow(121.*%f*%f+(%f-x)*(%f-x)+(%f-y)*(%f-y),1.5)+(13.*%f)/pow(169.*%f*%f+(%f-x)*(%f-x)+(%f-y)*(%f-y),1.5))",
1745  // pro->GetTrack()->GetEnergyStride(),L,L,L,
1746  // zWire,zWire,xWire,xWire,L,L,L,
1747  // zWire,zWire,xWire,xWire,L,L,L,
1748  // zWire,zWire,xWire,xWire,L,L,L,
1749  // zWire,zWire,xWire,xWire,L,L,L,
1750  // zWire,zWire,xWire,xWire,L,L,L,
1751  // zWire,zWire,xWire,xWire,L,L,L,
1752  // zWire,zWire,xWire,xWire,L,L,L
1753  // ); // formula used by Thomas and Manuel
1754 
1755  /* cout << "Pre(" << pro->GetPre()->X() << "," << pro->GetPre()->Z() << ")" << endl;
1756  cout << "Post(" << pro->GetPost()->X() << "," << pro->GetPost()->Z() << ")" << endl;*/
1757  }
1758  }
1759  else if (padsGeo->GetGeoType()==1) {//cylinder
1760  sprintf(buffer,
1761  "(%f/(2.50663*%f))*exp((-((x-%f)*%f-(y-%f)*%f)*((x-%f)*%f-(y-%f)*%f))/(2*%f*%f))",
1762  pro->GetTrack()->GetEnergyStride()*1000,sigma,
1763  preOfThisProjectionZ,sin(alpha),preOfThisProjection->Phi()*padPlaneRadius,cos(alpha),
1764  preOfThisProjectionZ,sin(alpha),preOfThisProjection->Phi()*padPlaneRadius,cos(alpha),
1765  sigma,sigma);
1766  }
1767 
1768 
1769  if(DIGI_DEBUG>2)
1770  cout << endl << " Function to integrate " << buffer << endl;
1771 
1772  TF2 *f2=0;
1773  if(padsGeo->GetGeoType()==0) {//box
1774  if(ampManager->GetIsWire()==0){
1775  f2 = new TF2("f2",buffer,
1776  strideCenterZ-10*sigma,
1777  strideCenterZ+10*sigma,
1778  strideCenterX-10*sigma,
1779  strideCenterX+10*sigma);
1780  }//adjust the number before the sigma!
1781  else if(ampManager->GetIsWire()==1){ // wire amplification
1782  /* f2 = new TF2("f2",buffer,
1783  pro->GetPre()->Z()-2.*ampManager->GetACseparation(),
1784  pro->GetPre()->Z()+2.*ampManager->GetACseparation(),
1785  pro->GetPre()->X()-2.*ampManager->GetACseparation(),
1786  pro->GetPre()->X()+2.*ampManager->GetACseparation());*/
1787  f2 = new TF2("f2",buffer); // xmin, xmax, ymin, ymax actually do not matter.
1788  }
1789  }
1790  else if (padsGeo->GetGeoType()==1) {//cylinder
1791  f2 = new TF2("f2",buffer,
1792  preOfThisProjectionZ-10*sigma,
1793  preOfThisProjectionZ+10*sigma,
1794  preOfThisProjection->Phi()*padPlaneRadius-10*sigma,
1795  preOfThisProjection->Phi()*padPlaneRadius+10*sigma);//adjust the number before the sigma!
1796  }
1797 
1798  //Swap the initial an final row and columns if track goes back
1799  if(initRow>finalRow){
1800  Int_t tempRow = initRow;
1801  initRow = finalRow;
1802  finalRow = tempRow;
1803  }
1804  if(initColumn>finalColumn){
1805  Int_t tempColumn = initColumn;
1806  initColumn = finalColumn;
1807  finalColumn = tempColumn;
1808  }
1809 
1810  //we need to know which pads are going to be checked!
1811  //IDEA! Use the vector to determine the conditions to take a pad:
1812  // 1 - scalar product(strideOnPadPlane,padCenter-pro->GetPre())>0
1813  // 2 - scalar product(strideOnPadPlane,padCenter-pro->GetPost())<0
1814 
1815  Int_t securityFactor = (Int_t)(2*sigma/padsGeo->GetPadSize());
1816  if(securityFactor<1) securityFactor = 1;
1817 
1818  // Int_t securityFactor=5;
1819 
1820  //TO BE IMPROVED... TESTING TOO MUCH PADS
1821  Int_t rowsUnderTest = (finalRow +securityFactor+1) - (initRow -securityFactor);
1822  Int_t columnsUnderTest = (finalColumn+securityFactor+1) - (initColumn-securityFactor);
1823 
1824  if(DIGI_DEBUG)
1825  cout << "________________________________________________________" << endl
1826  << " Output of driftManager::CalculatePadsWithCharge()" << endl
1827  << " securityFactor " << securityFactor
1828  << ", rowsUnderTest " << rowsUnderTest << " (from "
1829  << initRow-securityFactor << " to " << initRow-securityFactor+rowsUnderTest
1830  << "), columnsUnderTest " << columnsUnderTest
1831  << " (from " << initColumn-securityFactor << " to "
1832  << initColumn-securityFactor+rowsUnderTest << ")" << endl;
1833 
1834  Double_t charge=0; Int_t numberOfPadsWithSignal=0;
1835  Int_t padUnderTest; TVector3 centerPad;
1836  Int_t rowList[40000]={0}; Int_t columnList[40000]={0};
1837  Int_t rowNumber=0, colNumber=0;
1838  for(Int_t i = 0;i<rowsUnderTest;i++){
1839  for(Int_t j = 0;j<columnsUnderTest;j++){
1840  //interval 2D [ax,bx][ay,by]
1841  padUnderTest = padsGeo->CalculatePad(initRow-securityFactor+i,
1842  initColumn-securityFactor+j);
1843  centerPad = padsGeo->CoordinatesCenterOfPad(padUnderTest);
1844  if(DIGI_DEBUG){
1845  cout << "________________________________________________________" << endl
1846  << " Output of driftManager::CalculatePadsWithCharge()" << endl
1847  << " scalar with pre " << strideOnPadPlane.Dot(centerPad-(*(pro->GetPre())))
1848  << " scalar with post " << strideOnPadPlane.Dot(centerPad-(*(pro->GetPost())))
1849  << endl;
1850  }
1851 
1852  rowNumber = initRow-securityFactor+i;
1853  colNumber = initColumn-securityFactor+j;
1854 
1855  if(rowNumber>=1 && rowNumber <= padsGeo->GetNumberOfRows()
1856  && colNumber>=1 && colNumber <= padsGeo->GetNumberOfColumns()){
1857  rowList[numberOfPadsWithSignal] = rowNumber;
1858  columnList[numberOfPadsWithSignal] = colNumber;
1859  numberOfPadsWithSignal++;
1860  }
1861  }
1862  }
1863  if(DIGI_DEBUG)
1864  cout << "________________________________________________________" << endl
1865  << " Output of driftManager::CalculatePadsWithCharge()" << endl
1866  << " numberOfPadsWithSignal = " << numberOfPadsWithSignal<<endl;
1867 
1868  Double_t phiPad, xPad, zPad;
1869 
1870  if( numberOfPadsWithSignal>0) {
1871  ActarPadSignal** thePadSignal;
1872  thePadSignal = new ActarPadSignal*[numberOfPadsWithSignal];
1873 
1874  for(Int_t iterOnPads=0;iterOnPads<numberOfPadsWithSignal;iterOnPads++){
1875  padUnderTest = padsGeo->CalculatePad(rowList[iterOnPads],columnList[iterOnPads]);
1876  centerPad = padsGeo->CoordinatesCenterOfPad(padUnderTest);
1877  if(DIGI_DEBUG)
1878  cout << "________________________________________________________" << endl
1879  << " Output of driftManager::CalculatePadsWithCharge()" << endl
1880  << " Calculating charge for pad " << padUnderTest << " ("
1881  << rowList[iterOnPads] << "," << columnList[iterOnPads] << ")" << endl;
1882 
1883  phiPad = centerPad.Phi();
1884  xPad = centerPad.X();
1885  zPad = centerPad.Z();
1886 
1887  if(padsGeo->GetGeoType()==0) {//box
1888  if(padsGeo->GetPadType()==0){ //square pad
1889  charge = f2->Integral(zPad-halfPadSize,zPad+halfPadSize,xPad-halfPadSize,xPad+halfPadSize);
1890  // in this integration, the x, and y values should be relative to the center pad.
1891  }
1892  else if(padsGeo->GetPadType()==1){ //hexagonal pad
1893  if(padsGeo->GetPadLayout()==0){ // MAYA-type layout
1894  charge = f2->Integral(zPad-rHexagon,
1895  zPad+rHexagon,
1896  xPad-1.5*halfPadSize,
1897  xPad+1.5*halfPadSize);
1898  }
1899  else if(padsGeo->GetPadLayout()==1){
1900  charge = f2->Integral(zPad-1.5*halfPadSize,
1901  zPad+1.5*halfPadSize,
1902  xPad-rHexagon,
1903  xPad+rHexagon);
1904  }
1905  }
1906  }
1907  else if (padsGeo->GetGeoType()==1) {//cylinder
1908  if(padsGeo->GetPadType()==0) //square pad
1909  charge = f2->Integral(zPad-halfPadSize,
1910  zPad+halfPadSize,
1911  (phiPad*padPlaneRadius)-halfPadSize,
1912  (phiPad*padPlaneRadius)+halfPadSize);
1913  else if(padsGeo->GetPadType()==1) //hexagonal pad
1914  charge = f2->Integral(zPad-1.5*halfPadSize,
1915  zPad+1.5*halfPadSize,
1916  (phiPad*padPlaneRadius)-rHexagon,
1917  (phiPad*padPlaneRadius)+rHexagon);
1918  }
1919 
1920  if(DIGI_DEBUG && (rowList[iterOnPads]<0 || columnList[iterOnPads]<0))
1921  cout << "some thing WRONG: (row, column) = (" << rowList[iterOnPads] << ","
1922  << columnList[iterOnPads] << ")" << ", CHARGE="<< charge << "iterOnPads=" << iterOnPads << endl;
1923 
1924  //Let us create and fill as many padSignals as pads in the event
1925  thePadSignal[iterOnPads] = new ActarPadSignal();
1926  thePadSignal[iterOnPads]->SetPadNumber(padUnderTest);
1927  thePadSignal[iterOnPads]->SetPadRow(rowList[iterOnPads]);
1928  thePadSignal[iterOnPads]->SetPadColumn(columnList[iterOnPads]);
1929  thePadSignal[iterOnPads]->SetNumberOfStrides(1); //to solve
1930  thePadSignal[iterOnPads]->SetInitTime(pro->GetTimePre());
1931  thePadSignal[iterOnPads]->SetFinalTime(pro->GetTimePost());
1932  thePadSignal[iterOnPads]->SetSigmaTime(pro->GetSigmaLongAtPadPlane());
1933  thePadSignal[iterOnPads]->SetChargeDeposited(charge);
1934  thePadSignal[iterOnPads]->SetEventID(pro->GetTrack()->GetEventID());
1935  thePadSignal[iterOnPads]->SetRunID(pro->GetTrack()->GetRunID());
1936 
1937  new((*clo)[iterOnPads])ActarPadSignal(*thePadSignal[iterOnPads]);
1938  thePadSignal[iterOnPads]->Reset();
1939  }
1940 
1941  delete f2;
1942  for (Int_t i=0;i<numberOfPadsWithSignal;i++) delete thePadSignal[i];
1943  delete thePadSignal;
1944 
1945  }
1946  if(DIGI_DEBUG>3) cout << "Exits driftManager::CalculatePadsWithCharge_oldStyle()" << endl;
1947 }
1948 
1950  if(DIGI_DEBUG>3) cout << "Enters driftManager::GetStatus()" << endl;
1951  cout << "Connected to geometry "<< padsGeo << endl
1952  <<"with longitudinalDiffusion = " << longitudinalDiffusion
1953  <<", transversalDiffusion = " << transversalDiffusion << endl
1954  <<"driftVelocity = " << driftVelocity
1955  <<", magneticField = " << magneticField << endl;
1956 }
void SetRadiusOfAmpliWire(Double_t ra)
Definition: digit.h:940
Double_t K3N
Definition: digit.h:916
Int_t numberOfColumns
Definition: digit.h:335
Double_t longitudinalDiffusion
Definition: digit.h:1107
void SetGeometryValues(TString DetectorConfig)
Definition: digit.h:384
void SetIsWireOff()
Definition: digit.h:930
void SetGasWvalue(Double_t value)
Definition: digit.h:1141
Double_t CalculateRhoN(Double_t y)
Definition: digit.h:969
virtual ~padsGeometry()
Definition: digit.h:495
Double_t padSize
Definition: digit.h:344
Int_t GetEndCapMode(void)
Definition: digit.h:445
Int_t CalculateRow(Int_t p)
Definition: digit.h:473
Int_t GetPadType(void)
Definition: digit.h:431
Int_t GetPadRow()
Definition: digit.h:199
Double_t xBeamShift
Definition: digit.h:352
Double_t gasWvalue
Definition: digit.h:1119
void SetRHexagon(Double_t si)
Definition: digit.h:413
void SetGeoType(Int_t type)
Definition: digit.h:409
void SetSigmaTime(Double_t time)
Definition: digit.h:220
void SetPosition(Int_t pos)
Definition: digit.h:311
Double_t GetMathiesonFactorK3N()
Definition: digit.h:958
Double_t K3P
Definition: digit.h:915
Double_t GetLongitudinalDiffusion(void)
Definition: digit.h:1145
ActarPadSignal & operator=(const ActarPadSignal &right)
Definition: digit.h:253
void SetEndCapModeOn()
Definition: digit.h:424
Double_t initTime
Definition: digit.h:181
Double_t pitchOfAmpliWire
Definition: digit.h:913
Int_t GetPadLayout(void)
Definition: digit.h:432
Int_t runID
Definition: digit.h:188
Double_t GetACseparation()
Definition: digit.h:952
Double_t GetFinalTime()
Definition: digit.h:205
void SetMathiesonFactorK3N(Double_t k3n)
Definition: digit.h:948
Int_t GetPadNumber()
Definition: digit.h:198
void SetNumberOfRows(Int_t row)
Definition: digit.h:407
void SetRadius(Double_t ra)
Definition: digit.h:421
Double_t rhoP
Definition: digit.h:920
void SetPadNumber(Int_t pad)
Definition: digit.h:212
Double_t GetSizeBeamShielding(void)
Definition: digit.h:444
void SetFinalTime(Double_t time)
Definition: digit.h:219
Double_t sigmaTransvAtPadPlane
Definition: digit.h:283
void SetZLength(Double_t z)
Definition: digit.h:416
Double_t padPlaneRadius
Definition: digit.h:1118
Bool_t GetOldChargeCalculation(void)
Definition: digit.h:1151
void SetRunID(Int_t id)
Definition: digit.h:224
void SetSideBlankSpaceX(Double_t gapx)
Definition: digit.h:419
Int_t padColumn
Definition: digit.h:176
driftManager()
Definition: digit.h:1165
Double_t timePre
Definition: digit.h:279
void SetYLength(Double_t y)
Definition: digit.h:415
Double_t driftVelocity
Definition: digit.h:1109
Int_t GetNumberOfRows(void)
Definition: digit.h:428
Double_t sizeBeamShielding
Definition: digit.h:359
void SetDiffusionParameters(Double_t lon, Double_t tra)
Definition: digit.h:1131
STL namespace.
Double_t GetMathiesonFactorK3P()
Definition: digit.h:955
amplificationManager * ampManager
Definition: digit.h:1106
void SetMathiesonFactorK1N(Double_t k1n)
Definition: digit.h:946
void SetPadsGeometry(void)
Definition: digit.h:498
Bool_t oldChargeCalculation
Definition: digit.h:1125
Int_t GetNumberOfPads(void)
Definition: digit.h:429
void SetEventID(Int_t id)
Definition: digit.h:223
void SetTimePre(Double_t time)
Definition: digit.h:307
void SetPost(TVector3 *ve)
Definition: digit.h:306
Int_t GetPadColumn()
Definition: digit.h:200
~ActarPadSignal()
Definition: digit.h:239
void GetStatus(void)
Definition: digit.h:1949
void SetPadType(Int_t type)
Definition: digit.h:410
Double_t GetYLength(void)
Definition: digit.h:436
Double_t lambdaP
Definition: digit.h:917
void SetSideBlankSpaceZ(Double_t gapz)
Definition: digit.h:420
void SetPadSize(Double_t si)
Definition: digit.h:412
Int_t GetPosition()
Definition: digit.h:302
void SetIsWireOn()
Definition: digit.h:926
Int_t eventID
Definition: digit.h:187
Double_t GetTransversalDiffusion(void)
Definition: digit.h:1146
void SetYPre(Double_t yc)
TVector3 CoordinatesCenterOfPad(Int_t pad)
Definition: digit.h:824
Int_t GetPadColumnFromXZValue(Double_t x, Double_t z)
Definition: digit.h:756
Double_t GetRHexagon(void)
Definition: digit.h:434
Double_t radiusOfAmpliWire
Definition: digit.h:912
void SetSigmaLongAtPadPlane(Double_t del)
Definition: digit.h:309
Double_t lorentzAngle
Definition: digit.h:1110
Double_t GetSigmaLongAtPadPlane()
Definition: digit.h:300
void SetPadRow(Int_t pad)
Definition: digit.h:213
Double_t GetZLength(void)
Definition: digit.h:437
virtual ~driftManager()
Definition: digit.h:1176
Double_t GetDeltaProximityBeam(void)
Definition: digit.h:443
Int_t GetPadRowFromXZValue(Double_t x, Double_t z)
Definition: digit.h:804
ActarSimSimpleTrack * GetTrack()
Definition: digit.h:295
Double_t finalTime
Definition: digit.h:182
void SetMagneticField(Double_t vel)
Definition: digit.h:1140
Double_t timePost
Definition: digit.h:280
Double_t GetRadiusOfAmpliWire()
Definition: digit.h:950
void SetDeltaProximityBeam(Double_t de)
Definition: digit.h:422
void SetEndCapModeOff()
Definition: digit.h:425
Double_t sigmaLongAtPadPlane
Definition: digit.h:282
Double_t sideBlankSpaceX
Definition: digit.h:355
void SetSizeBeamShielding(Double_t le)
Definition: digit.h:423
virtual ~amplificationManager()
Definition: digit.h:994
Double_t yBeamShift
Definition: digit.h:353
Double_t sideBlankSpaceZ
Definition: digit.h:356
Double_t GetPitchOfAmpliWire()
Definition: digit.h:951
void Reset(void)
Definition: digit.h:242
ActarSimSimpleTrack * track
Definition: digit.h:276
void SetPitchOfAmpliWire(Double_t s)
Definition: digit.h:941
void SetMathiesonFactorK1P(Double_t k1p)
Definition: digit.h:943
Int_t numberOfPads
Definition: digit.h:337
Int_t endCapMode
Definition: digit.h:361
void SetDriftVelocity(Double_t vel)
Definition: digit.h:1138
void SetSigmaTransvAtPadPlane(Double_t del)
Definition: digit.h:310
Int_t padType
Definition: digit.h:341
void SetLorentzAngle(Double_t vel)
Definition: digit.h:1139
Double_t GetMathiesonFactorK1N()
Definition: digit.h:956
Int_t geoType
Definition: digit.h:340
Double_t GetXBeamShift(void)
Definition: digit.h:438
TVector3 * post
Definition: digit.h:278
Int_t padRow
Definition: digit.h:175
Double_t GetSigmaTransvAtPadPlane()
Definition: digit.h:301
Double_t GetXLength(void)
Definition: digit.h:435
Int_t DIGI_DEBUG
Definition: digit.h:110
Int_t CalculatePositionAfterDrift(projectionOnPadPlane *pro)
Definition: digit.h:1230
void SetInitTime(Double_t time)
Definition: digit.h:218
Double_t GetMathiesonFactorK2N()
Definition: digit.h:957
TVector3 * GetPre()
Definition: digit.h:296
Double_t GetLorentzAngle(void)
Definition: digit.h:1148
void SetNumberOfPads(Int_t pad)
Definition: digit.h:408
Double_t chargeDeposited
Definition: digit.h:185
TVector3 * pre
Definition: digit.h:277
Double_t xLength
Definition: digit.h:348
void SetXBeamShift(Double_t xBeam)
Definition: digit.h:417
Double_t magneticField
Definition: digit.h:1112
ActarPadSignal()
Definition: digit.h:229
void SetZPost(Double_t zc)
void SetACseparation(Double_t h)
Definition: digit.h:942
Double_t GetInitTime()
Definition: digit.h:204
void SetDriftParameters(Double_t voltage, Double_t height, Double_t pressure, TString gasName)
Definition: digit.h:1179
void SetPre(TVector3 *ve)
Definition: digit.h:305
Double_t rHexagon
Definition: digit.h:345
Int_t GetRunID()
Definition: digit.h:210
Int_t numberOfStrides
Definition: digit.h:178
Double_t GetYBeamShift(void)
Definition: digit.h:439
Int_t GetGeoType(void)
Definition: digit.h:430
Double_t GetRadius(void)
Definition: digit.h:442
Double_t GetMathiesonFactorK2P()
Definition: digit.h:954
Int_t GetNumberOfStrides()
Definition: digit.h:202
Double_t sigmaTime
Definition: digit.h:183
Int_t GetEventID()
Definition: digit.h:209
Double_t GetMagneticField(void)
Definition: digit.h:1149
void SetTimePost(Double_t time)
Definition: digit.h:308
void SetOldChargeCalculation(void)
Definition: digit.h:1142
void SetPadLayout(Int_t layout)
Definition: digit.h:411
Float_t Polya(Float_t param=3.2)
Definition: digit.h:123
void SetChargeDeposited(Double_t cha)
Definition: digit.h:221
Double_t GetGasWvalue(void)
Definition: digit.h:1150
Int_t IsInPadNumber(TVector3 *point)
Definition: digit.h:614
TVector3 * GetPost()
Definition: digit.h:297
Double_t deltaProximityBeam
Definition: digit.h:358
void ConnectToGeometry(padsGeometry *pad)
Definition: digit.h:1155
Double_t yLength
Definition: digit.h:349
Double_t CalculateRhoP(Double_t x)
Definition: digit.h:960
void SetYBeamShift(Double_t yBeam)
Definition: digit.h:418
Double_t GetMathiesonFactorK1P()
Definition: digit.h:953
Int_t GetNumberOfColumns(void)
Definition: digit.h:427
Int_t CalculatePad(Int_t r, Int_t c)
Definition: digit.h:452
padsGeometry()
Definition: digit.h:482
void SetWireAmplificationParameters(Double_t ra, Double_t s, Double_t h)
Definition: digit.h:997
void SetPadColumn(Int_t pad)
Definition: digit.h:214
Double_t GetChargeDeposited()
Definition: digit.h:207
Double_t zLength
Definition: digit.h:350
Double_t GetTimePost()
Definition: digit.h:299
void SetNewChargeCalculation(void)
Definition: digit.h:1143
Double_t radius
Definition: digit.h:347
void CalculatePadsWithCharge(projectionOnPadPlane *pro, TClonesArray *clo, Int_t &numberOfPadsBeforeThisLoopStarted)
Definition: digit.h:1408
void SetYPost(Double_t yc)
Int_t numberOfRows
Definition: digit.h:336
Double_t GetDriftVelocity(void)
Definition: digit.h:1147
void ConnectToAmplificationManager(amplificationManager *amp)
Definition: digit.h:1156
virtual ~projectionOnPadPlane()
Definition: digit.h:324
void SetXLength(Double_t x)
Definition: digit.h:414
Double_t GetSideBlankSpaceX(void)
Definition: digit.h:440
Double_t GetTimePre()
Definition: digit.h:298
void SetMathiesonFactorK2N(Double_t k2n)
Definition: digit.h:947
void SetNumberOfStrides(Int_t num)
Definition: digit.h:216
void SetZPre(Double_t zc)
Double_t GetSideBlankSpaceZ(void)
Definition: digit.h:441
Double_t GetSigmaTime()
Definition: digit.h:206
Int_t padNumber
Definition: digit.h:174
void SetMathiesonFactorK3P(Double_t k3p)
Definition: digit.h:945
void SetMathiesonFactorK2P(Double_t k2p)
Definition: digit.h:944
Double_t GetPadSize(void)
Definition: digit.h:433
void SetGeometryValues(Int_t geo, Int_t pad, Int_t layout, Double_t x, Double_t y, Double_t z, Double_t xBeam, Double_t yBeam, Double_t ra, Double_t psi, Double_t gapx, Double_t gapz)
Definition: digit.h:370
padsGeometry * padsGeo
Definition: digit.h:1105
Int_t GetIsWire()
Definition: digit.h:934
Double_t ACseparation
Definition: digit.h:914
Int_t padLayout
Definition: digit.h:342
void SetTrack(ActarSimSimpleTrack *tr)
Definition: digit.h:304
void CalculatePadsWithCharge_oldStyle(Double_t k1p, Double_t k2p, Double_t k3p, Double_t k1n, Double_t k2n, Double_t k3n, projectionOnPadPlane *pro, TClonesArray *clo)
Definition: digit.h:1636
Int_t CalculateColumn(Int_t p)
Definition: digit.h:465
void SetNumberOfColumns(Int_t col)
Definition: digit.h:406
Double_t transversalDiffusion
Definition: digit.h:1108