StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StTrsWireHistogram.cc
1 /***************************************************************************
2  *
3  * $Id: StTrsWireHistogram.cc,v 1.33 2012/06/11 15:04:56 fisyak Exp $
4  *
5  * Author: brian, May 1998
6  ***************************************************************************
7  *
8  * Description: Collection of all StTrsMiniChargeSegment transported to
9  * the pad-plane
10  *
11  ***************************************************************************
12  *
13  * $Log: StTrsWireHistogram.cc,v $
14  * Revision 1.33 2012/06/11 15:04:56 fisyak
15  * std namespace
16  *
17  * Revision 1.32 2009/11/03 14:34:19 fisyak
18  * Remove default in zFromTB
19  *
20  * Revision 1.31 2005/12/12 21:00:12 perev
21  * 3 random generators ==> 1
22  *
23  * Revision 1.30 2004/04/07 18:57:25 perev
24  * Improve memory usage
25  *
26  * Revision 1.29 2003/12/24 13:44:54 fisyak
27  * Add (GEANT) track Id information in Trs; propagate it via St_tpcdaq_Maker; account interface change in StTrsZeroSuppressedReaded in StMixerMaker
28  *
29  * Revision 1.28 2003/12/17 18:22:01 fisyak
30  * mIoSectorSpacing has never been defined and this causes that Inner Sector has randomly been ejected
31  *
32  * Revision 1.27 2003/09/02 17:59:19 perev
33  * gcc 3.2 updates + WarnOff
34  *
35  * Revision 1.26 2003/04/30 20:39:09 perev
36  * Warnings cleanup. Modified lines marked VP
37  *
38  * Revision 1.25 2001/02/15 21:34:54 perev
39  * clear improved
40  *
41  * Revision 1.24 2000/08/07 22:44:39 perev
42  * srand48 added
43  *
44  * Revision 1.23 2000/08/04 03:32:18 long
45  * nQOnWire<12--->nQOnWire<6.5
46  * add "bin.sigmaT()+d[0]/12"
47  *
48  * Revision 1.22 2000/07/30 22:26:14 long
49  * nQOnWire<12-->nQOnWire<6.5
50  *
51  * Revision 1.21 2000/07/30 02:45:58 long
52  * 1)add random class
53  * 2)add erf look up table and table builder,EXB pull dx[],time delay dz[]
54  * OmegaTau
55  * 3)do Charge to wire assignment!!!
56  * 4)add polya distribution for single electron avalanch.
57  *
58  * Revision 1.20 2000/02/24 16:42:22 long
59  * StTrsWireBinEntry
60  * theNewSegment(position,0);--->
61  * StTrsWireBinEntry
62  * theNewSegment(position,0,bin.sigmaL(),bin.sigmaT());
63  *
64  * Revision 1.19 2000/01/10 23:14:31 lasiuk
65  * Include MACROS for compatiblity with SUN CC5
66  *
67  * Revision 1.18 1999/12/08 02:10:43 calderon
68  * Modified to eliminate warnings on Linux.
69  *
70  * Revision 1.17 1999/10/22 15:51:48 calderon
71  * Remove ifdefs for erf. Problem is solved by loading libm at the
72  * macro level.
73  *
74  * Revision 1.16 1999/10/22 00:00:15 calderon
75  * -added macro to use Erf instead of erf if we have HP and Root together.
76  * -constructor with char* for StTrsDedx so solaris doesn't complain
77  * -remove mZeros from StTrsDigitalSector. This causes several files to
78  * be modified to conform to the new data format, so only mData remains,
79  * access functions change and digitization procedure is different.
80  *
81  * Revision 1.15 1999/10/04 16:17:33 long
82  * wireCoordinate(kk)--> bin.position().y()
83  *
84  * Revision 1.14 1999/07/19 21:39:19 lasiuk
85  * - addEntry() distributes charge on a (user) settable range of wires
86  * - setRangeOfWiresForChargeDistribution(int) added (default is 0)
87  *
88  * Revision 1.13 1999/07/09 03:47:04 lasiuk
89  * add switch for singleElectron multiplication, gaussian random
90  * number generator
91  *
92  * Revision 1.12 1999/04/20 20:06:04 ward
93  * Protection against pointer error in StTrsWireHistogram::clear
94  *
95  * Revision 1.11 1999/04/07 00:49:05 lasiuk
96  * use the z offset for driftLength
97  *
98  * Revision 1.10 1999/02/16 23:40:32 lasiuk
99  * check clear/add entry
100  *
101  * Revision 1.9 1999/02/14 20:44:32 lasiuk
102  * gas gain settable via member function
103  * escape if min()<0
104  *
105  * Revision 1.8 1999/02/12 01:26:38 lasiuk
106  * Limit debug output
107  *
108  * Revision 1.7 1999/02/10 18:03:42 lasiuk
109  * gas gain manual setting
110  * debug output
111  *
112  * Revision 1.6 1999/02/10 04:28:29 lasiuk
113  * comment debug
114  *
115  * Revision 1.5 1999/01/18 20:59:39 lasiuk
116  * change gas gain 10^4
117  *
118  * Revision 1.4 1999/01/18 10:17:07 lasiuk
119  * distanceToWire
120  *
121  * Revision 1.3 1998/11/16 14:47:25 lasiuk
122  * use wireIndex to clarify name (not wireNumber)
123  * remove mLastWire, mLastEntry
124  *
125  * Revision 1.2 1998/11/13 21:32:38 lasiuk
126  * gains
127  *
128  * Revision 1.1 1998/11/10 17:12:28 fisyak
129  * Put Brian trs versin into StRoot
130  *
131  * Revision 1.5 1998/11/08 17:08:02 lasiuk
132  * change from boolean macros
133  * use resize() for LINUX/ allocators for SUN
134  * add typedefs for vector<> types
135  *
136  * Revision 1.4 1998/11/03 17:31:57 lasiuk
137  * incorporate gas gain/fluctuations
138  * add time delay of collection depending on charge position wrt wire position
139  * rename wire()
140  *
141  * Revision 1.3 1998/10/22 00:24:28 lasiuk
142  * Oct 22
143  *
144  * Revision 1.2 1998/06/30 22:48:58 lasiuk
145  * use db numbers; typecast yposition to wire position
146  *
147  * Revision 1.1 1998/06/04 23:31:58 lasiuk
148  * Initial Revision
149  *
150  **************************************************************************/
151 #include <algorithm>
152 #include <unistd.h> // sleep
153 
154 #ifndef ST_NO_EXCEPTIONS
155 # include <stdexcept>
156 # if !defined(ST_NO_NAMESPACES)
157  using std::range_error;
158 # endif
159 #endif
160 using std::min;
161 using std::max;
162 #include "SystemOfUnits.h"
163 #ifndef ST_NO_NAMESPACES
164 using namespace units;
165 #endif
166 #include "StTrsWireHistogram.hh"
167 #include "StTrsRandom.hh"
168 #include "TMath.h"
169 
170 StTrsWireHistogram* StTrsWireHistogram::mInstance = 0; // static data member
171 HepJamesRandom StTrsWireHistogram::mEngine;
172 RandGauss StTrsWireHistogram::mGaussianDistribution(mEngine);
173 RandExponential StTrsWireHistogram::mExponentialDistribution(mEngine);
174 
175 StTrsWireHistogram::StTrsWireHistogram(StTpcGeometry* geoDb, StTpcSlowControl* scDb, StTrsDeDx* gasDb,StMagneticField* mag)
176  : mMin(-1),
177  mMax(-1),
178  mGeomDb(geoDb),
179  mSCDb(scDb),
180  mGasDb(gasDb),
181  mDoGasGain(true),
182  mDoGasGainFluctuations(true),
183  mGasGainCalculationDone(false),
184  mDoSingleElectronMultiplication(false),
185  mDoTimeDelay(false),
186  mSectorWires(0)
187 
188 {
189  mSectorWires.reserve(10000);
190 //VP srand48(19460510);
191  random=&(StTrsRandom::inst());
192  mNumberOfEntriesInTable=4000;
193  mRangeOfTable=4.0;
194  mNumberOfInnerSectorAnodeWires =
195  mGeomDb->numberOfInnerSectorAnodeWires();
196  mNumberOfOuterSectorAnodeWires =
197  mGeomDb->numberOfOuterSectorAnodeWires();
198 
199  mTotalNumberOfAnodeWires =
200  mNumberOfInnerSectorAnodeWires + mNumberOfOuterSectorAnodeWires;
201  mSectorWires.resize(mTotalNumberOfAnodeWires);
202 // PR(mTotalNumberOfAnodeWires);
203 
204  gasGainCalculation();
205  mGasGainCalculationDone = true;
206  FreqFunctionTableBuilder();
207  mOmegaTau=2.34*mag->at(StThreeVector<double>(0,0,0)).z()/kilogauss/5.0;
208  dx[0]=mOmegaTau*0.14/::sqrt((1+mOmegaTau*mOmegaTau)*(1+mOmegaTau*mOmegaTau)*0.75+0.25);
209  dx[1]=mOmegaTau*0.04/::sqrt((1+mOmegaTau*mOmegaTau)*(1+mOmegaTau*mOmegaTau)*0.925+0.075);
210  dx[2]=-dx[1];
211  dx[3]=-dx[0];
212  dz[0]=0.08; //cm old 0.068cm
213  dz[1]=-0.08; //cm
214  dz[2]=-0.08; //cm
215  dz[3]=0.08; //cm
216 
217 
218 }
219 
220 StTrsWireHistogram::~StTrsWireHistogram() {/* nopt */}
221 
222 void StTrsWireHistogram::FreqFunctionTableBuilder()
223 {// erf(x)
224  int cntr=0;
225 
226 do {
227  Double_t x = 1.0*cntr*mRangeOfTable/mNumberOfEntriesInTable;
228  Double_t y = TMath::Erf(x);
229  mFreqFunctionTable.push_back(y);
230  cntr++;
231  }while(cntr < mNumberOfEntriesInTable);
232 
233 }
234 double StTrsWireHistogram::table_fast( double argument) const
235 {
236 
237 
238 
239 
240 
241  float a =argument/mRangeOfTable*mNumberOfEntriesInTable;
242  int index;
243  if(a>=0){
244  index = (int)(a+0.5);
245  if(index>=mNumberOfEntriesInTable)return 1.0;
246  return mFreqFunctionTable[index];}
247  else
248  {index = (int)(-a+0.5);
249  if(index>=mNumberOfEntriesInTable)return -1.0;
250  return -mFreqFunctionTable[index];}
251 }
252 
253 
254 
255 StTrsWireHistogram* StTrsWireHistogram::instance(StTpcGeometry* geoDb, StTpcSlowControl* scDb, StTrsDeDx* gasDb,StMagneticField *mag)
256 {
257  if(!mInstance) {
258  mInstance = new StTrsWireHistogram(geoDb, scDb, gasDb,mag);
259  }
260  else { // do nothing
261  std::cerr << "Cannot make a second instance of StTrsWireHistogram() " << endl;
262  std::cerr << "Continuing..." << endl;
263  }
264  return mInstance;
265 }
266 
267 void StTrsWireHistogram::addEntry(StTrsWireBinEntry& bin,int sector)
268 {
269  // also needs db information to create coordinate->wire map
270  // Find closes wire to: bin.position().y()
271  double Q=bin.numberOfElectrons();
272  double *d=bin.d();
273  double innerSectorBoundary = mGeomDb->firstOuterSectorAnodeWire() - 0.5*mGeomDb->anodeWirePitch();
274  // mGeomDb->outerSectorEdge() - mGeomDb->ioSectorSpacing(); mIoSectorSpacing has never been defined
275  double yCoordinateOfHit = random->Gaus(bin.position().y(),(bin.sigmaT()+d[1]/12)/::sqrt(Q));
276  double sigma=bin.sigmaT();
277  double D=mGeomDb->anodeWirePitch()/2.;
278 
279  double dy=d[1];
280 
281  // if(dy<=0.){cout<<" wrong in dySubsegment calculation..."<<dy<<" "<<bin.position().y()<<" "<<bin.position().x()<<" "<<bin.position().z()<<endl;
282  // return ;}
283  // dy=0.;
284  double yMax=yCoordinateOfHit+1.5*sigma+dy/2.0;
285  double yMin=yCoordinateOfHit-1.5*sigma-dy/2.0;
286  // double yMax=yCoordinateOfHit+3.0*sigma+dy/2.0;
287  // double yMin=yCoordinateOfHit-3.0*sigma-dy/2.0;
288 
289  int WireHigh,WireLow;
290  if(yCoordinateOfHit < innerSectorBoundary) { // in inner part of sector
291  WireHigh =
292  (int)((yMax - mGeomDb->firstInnerSectorAnodeWire())/mGeomDb->anodeWirePitch()+0.5);
293  WireLow =
294  (int)((yMin - mGeomDb->firstInnerSectorAnodeWire())/mGeomDb->anodeWirePitch() + .5);
295  WireHigh=min(mGeomDb->numberOfInnerSectorAnodeWires() - 1,WireHigh);
296  WireLow=max(1,WireLow);
297 
298 
299  }
300  else { // in outer part of sectortmpWireHigh =
301  WireHigh=(int)((yMax - mGeomDb->firstOuterSectorAnodeWire())/mGeomDb->anodeWirePitch() + .5);
302 
303  WireLow =(int)((yMin - mGeomDb->firstOuterSectorAnodeWire())/mGeomDb->anodeWirePitch() + .5);
304  WireHigh=min(mGeomDb->numberOfOuterSectorAnodeWires() - 1,WireHigh)+mGeomDb->numberOfInnerSectorAnodeWires();
305  WireLow=max(1,WireLow)+mGeomDb->numberOfInnerSectorAnodeWires();
306 
307  }
308 
309  int WireIndex,gWire;
310  double Prob;
311  double nQOnWire;
312  double y1,y2,y3,y4;
313 //VPunused double ax=0.;
314 //VPunused double az=0.;
315  double nQ=0;
316  int Qtotal=0;
317  D=D/4;
318  float w=0.1 ; // pitch of gating grid ;
319  for(WireIndex=WireLow;WireIndex<=WireHigh;WireIndex++)
320  {
321  for(gWire=-2;gWire<2;gWire++){
322 
323  y2=(wireCoordinate(WireIndex)+w*gWire+w/2+D+dy-yCoordinateOfHit)/sigma/M_SQRT2;
324  y1=(wireCoordinate(WireIndex)+w*gWire+w/2-D+dy-yCoordinateOfHit)/sigma/M_SQRT2;
325  y4=(wireCoordinate(WireIndex)+w*gWire+w/2+D-dy-yCoordinateOfHit)/sigma/M_SQRT2;
326  y3=(wireCoordinate(WireIndex)+w*gWire+w/2-D-dy-yCoordinateOfHit)/sigma/M_SQRT2;
327 
328 
329  // y2=(wireCoordinate(WireIndex)+w*gWire+D-yCoordinateOfHit)/sigma/M_SQRT2;
330  // y1=(wireCoordinate(WireIndex)+w*gWire-D-yCoordinateOfHit)/sigma/M_SQRT2;
331  Prob=y2*table_fast(y2)-y1*table_fast(y1)
332  -y4*table_fast(y4)+y3*table_fast(y3)
333  +1./::sqrt(M_PI)*(exp(-y2*y2)- exp(-y1*y1)
334  +exp(-y3*y3)- exp(-y4*y4));
335  Prob=Prob*sigma/dy/4.0*M_SQRT2;
336  // Prob=0.5*(table_fast(y2)-table_fast(y1));
337  nQOnWire= (int)(Prob* Q+0.5);
338  Qtotal+=(int)nQOnWire;
339  if( Qtotal> Q)nQOnWire--;
340 
341 
342  double newx,newz;
343 
344  if(nQOnWire>0){
345 
346 
347 
348  nQ+=nQOnWire;
349  // float unknown=0.02;
350  // newx=random->Gaus(bin.position().x(),bin.sigmaT()/::sqrt(nQOnWire)+unknown);
351  // cout<<bin.position().x()<<" "<<bin.sigmaT()<<" "<<nQOnWire<<" "<<bin.position().z()<<" "<<bin.sigmaL()<<endl;
352  // cin>>newx;
353  newx=random->Gaus(bin.position().x(),(bin.sigmaT()+d[0]/12)/::sqrt(nQOnWire));
354 
355  newz=random->Gaus(bin.position().z(),(bin.sigmaL()+d[2]/12)/::sqrt(nQOnWire));
356 
357  if(newz<0.)continue;
358  if(sector>12.5)newx+=dx[gWire+2];
359  else
360  newx-=dx[gWire+2];
361 
362 
363  newz+=dz[gWire+2];
364 
365  // ax=ax+newx*nQOnWire;
366  // az=az+newz*nQOnWire;
367  // newx=0;
368  // newz=100;
370  position(newx,
371  wireCoordinate(WireIndex),
372 
373  // bin.position().y(),
374  newz); //HL 04/25/00
375 
376 
377 
378 
379 
380  //
381  // Gas Gain
382  double avalancheFactor = nQOnWire;
383  if(mDoGasGain) {
384  if(nQOnWire<6.5)mDoSingleElectronMultiplication=1;
385  // mDoSingleElectronMultiplication=0;
386  if(mDoSingleElectronMultiplication) {
387  avalancheFactor =
388  // exponentialAvalanche(WireIndex,avalancheFactor );
389  polyaAvalanche(WireIndex,avalancheFactor );
390  }
391  else { // Do Gaussian scaling
392  avalancheFactor =
393  gaussianAvalanche(WireIndex, avalancheFactor);
394  }
395  } // end of gas gain
396 
397  if(avalancheFactor<0.5)continue;
399  theNewSegment(position,0,bin.sigmaL(),sigma,bin.d(),bin.id());
400  theNewSegment.setNumberOfElectrons((int)(avalancheFactor+0.5));
401 
402  // Time Delay
403  // Increase DriftLength Proportional to the Distance from the Wire
404  // Keeping in mind a 2mm shift is approximately .1 timebins
405  // This means 500 um is 2 mm!
406  // Currently a linear function is used, but a better profile
407  // can Probably be found with some study.
408 
409  if(mDoTimeDelay) {
410  double distanceToWire =
411  fabs(yCoordinateOfHit - wireCoordinate(WireIndex));
412  {
413 #ifndef ST_NO_NAMESPACES
414  using namespace units;
415 #endif
416  double increase = 250*micrometer/millimeter*distanceToWire;
417 
418  double oldDriftLength = bin.position().z();
419  theNewSegment.position().setZ((oldDriftLength+increase));
420  }
421  }
422 
423  //
424  // You had better convince yourself
425  // that this is really right!
426  //
427  // Change coordinate of the wire
428  // due to diffusion. Remember that this
429  // is not needed in the single electron
430  // limit! That is the reason for the
431  // strange scale factor! Must be done
432  // before the gas gain is calculated or
433  // the factor is ~1
434  //
435 // double ne = bin.numberOfElectrons()*chargeFraction;
436 // double scaledSigma = ::sqrt(fabs((ne-1)/ne)*sigma);
437 // double xPosition =
438 // mGaussianDistribution.shoot(theNewSegment.position().x(),
439 // (scaledSigma));
440 // theNewSegment.position().setX(xPosition);
441 
442  mSectorWires[WireIndex].push_back(theNewSegment);
443 
444  //
445  // Set the limits for the wire Histogram
446  if (mMin<0) mMin = WireIndex;
447  if (mMax<0) mMax = WireIndex;
448  if (mMin >WireIndex ) mMin = WireIndex;
449  if (mMax <WireIndex) mMax = WireIndex;
450 
451  } //endif nQ>0
452  } //loop over gWire
453  }// for loop over WireIndex
454 
455 
456 
457 
458 
459 }
460 
461 void StTrsWireHistogram::clear()
462 {
463 //VP for(int ii=mMin; ii<= mMax; ii++) {
464 //VP if(ii<0) continue; // Iwona and Herb, April 20 1999.
465 //VP mSectorWires[ii].clear();
466 //VP }
467 
468  int sz = mSectorWires.size();
469  mSectorWires.clear();
470  mSectorWires.resize(sz);
471  mMin = -1;
472  mMax = -1;
473 
474 }
475 
476 double StTrsWireHistogram::wireCoordinate(int index) const
477 {
478  double wireY = (index < mNumberOfInnerSectorAnodeWires) ?
479  mGeomDb->firstInnerSectorAnodeWire() + (index)*mGeomDb->anodeWirePitch() :
480  mGeomDb->firstOuterSectorAnodeWire() + (index-mGeomDb->numberOfInnerSectorAnodeWires())*mGeomDb->anodeWirePitch();
481  return wireY;
482 }
483 
484 //vector<StTrsWireBinEntry>&
485 aTpcWire& StTrsWireHistogram::getWire(int num)
486 {
487  if(num>=0 && num<mTotalNumberOfAnodeWires) {
488  return mSectorWires[num];
489  }
490  else {
491 #ifndef ST_NO_EXCEPTIONS
492  throw range_error("Bounds error in StTrsWireHistogram::wire()");
493 #else
494  std::cerr << "Bounds error...only " << mTotalNumberOfAnodeWires << " wires." << endl;
495  std::cerr << "Exitting..." << endl;
496  return mSectorWires[0]; // This is a sad/sad workaround for no exceptions!
497 #endif
498  }
499 }
500 
501 //vector<vector<StTrsWireBinEntry> >&
502 aTpcWirePlane& StTrsWireHistogram::getWireHistogram()
503 {
504  return mSectorWires;
505 }
506 
507 // void StTrsWireHistogram::putWire(int wNumber, vector<StTrsWireBinEntry>& wire)
508 // {
509 // if(wNumber>=0 && wNumber<mTotalNumberOfAnodeWires)
510 // mSectorWires[wNumber] = wire;
511 // else {
512 // #ifndef ST_NO_EXCEPTIONS
513 // throw range_error("StTrsWireHistogram::putWire() index error!");
514 // #else
515 // std::cerr << "StTrsWireHistogram::putWire() index error!" << endl;
516 // #endif
517 // }
518 // }
519 
520 void StTrsWireHistogram::setDoGasGainFluctuations(bool doIt)
521 {
522  // Make sure if you turn "on" fluctuations, that gas gain is on!
523  if(doIt && !mDoGasGain)
524  mDoGasGain = true;
525 
526  mDoGasGainFluctuations = doIt;
527 }
528 
529 // These two could be inline, but are only called once
530 // so Probably doesn't matter performance wise
531 void StTrsWireHistogram::setGasGainInnerSector(double v)
532 {
533  mInnerSectorGasGain = v;
534  cout << "Gas gain IS: " << mInnerSectorGasGain << endl;
535 }
536 
537 
538 void StTrsWireHistogram::setGasGainOuterSector(double v)
539 {
540  mOuterSectorGasGain = v;
541  cout << "Gas gain OS: " << mOuterSectorGasGain << endl;
542 }
543 
544 double StTrsWireHistogram::polya(){
545  double x,y;
546  do{
547  x=StTrsRandom::inst().Rndm()*8.0;
548  y=StTrsRandom::inst().Rndm();
549  }while(y>2.4395225*x*::sqrt(x)/exp(x));
550  return x;
551 }
552 
553 double StTrsWireHistogram::polyaAvalanche(int iWire, double numElec)
554 {
555  double gasGainFactor;
556  double electrons = 0;
557  double b=0.4;
558  mInnerSectorGasGain=3558;
559  // mOuterSectorGasGain=1315;
560  mOuterSectorGasGain=1310;
561  if(mDoGasGainFluctuations) {
562  int ctr = 0;
563  do {
564  gasGainFactor = polya();
565  electrons += gasGainFactor;
566  ctr++;
567  } while(ctr<numElec);
568 
569  electrons =(iWire < mNumberOfInnerSectorAnodeWires) ?
570  electrons*b*mInnerSectorGasGain:
571  electrons*b*mOuterSectorGasGain;
572  }
573  else {
574  electrons = (iWire < mNumberOfInnerSectorAnodeWires) ?
575  numElec*mInnerSectorGasGain :
576  numElec*mOuterSectorGasGain;
577  }
578  return electrons;
579 }
580 double StTrsWireHistogram::exponentialAvalanche(int iWire, double numElec)
581 {
582  double gasGainFactor;
583  double electrons = 0;
584  mInnerSectorGasGain=3558;
585 
586  mOuterSectorGasGain=1310;
587  if(mDoGasGainFluctuations) {
588  int ctr = 0;
589  do {
590  gasGainFactor = (iWire < mNumberOfInnerSectorAnodeWires) ?
591  mExponentialDistribution.shoot(mInnerSectorGasGain) :
592  mExponentialDistribution.shoot(mOuterSectorGasGain);
593  electrons += gasGainFactor;
594  ctr++;
595  } while(ctr<numElec);
596  }
597  else {
598  electrons = (iWire < mNumberOfInnerSectorAnodeWires) ?
599  numElec*mInnerSectorGasGain :
600  numElec*mOuterSectorGasGain;
601  }
602  return electrons;
603 }
604 
605 double StTrsWireHistogram::gaussianAvalanche(int iWire, double numElec)
606 {
607  //
608  // The fluctuation values (13%) should be set via the
609  // db or some macro call. For now we will keep them
610  // here
611 //VPunused double innerFluc;
612 //VPunused double outerFluc;
613  double b=0.4;
614  // mInnerSectorGasGain=2503;
615  mInnerSectorGasGain=3558;
616  // mOuterSectorGasGain=1315;
617  mOuterSectorGasGain=1310;
618  // mDoGasGainFluctuations=0;
619  if(mDoGasGainFluctuations)
620  return (iWire < mNumberOfInnerSectorAnodeWires) ?
621  mGaussianDistribution.shoot(mInnerSectorGasGain*numElec,mInnerSectorGasGain*::sqrt(numElec*b)):
622  mGaussianDistribution.shoot(mOuterSectorGasGain*numElec,mOuterSectorGasGain*::sqrt(numElec*b));
623 
624 
625  else
626  return (iWire < mNumberOfInnerSectorAnodeWires) ?
627  mInnerSectorGasGain*numElec:
628  mOuterSectorGasGain*numElec;
629 
630 
631 }
632 
633 
634 double StTrsWireHistogram::noFluctuations(int wireIndex) const
635 {
636  return (wireIndex<mNumberOfInnerSectorAnodeWires) ?
637  mInnerSectorGasGain : mOuterSectorGasGain;
638 }
639 
640 void StTrsWireHistogram::gasGainCalculation()
641 {
642  // do calculation here and use values from db
643  // For now use values from SN263
644  // mInnerSectorGasGain =
645  // exp(scDb->innerSectorGasGainb*(innerSectorAnodeVoltage-innerSectorGasGainVzero));
646  // mOuterSectorGasGain =
647  // exp(scDb->outerSectorGasGainb*(outerSectorAnodeVoltage-outerSectorGasGainVzero));
648 }