StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StBbcSimulationMaker.cxx
1 
8 #include "StBbcSimulationMaker.h"
9 #include "g2t/St_g2t_bbc_Module.h"
10 #include "TDataSetIter.h"
11 #include "TRandom.h"
12 #include <vector>
13 #include "StEvent.h"
14 #include "StTriggerDetectorCollection.h"
15 #include "StBbcTriggerDetector.h"
16 #include "StMessMgr.h"
17 
18 TRandom BbcRndm = TRandom(0);
19 
20 ClassImp(StBbcSimulationMaker)
21 
22  const float BbcTimingRMS = 900.E-12;
29 const uint16_t NPMTsmall1 = 16;
30 const uint16_t NPMTlarge1 = 8;
31 const uint16_t NPMT1 = NPMTsmall1+NPMTlarge1;//# of PMTs on one side (East/West)
32 const uint16_t NPMT2 = 2*NPMT1; // ditto on both sides
33 const float dE1MIPper_gcm2 = 1.95E-3; // in GeV/(g/cm**2), for polystyrene
34 const float PolystereneDensity = 1.032; // in g/cm**3
35 const float TyleThickness = 1.; // in cm
36 const float dE_1MIP = dE1MIPper_gcm2*PolystereneDensity*TyleThickness;
37 const float NPhotoelectrons_1MIP = 15.;
38 const float pC_per_Photoelectron = 0.3;
39 const short NADCbins = 256; /* bins are numbered from 0 to 255 */
40 const short NTDCbins = 256; /* ditto */
41 const float pC_perADCbin = 0.25; /* Central trigger barrel
42  Digitizer Boards (CDB) have such
43  conversion gain (see STAR NIM) */
44 const float ADC0 = 0.; /* beginning of ADC range */
45 const float s_perTDCbin = .1E-9; /* so that 25.6 ns is full range (guess) */
46 const float TDC0 = 0.; /* beginning of TDC range */
47 const float OuterFactor = 0.8; /* larger scintillators of the outer ring
48  have less light output by this factor,
49  compared with the inner ring, per
50  equal ionization */
51 const float SinglePhotoElectronResolution = 0.3; // according to Les Bland
52 /* Numbering: the real PMT numbering (used in the map) starts from 1.
53 ALL OTHERS start from 0 !
54  */
55 //____________________________________________________________________________
56 
57 bool IsSmall(short iPMT)
58 {
60  if ( 0<=iPMT && iPMT<NPMTsmall1) return 1;
61  if ( NPMT1<=iPMT && iPMT<NPMT1+NPMTsmall1) return 1;
62  return 0;
63 }
64 
65 /*------------------------------------------------------------------------*/
66 class BbcTOF
67 {
72 private:
73  vector<float> Times;
74 
75 public:
76  BbcTOF():Times(vector<float>(NPMT2)){}; // NPMT1 !
77  ~BbcTOF(){};
78  void AddTOF(uint16_t ipmt, float time)
79  {
83  if (Times[ipmt]==0 || Times[ipmt]>time) {Times[ipmt]=time;}
84  }
85  float GetTOF(uint16_t ipmt)
86  {
88 
89  float tof = 0;
90  if (Times[ipmt]!=0.){ tof = Times[ipmt]+BbcRndm.Gaus(0.,BbcTimingRMS); }
91  return tof;
92  }
93  short GetTDC(uint16_t ipmt)
94  {
96  float T = this->GetTOF(ipmt);
97 
98  if (T<TDC0) {return 0;}
99  short N = (short)((T-TDC0)/s_perTDCbin);
100  if (N>=NTDCbins) {return NTDCbins-1;}
101  return N;
102  }
103 
104 };
105 /*------------------------------------------------------------------------*/
106 class BbcDE
107 {
113 private:
114  vector<float> dE;
115 
116 public:
117  BbcDE():dE(vector<float>(NPMT2)){};
118  ~BbcDE(){};
119  void AddDE(uint16_t ipmt, float de)
120  {
121  if (!IsSmall(ipmt)) {de *= OuterFactor;}
122  dE[ipmt] += de;
123  }
124  float GetDE(uint16_t ipmt)
125  {
127 
128  float PoissonMean = dE[ipmt]/dE_1MIP*NPhotoelectrons_1MIP;
129  short NPhotoelectrons = BbcRndm.Poisson(PoissonMean);
130  float Q = pC_per_Photoelectron*
131  (1+BbcRndm.Gaus(0.,SinglePhotoElectronResolution))*
132  NPhotoelectrons;
133  return Q;
134  }
135  short GetADC(uint16_t ipmt)
136  {
138  float A = this->GetDE(ipmt);
139  if (A<ADC0) {return 0;}
140  short N = (short)((A-ADC0)/pC_perADCbin);
141  if (N>=NADCbins) {return NADCbins-1;}
142  return N;
143  }
144 };
145 //_____________________________________________________________________________
147 
155 {
158 }
159 
160 //_____________________________________________________________________________
162 
172 {
173  //
174 }
175 
176 
177 //_____________________________________________________________________________
180 {
203  // BBC tile BBC PMT number Comments/description
204  // -------- -------------- --------------------
205  for (short iew=1; iew<=2; iew++)
206  {
207  short EW = iew*1000; // for VID
208  // short EWshift = (iew-1)*NPMT1; if Akio numbered from West
209  short EWshift = (2-iew)*NPMT1; // for PMT
216  // 1 1 inner small hex tile, 12:00 pos'n 90 degrees
217  Geant2PMT[EW+113] = EWshift+1;
218  // 2 2 inner small hex tile, 2:00 pos'n 30 degrees
219  Geant2PMT[EW+123] = EWshift+2;
220  // 3 3 inner small hex tile, 4:00 pos'n -30 degrees
221  Geant2PMT[EW+133] = EWshift+3;
222  // 4 4 inner small hex tile, 6:00 pos'n -90 degrees
223  Geant2PMT[EW+143] = EWshift+4;
224  // 5 5 inner small hex tile, 8:00 pos'n -150 degrees
225  Geant2PMT[EW+153] = EWshift+5;
226  // 6 6 inner small hex tile, 10:00 pos'n 150 degrees
227  Geant2PMT[EW+163] = EWshift+6;
228  // 7 7 outer small hex tile, 11:00 pos'n 120 degrees
229  Geant2PMT[EW+111] = EWshift+7;
230  // 8 8 outer small hex tile, 12:00 pos'n 90 degrees
231  Geant2PMT[EW+112] = EWshift+8;
232  // 9 7 outer small hex tile, 1:00 pos'n 60 degrees
233  Geant2PMT[EW+121] = EWshift+7;
234  // 10 9 outer small hex tile, 2:00 pos'n 30 degrees
235  Geant2PMT[EW+122] = EWshift+9;
236  // 11 10 outer small hex tile, 3:00 pos'n 0 degrees
237  Geant2PMT[EW+131] = EWshift+10;
238  // 12 11 outer small hex tile, 4:00 pos'n -30 degrees
239  Geant2PMT[EW+132] = EWshift+11;
240  // 13 12 outer small hex tile, 5:00 pos'n -60 degrees
241  Geant2PMT[EW+141] = EWshift+12;
242  // 14 13 outer small hex tile, 6:00 pos'n -90 degrees
243  Geant2PMT[EW+142] = EWshift+13;
244  // 15 12 outer small hex tile, 7:00 pos'n -120 degrees
245  Geant2PMT[EW+151] = EWshift+12;
246  // 16 14 outer small hex tile, 8:00 pos'n -150 degrees
247  Geant2PMT[EW+152] = EWshift+14;
248  // 17 15 outer small hex tile, 9:00 pos'n 180 degrees
249  Geant2PMT[EW+161] = EWshift+15;
250  // 18 16 outer small hex tile, 10:00 pos'n 150 degrees
251  Geant2PMT[EW+162] = EWshift+16;
252 
253  // 19 17 inner large hex tile, 12:00 pos'n 90 degrees
254  Geant2PMT[EW+213] = EWshift+17;
255  // 20 18 inner large hex tile, 2:00 pos'n 30 degrees
256  Geant2PMT[EW+223] = EWshift+18;
257  // 21 18 inner large hex tile, 4:00 pos'n -30 degrees
258  Geant2PMT[EW+233] = EWshift+18;
259  // 22 19 inner large hex tile, 6:00 pos'n -90 degrees
260  Geant2PMT[EW+243] = EWshift+19;
261  // 23 20 inner large hex tile, 8:00 pos'n -150 degrees
262  Geant2PMT[EW+253] = EWshift+20;
263  // 24 20 inner large hex tile, 10:00 pos'n 150 degrees
264  Geant2PMT[EW+263] = EWshift+20;
265  // 25 21 outer large hex tile, 11:00 pos'n 120 degrees
266  Geant2PMT[EW+211] = EWshift+21;
267  // 26 21 outer large hex tile, 12:00 pos'n 90 degrees
268  Geant2PMT[EW+212] = EWshift+21;
269  // 27 21 outer large hex tile, 1:00 pos'n 60 degrees
270  Geant2PMT[EW+221] = EWshift+21;
271  // 28 22 outer large hex tile, 2:00 pos'n 30 degrees
272  Geant2PMT[EW+222] = EWshift+22;
273  // 29 22 outer large hex tile, 3:00 pos'n 0 degrees
274  Geant2PMT[EW+231] = EWshift+22;
275  // 30 22 outer large hex tile, 4:00 pos'n -30 degrees
276  Geant2PMT[EW+232] = EWshift+22;
277  // 31 23 outer large hex tile, 5:00 pos'n -60 degrees
278  Geant2PMT[EW+241] = EWshift+23;
279  // 32 23 outer large hex tile, 6:00 pos'n -90 degrees
280  Geant2PMT[EW+242] = EWshift+23;
281  // 33 23 outer large hex tile, 7:00 pos'n -120 degrees
282  Geant2PMT[EW+251] = EWshift+23;
283  // 34 24 outer large hex tile, 8:00 pos'n -150 degrees
284  Geant2PMT[EW+252] = EWshift+24;
285  // 35 24 outer large hex tile, 9:00 pos'n 180 degrees
286  Geant2PMT[EW+261] = EWshift+24;
287  // 36 24 outer large hex tile, 10:00 pos'n 150 degrees
288  Geant2PMT[EW+262] = EWshift+24;
289  }
290 
291  // Create Histograms
292 #ifdef BbcSimQa
293  QaFile = new TFile("StBbcSimQa.root","recreate");
294  QaBbcPmtdE = new TH1F("QaBbcPmtdE","BBC PMT",NPMT2,-0.5,NPMT2-0.5);
295  QaBbcPmtTime = new TH1F("QaBbcPmtTime","BBC PMT",NPMT2,-0.5,NPMT2-0.5);
296  QaBbcEastVid =
297  new TH1F("QaBbcEastVid","BBC PMT with East VID",256,-0.5,255.5);
298  QaBbcWestVid =
299  new TH1F("QaBbcWestVid","BBC PMT with West VID",256,-0.5,255.5);
300  QaBbcEastPmt =
301  new TH1F("QaBbcEastPmt","BBC PMT with East #", 256,-0.5,255.5);
302  QaBbcWestPmt =
303  new TH1F("QaBbcWestPmt","BBC PMT with West #", 256,-0.5,255.5);
304  // create a test map, reverse w.r.t. Geant2PMT
305  typedef map<short,short>::const_iterator CI;
306 
307  for (CI I=Geant2PMT.begin(); I!=Geant2PMT.end(); ++I)
308  {
309  PMT2Geant[(*I).second] = (*I).first;
310  }
311 #endif
312 
313  return StMaker::Init();
314 }
315 
316 //_____________________________________________________________________________
318 {
320 
321  TDataSet* ds= GetInputDS("geant");
322  assert(ds);
323  StEvent* event = (StEvent*)GetInputDS("StEvent");
324  assert(event);
325  St_g2t_ctf_hit* g2t_bbc_hit = (St_g2t_ctf_hit*)ds->Find("g2t_bbc_hit");
326 
327  if (g2t_bbc_hit)
328  {
329  short nBBChits = g2t_bbc_hit->GetNRows();
330  BbcTOF TOFdata;
331  BbcDE DEdata;
332  g2t_ctf_hit_st *bbc_hit = g2t_bbc_hit->GetTable();
333  for (short iBBChit=0; iBBChit<nBBChits; iBBChit++)
334  {
335  float De = bbc_hit[iBBChit].de;
336  float TOF = bbc_hit[iBBChit].tof;
337  short Vid = bbc_hit[iBBChit].volume_id;
338 
339  short PMTid = Geant2PMT[Vid];
340  if (PMTid == 0) {
341  LOG_ERROR << "Cannot find a PMTid in Geant2PMT for Vid = " << Vid << endm;
342  continue;
343  }
344  PMTid -= 1;
345  DEdata.AddDE(PMTid,De);
346  TOFdata.AddTOF(PMTid,TOF);
347  }
348 
349  StTriggerDetectorCollection* myTrig =event->triggerDetectorCollection();
350  if (!myTrig) {
351  Warning("Make"," NoStTriggerDetectorCollection, Make the new one\n");
352  myTrig = new StTriggerDetectorCollection;
353  event->setTriggerDetectorCollection(myTrig);
354  }
355  StBbcTriggerDetector& myBbc = myTrig->bbc();
356 
357 
358  for (uint16_t iPMT = 0; iPMT<NPMT2; iPMT++)
359  {
360  short ADC = DEdata.GetADC(iPMT);
361 #ifdef BbcSimQa
362  // QaBbcPmtAdc->Fill(iPMT,ADC);
363  short Vid = PMT2Geant[iPMT+1];
364 
365  if (Vid<2000) {QaBbcWestVid->Fill(ADC);}
366  if (Vid>2000) {QaBbcEastVid->Fill(ADC);}
367  if (iPMT<NPMT1) {QaBbcEastPmt->Fill(ADC);}
368  if (NPMT1<=iPMT && iPMT<NPMT2) {QaBbcWestPmt->Fill(ADC);}
369  QaBbcPmtTime->Fill(iPMT,TOFdata.GetTOF(iPMT));
370  QaBbcPmtdE->Fill(iPMT,DEdata.GetDE(iPMT));
371 #endif
372  myBbc.setAdc(iPMT, ADC);
373  if (IsSmall(iPMT))
374  {
375  short TDC = TOFdata.GetTDC(iPMT);
376  myBbc.setTdc(iPMT, TDC);
377  }
378  }
379  }
380 else
381  {
382  gMessMgr->Info
383  ("MLK StBbcSimulationMaker::Make() could not inst g2t_bbc_hit\n");
384  }
385 
386  return kStOK;
387 }
390 {
392 #ifdef BbcSimQa
393  QaFile->Write();
394  QaFile->Close();
395 #endif
396  return StMaker::Finish();
397 }
398 
399 
400 
401 
402 
403 
404 
405 
406 
virtual Int_t Init()
Init - is a first method the top level StChain calls to initialize all its makers.
void AddTOF(uint16_t ipmt, float time)
short GetTDC(uint16_t ipmt)
virtual ~StBbcSimulationMaker()
This is BbcSimulation destructor.
Definition: tof.h:15
StBbcSimulationMaker(const char *name="BbcSimulation")
BbcSimulation constructor.
short GetADC(uint16_t ipmt)
Definition: Stypes.h:40
virtual Int_t Finish()
Definition: StMaker.cxx:776
float GetTOF(uint16_t ipmt)
float GetDE(uint16_t ipmt)
virtual TDataSet * Find(const char *path) const
Definition: TDataSet.cxx:362