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 // Note: BBC new factors are calibrated by 2017 p+p runs
58 const short ADCBin = 4096;
59 
60 const float LightFactor[NPMT2] = {1., 1., 0.95, 0.92, 1., 1., 1., 1., 0.9, 0.96, 0.95, 1., 0.95, 0.97, 1., 1., // East small
61  0.33, 0.298, 0.25, 0.26, 0.22, 0.4, 0.24, 0.26, // East large
62  1.2, 0.9, 1., 0.6, 1., 1., 1.2, 1.2, 1.25, 0.4, 1., 1., 0.95, 0.95, 0.94, 0.95, // West small
63  0., 0.243, 0., 0.2, 0.24, 0.18, 0.19, 0.2}; // West large
64 
65 const float TileResolution[NPMT2] = {0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, // East small
66  0.6, 0.6, 0.4, 0.5, 0.5, 0.6, 0.4, 0.5, // East large
67  0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.5, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, // West small
68  0., 0.5, 0., 0.5, 0.6, 0.6, 0.4, 0.65}; // West large
69 
70 const float pC_per_ADCBins[NPMT2] = {0.03, 0.03, 0.033, 0.033, 0.03, 0.03, 0.022, 0.03, 0.021, 0.022, 0.024, 0.03, 0.024, 0.024, 0.025, 0.027, // East small
71  0.0226, 0.028, 0.021, 0.023, 0.014, 0.0125, 0.012, 0.0125, // East large
72  0.031, 0.03, 0.03, 0.018, 0.03, 0.03, 0.023, 0.024, 0.028, 0.005, 0.03, 0.03, 0.028, 0.023, 0.022, 0.028, // West small
73  0., 0.027, 0., 0.06, 0.013, 0.014, 0.0129, 0.02}; // West large
74 
75 const int shift_ADC0[NPMT2] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // East small
76  0, 0, 0, 0, -15, 0, -15, 0, // East large
77  0, 0, 0, 0, 0, 0, 0, 0, 0, -60, 0, 0, 0, 0, 0, 0, // West small
78  0, 0, 0, 0, -10, -7, -15, -10}; // West large
79 
80 //____________________________________________________________________________
81 
82 bool IsSmall(short iPMT)
83 {
85  if ( 0<=iPMT && iPMT<NPMTsmall1) return 1;
86  if ( NPMT1<=iPMT && iPMT<NPMT1+NPMTsmall1) return 1;
87  return 0;
88 }
89 
90 /*------------------------------------------------------------------------*/
91 class BbcTOF
92 {
97 private:
98  vector<float> Times;
99 
100 public:
101  BbcTOF():Times(vector<float>(NPMT2)){}; // NPMT1 !
102  ~BbcTOF(){};
103  void AddTOF(uint16_t ipmt, float time)
104  {
108  if (Times[ipmt]==0 || Times[ipmt]>time) {Times[ipmt]=time;}
109  }
110  float GetTOF(uint16_t ipmt)
111  {
113 
114  float tof = 0;
115  if (Times[ipmt]!=0.){ tof = Times[ipmt]+BbcRndm.Gaus(0.,BbcTimingRMS); }
116  return tof;
117  }
118  short GetTDC(uint16_t ipmt)
119  {
121  float T = this->GetTOF(ipmt);
122 
123  if (T<TDC0) {return 0;}
124  short N = (short)((T-TDC0)/s_perTDCbin);
125  if (N>=NTDCbins) {return NTDCbins-1;}
126  return N;
127  }
128 
129 };
130 /*------------------------------------------------------------------------*/
131 class BbcDE
132 {
138 private:
139  vector<float> dE;
140 
141 public:
142  BbcDE():dE(vector<float>(NPMT2)){};
143  ~BbcDE(){};
144  void AddDE(uint16_t ipmt, float de)
145  {
146  de *= LightFactor[ipmt];
147  dE[ipmt] += de;
148  }
149  float GetDE(uint16_t ipmt)
150  {
152  float PoissonMean = dE[ipmt]/dE_1MIP*NPhotoelectrons_1MIP;
153  short NPhotoelectrons = BbcRndm.Poisson(PoissonMean);
154  float Q = pC_per_Photoelectron*
155  (1+BbcRndm.Gaus(0.,TileResolution[ipmt]))*NPhotoelectrons;
156  return Q;
157  }
158  short GetADC(uint16_t ipmt)
159  {
161  float A = this->GetDE(ipmt);
162  short N = (short)(A/pC_per_ADCBins[ipmt] + shift_ADC0[ipmt]);
163  if (N>=ADCBin) {return ADCBin-1;}
164  if (N<0){return 0;}
165  return N;
166  }
167 };
168 //_____________________________________________________________________________
170 
178 {
181 }
182 
183 //_____________________________________________________________________________
185 
195 {
196  //
197 }
198 
199 
200 //_____________________________________________________________________________
203 {
226  // BBC tile BBC PMT number Comments/description
227  // -------- -------------- --------------------
228  for (short iew=1; iew<=2; iew++)
229  {
230  short EW = iew*1000; // for VID
231  // short EWshift = (iew-1)*NPMT1; if Akio numbered from West
232  short EWshift = (2-iew)*NPMT1; // for PMT
239  // 1 1 inner small hex tile, 12:00 pos'n 90 degrees
240  Geant2PMT[EW+113] = EWshift+1;
241  // 2 2 inner small hex tile, 2:00 pos'n 30 degrees
242  Geant2PMT[EW+123] = EWshift+2;
243  // 3 3 inner small hex tile, 4:00 pos'n -30 degrees
244  Geant2PMT[EW+133] = EWshift+3;
245  // 4 4 inner small hex tile, 6:00 pos'n -90 degrees
246  Geant2PMT[EW+143] = EWshift+4;
247  // 5 5 inner small hex tile, 8:00 pos'n -150 degrees
248  Geant2PMT[EW+153] = EWshift+5;
249  // 6 6 inner small hex tile, 10:00 pos'n 150 degrees
250  Geant2PMT[EW+163] = EWshift+6;
251  // 7 7 outer small hex tile, 11:00 pos'n 120 degrees
252  Geant2PMT[EW+111] = EWshift+7;
253  // 8 8 outer small hex tile, 12:00 pos'n 90 degrees
254  Geant2PMT[EW+112] = EWshift+8;
255  // 9 7 outer small hex tile, 1:00 pos'n 60 degrees
256  Geant2PMT[EW+121] = EWshift+7;
257  // 10 9 outer small hex tile, 2:00 pos'n 30 degrees
258  Geant2PMT[EW+122] = EWshift+9;
259  // 11 10 outer small hex tile, 3:00 pos'n 0 degrees
260  Geant2PMT[EW+131] = EWshift+10;
261  // 12 11 outer small hex tile, 4:00 pos'n -30 degrees
262  Geant2PMT[EW+132] = EWshift+11;
263  // 13 12 outer small hex tile, 5:00 pos'n -60 degrees
264  Geant2PMT[EW+141] = EWshift+12;
265  // 14 13 outer small hex tile, 6:00 pos'n -90 degrees
266  Geant2PMT[EW+142] = EWshift+13;
267  // 15 12 outer small hex tile, 7:00 pos'n -120 degrees
268  Geant2PMT[EW+151] = EWshift+12;
269  // 16 14 outer small hex tile, 8:00 pos'n -150 degrees
270  Geant2PMT[EW+152] = EWshift+14;
271  // 17 15 outer small hex tile, 9:00 pos'n 180 degrees
272  Geant2PMT[EW+161] = EWshift+15;
273  // 18 16 outer small hex tile, 10:00 pos'n 150 degrees
274  Geant2PMT[EW+162] = EWshift+16;
275 
276  // 19 17 inner large hex tile, 12:00 pos'n 90 degrees
277  Geant2PMT[EW+213] = EWshift+17;
278  // 20 18 inner large hex tile, 2:00 pos'n 30 degrees
279  Geant2PMT[EW+223] = EWshift+18;
280  // 21 18 inner large hex tile, 4:00 pos'n -30 degrees
281  Geant2PMT[EW+233] = EWshift+18;
282  // 22 19 inner large hex tile, 6:00 pos'n -90 degrees
283  Geant2PMT[EW+243] = EWshift+19;
284  // 23 20 inner large hex tile, 8:00 pos'n -150 degrees
285  Geant2PMT[EW+253] = EWshift+20;
286  // 24 20 inner large hex tile, 10:00 pos'n 150 degrees
287  Geant2PMT[EW+263] = EWshift+20;
288  // 25 21 outer large hex tile, 11:00 pos'n 120 degrees
289  Geant2PMT[EW+211] = EWshift+21;
290  // 26 21 outer large hex tile, 12:00 pos'n 90 degrees
291  Geant2PMT[EW+212] = EWshift+21;
292  // 27 21 outer large hex tile, 1:00 pos'n 60 degrees
293  Geant2PMT[EW+221] = EWshift+21;
294  // 28 22 outer large hex tile, 2:00 pos'n 30 degrees
295  Geant2PMT[EW+222] = EWshift+22;
296  // 29 22 outer large hex tile, 3:00 pos'n 0 degrees
297  Geant2PMT[EW+231] = EWshift+22;
298  // 30 22 outer large hex tile, 4:00 pos'n -30 degrees
299  Geant2PMT[EW+232] = EWshift+22;
300  // 31 23 outer large hex tile, 5:00 pos'n -60 degrees
301  Geant2PMT[EW+241] = EWshift+23;
302  // 32 23 outer large hex tile, 6:00 pos'n -90 degrees
303  Geant2PMT[EW+242] = EWshift+23;
304  // 33 23 outer large hex tile, 7:00 pos'n -120 degrees
305  Geant2PMT[EW+251] = EWshift+23;
306  // 34 24 outer large hex tile, 8:00 pos'n -150 degrees
307  Geant2PMT[EW+252] = EWshift+24;
308  // 35 24 outer large hex tile, 9:00 pos'n 180 degrees
309  Geant2PMT[EW+261] = EWshift+24;
310  // 36 24 outer large hex tile, 10:00 pos'n 150 degrees
311  Geant2PMT[EW+262] = EWshift+24;
312  }
313 
314  // Create Histograms
315 #ifdef BbcSimQa
316  QaFile = new TFile("StBbcSimQa.root","recreate");
317  QaBbcPmtdE = new TH1F("QaBbcPmtdE","BBC PMT",NPMT2,-0.5,NPMT2-0.5);
318  QaBbcPmtTime = new TH1F("QaBbcPmtTime","BBC PMT",NPMT2,-0.5,NPMT2-0.5);
319  QaBbcEastVid =
320  new TH1F("QaBbcEastVid","BBC PMT with East VID",256,-0.5,255.5);
321  QaBbcWestVid =
322  new TH1F("QaBbcWestVid","BBC PMT with West VID",256,-0.5,255.5);
323  QaBbcEastPmt =
324  new TH1F("QaBbcEastPmt","BBC PMT with East #", 256,-0.5,255.5);
325  QaBbcWestPmt =
326  new TH1F("QaBbcWestPmt","BBC PMT with West #", 256,-0.5,255.5);
327  // create a test map, reverse w.r.t. Geant2PMT
328  typedef map<short,short>::const_iterator CI;
329 
330  for (CI I=Geant2PMT.begin(); I!=Geant2PMT.end(); ++I)
331  {
332  PMT2Geant[(*I).second] = (*I).first;
333  }
334 #endif
335 
336  return StMaker::Init();
337 }
338 
339 //_____________________________________________________________________________
341 {
343 
344  TDataSet* ds= GetInputDS("geant");
345  assert(ds);
346  StEvent* event = (StEvent*)GetInputDS("StEvent");
347  assert(event);
348  St_g2t_ctf_hit* g2t_bbc_hit = (St_g2t_ctf_hit*)ds->Find("g2t_bbc_hit");
349 
350  if (g2t_bbc_hit)
351  {
352  short nBBChits = g2t_bbc_hit->GetNRows();
353  BbcTOF TOFdata;
354  BbcDE DEdata;
355  g2t_ctf_hit_st *bbc_hit = g2t_bbc_hit->GetTable();
356  for (short iBBChit=0; iBBChit<nBBChits; iBBChit++)
357  {
358  float De = bbc_hit[iBBChit].de;
359  float TOF = bbc_hit[iBBChit].tof;
360  short Vid = bbc_hit[iBBChit].volume_id;
361 
362  short PMTid = Geant2PMT[Vid];
363  if (PMTid == 0) {
364  LOG_ERROR << "Cannot find a PMTid in Geant2PMT for Vid = " << Vid << endm;
365  continue;
366  }
367  PMTid -= 1;
368  DEdata.AddDE(PMTid,De);
369  TOFdata.AddTOF(PMTid,TOF);
370  }
371 
372  StTriggerDetectorCollection* myTrig =event->triggerDetectorCollection();
373  if (!myTrig) {
374  Warning("Make"," NoStTriggerDetectorCollection, Make the new one\n");
375  myTrig = new StTriggerDetectorCollection;
376  event->setTriggerDetectorCollection(myTrig);
377  }
378  StBbcTriggerDetector& myBbc = myTrig->bbc();
379 
380 
381  for (uint16_t iPMT = 0; iPMT<NPMT2; iPMT++)
382  {
383  short ADC = DEdata.GetADC(iPMT);
384 #ifdef BbcSimQa
385  // QaBbcPmtAdc->Fill(iPMT,ADC);
386  short Vid = PMT2Geant[iPMT+1];
387 
388  if (Vid<2000) {QaBbcWestVid->Fill(ADC);}
389  if (Vid>2000) {QaBbcEastVid->Fill(ADC);}
390  if (iPMT<NPMT1) {QaBbcEastPmt->Fill(ADC);}
391  if (NPMT1<=iPMT && iPMT<NPMT2) {QaBbcWestPmt->Fill(ADC);}
392  QaBbcPmtTime->Fill(iPMT,TOFdata.GetTOF(iPMT));
393  QaBbcPmtdE->Fill(iPMT,DEdata.GetDE(iPMT));
394 #endif
395  myBbc.setAdc(iPMT, ADC);
396  if (IsSmall(iPMT))
397  {
398  short TDC = TOFdata.GetTDC(iPMT);
399  myBbc.setTdc(iPMT, TDC);
400  }
401  }
402  }
403 else
404  {
405  gMessMgr->Info
406  ("MLK StBbcSimulationMaker::Make() could not inst g2t_bbc_hit\n");
407  }
408 
409  return kStOK;
410 }
413 {
415 #ifdef BbcSimQa
416  QaFile->Write();
417  QaFile->Close();
418 #endif
419  return StMaker::Finish();
420 }
421 
422 
423 
424 
425 
426 
427 
428 
429 
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