Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4_TrkrSimulation.C
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4_TrkrSimulation.C
1 #ifndef MACRO_G4TRKRSIM_C
2 #define MACRO_G4TRKRSIM_C
3 
4 #include <GlobalVariables.C>
5 #include <G4_TrkrVariables.C>
6 #include <G4_ActsGeom.C>
7 
9 #include <g4mvtx/PHG4MvtxDefs.h>
11 #include <g4mvtx/PHG4MvtxHitReco.h>
13 
15 #include <g4intt/PHG4InttDefs.h>
17 #include <g4intt/PHG4InttHitReco.h>
19 
21 #include <g4tpc/PHG4TpcDigitizer.h>
26 #include <g4tpc/PHG4TpcPadPlane.h>
28 #include <g4tpc/PHG4TpcSubsystem.h>
29 
30 #pragma GCC diagnostic push
31 #pragma GCC diagnostic ignored "-Wundefined-internal"
33 #pragma GCC diagnostic pop
34 
38 
39 #include <g4main/PHG4Reco.h>
40 
41 #include <cmath>
42 #include <vector>
43 
44 R__LOAD_LIBRARY(libg4tpc.so)
45 R__LOAD_LIBRARY(libg4mvtx.so)
46 R__LOAD_LIBRARY(libg4intt.so)
47 R__LOAD_LIBRARY(libg4micromegas.so)
48 
49 void MvtxInit()
50 {
54 }
55 
56 double Mvtx(PHG4Reco* g4Reco, double radius,
57  const int supportactive = 0)
58 {
59  bool maps_overlapcheck = Enable::OVERLAPCHECK || Enable::MVTX_OVERLAPCHECK;
61  bool SupportActive = Enable::SUPPORT || Enable::MVTX_SUPPORT;
62 
63  PHG4MvtxSubsystem* mvtx = new PHG4MvtxSubsystem("MVTX");
64  mvtx->Verbosity(verbosity);
65 
66  for (int ilayer = 0; ilayer < G4MVTX::n_maps_layer; ilayer++)
67  {
68  double radius_lyr = PHG4MvtxDefs::mvtxdat[ilayer][PHG4MvtxDefs::kRmd];
69 // mvtx->set_double_param(ilayer, "layer_z_offset", G4MVTXAlignment::z_offset[ilayer]);
70  if (verbosity)
71  {
72  cout << "Create Maps layer " << ilayer << " with radius " << radius_lyr << " mm." << endl;
73  }
74  radius = radius_lyr / 10.;
75  }
76 // mvtx->set_string_param(PHG4MvtxDefs::GLOBAL, "alignment_path", G4MVTXAlignment::alignment_path);
77  mvtx->set_string_param(PHG4MvtxDefs::GLOBAL, "stave_geometry_file", string(getenv("CALIBRATIONROOT")) + string("/Tracking/geometry/mvtx_stave.gdml"));
78 
79  mvtx->SetActive();
80  if (SupportActive)
81  {
82  mvtx->SetSupportActive();
83  }
84  mvtx->OverlapCheck(maps_overlapcheck);
85  g4Reco->registerSubsystem(mvtx);
86  radius += G4MVTX::radius_offset;
87  return radius;
88 }
89 
90 void Mvtx_Cells()
91 {
94  // new storage containers
95  PHG4MvtxHitReco* maps_hits = new PHG4MvtxHitReco("MVTX");
96  maps_hits->Verbosity(verbosity);
97 
98  double maps_readout_window = 5000.0; // ns
99  double extended_readout_time = 0.0;
100  if(TRACKING::pp_mode) extended_readout_time = TRACKING::pp_extended_readout_time;
101  // override the default timing window - default is +/- 5000 ns
102  maps_hits->set_double_param("mvtx_tmin", -maps_readout_window);
103  maps_hits->set_double_param("mvtx_tmax", maps_readout_window + extended_readout_time);
104 
105  std::cout << "PHG4MvtxHitReco: readout window is from " << -maps_readout_window << " to " << maps_readout_window + extended_readout_time << std::endl;
106  se->registerSubsystem(maps_hits);
107 
108  PHG4MvtxDigitizer* digimvtx = new PHG4MvtxDigitizer();
109  digimvtx->Verbosity(verbosity);
110  // energy deposit in 25 microns = 9.6 KeV = 1000 electrons collected after recombination
111  //digimvtx->set_adc_scale(0.95e-6); // default set in code is 0.95e-06, which is 99 electrons
112  se->registerSubsystem(digimvtx);
113 
114  return;
115 }
116 
117 
118 void InttInit()
119 {
120  BlackHoleGeometry::max_radius = std::max(BlackHoleGeometry::max_radius, 20.); // estimated from display, can be made smaller but good enough
121  BlackHoleGeometry::max_z = std::max(BlackHoleGeometry::max_z, 410. / 2.);
123  // the mvtx is not called if disabled but the default number of layers is set to 3, so we need to set it
124  // to zero
125  if (!Enable::MVTX)
126  {
128  }
129 }
130 
131 double Intt(PHG4Reco* g4Reco, double radius,
132  const int absorberactive = 0)
133 {
135  bool intt_overlapcheck = Enable::OVERLAPCHECK || Enable::INTT_OVERLAPCHECK;
136 
137  // instantiate the INTT subsystem and register it
138  // We make one instance of PHG4INTTSubsystem for all four layers of tracker
139  // dimensions are in mm, angles are in radians
140 
141  // PHG4InttSubsystem creates the detetor layer using PHG4InttDetector
142  // and instantiates the appropriate PHG4SteppingAction
143 
144  // The length of vpair is used to determine the number of layers
145  std::vector<std::pair<int, int>> vpair; // (sphxlayer, inttlayer)
146  for (int i = 0; i < G4INTT::n_intt_layer; i++)
147  {
148  // We want the sPHENIX layer numbers for the Intt to be from n_maps_layer to n_maps_layer+n_intt_layer - 1
149  vpair.push_back(std::make_pair(G4MVTX::n_maps_layer + i, i)); // sphxlayer=n_maps_layer+i corresponding to inttlayer=i
150  if (verbosity) cout << "Create strip tracker layer " << vpair[i].second << " as sphenix layer " << vpair[i].first << endl;
151  }
152 
153  PHG4InttSubsystem* sitrack = new PHG4InttSubsystem("INTT", vpair);
154  sitrack->Verbosity(verbosity);
155  sitrack->SetActive(1);
156  sitrack->OverlapCheck(intt_overlapcheck);
158  {
159  sitrack->SetAbsorberActive();
160  }
162  {
163  sitrack->set_int_param(PHG4InttDefs::SUPPORTPARAMS, "supportactive", 1);
164  }
165  g4Reco->registerSubsystem(sitrack);
166 
167  // Set the laddertype and ladder spacing configuration
168 
169  cout << "Intt has " << G4INTT::n_intt_layer << " layers with layer setup:" << endl;
170  for (int i = 0; i < G4INTT::n_intt_layer; i++)
171  {
172  cout << " Intt layer " << i << " laddertype " << G4INTT::laddertype[i] << " nladders " << G4INTT::nladder[i]
173  << " sensor radius " << G4INTT::sensor_radius[i] << endl;
174  sitrack->set_int_param(i, "laddertype", G4INTT::laddertype[i]);
175  sitrack->set_int_param(i, "nladder", G4INTT::nladder[i]);
176  sitrack->set_double_param(i, "sensor_radius", G4INTT::sensor_radius[i]); // expecting cm
177  }
178 
179  // outer radius marker (translation back to cm)
180  radius = G4INTT::intt_radius_max * 0.1;
181  return radius;
182 }
183 
184 // Central detector cell reco is disabled as EIC setup use the fast tracking sim for now
186 {
189 
191  {
192  // Load pre-defined deadmaps
193  PHG4InttDeadMapLoader* deadMapINTT = new PHG4InttDeadMapLoader("INTT");
194 
195  for (int i = 0; i < G4INTT::n_intt_layer; i++)
196  {
197  string DeadMapConfigName = Form("intt_layer%d/", i);
198 
200  {
201  string DeadMapPath = string(getenv("CALIBRATIONROOT")) + string("/Tracking/INTT/DeadMap/");
202  //string DeadMapPath = "/sphenix/u/wxie/sphnx_software/INTT" + string("/DeadMap/");
203 
204  DeadMapPath += DeadMapConfigName;
205 
206  deadMapINTT->deadMapPath(G4MVTX::n_maps_layer + i, DeadMapPath);
207  }
208  else
209  {
210  cout << "G4_Intt.C - fatal error - invalid InttDeadMapOption = " << G4INTT::InttDeadMapOption << endl;
211  exit(1);
212  }
213  }
214 
215  deadMapINTT->Verbosity(verbosity);
216  //deadMapINTT -> Verbosity(1);
217  se->registerSubsystem(deadMapINTT);
218  }
219  // new storage containers
220  PHG4InttHitReco* reco = new PHG4InttHitReco();
221 
222  // The timing window defaults are set in the INTT ladder model, they can be overridden here
223  double extended_readout_time = 0.0;
224  if(TRACKING::pp_mode) extended_readout_time = TRACKING::pp_extended_readout_time;
225  reco->set_double_param("tmax", 80.0 + extended_readout_time);
226  reco->set_double_param("tmin", -20.0);
227  std::cout << "INTT readout window is set to -20 to " << 80.0 + extended_readout_time << std::endl;
228  reco->Verbosity(verbosity);
229  se->registerSubsystem(reco);
230 
231  // Intt digitization
232  //===========
233  // these should be used for the Intt
234  /*
235  How threshold are calculated based on default FPHX settings
236  Four part information goes to the threshold calculation:
237  1. In 320 um thick silicon, the MIP e-h pair for a nominally indenting tracking is 3.87 MeV/cm * 320 um / 3.62 eV/e-h = 3.4e4 e-h pairs
238  2. From DOI: 10.1016/j.nima.2014.04.017, FPHX integrator amplifier gain is 100mV / fC. That translate MIP voltage to 550 mV.
239  3. From [FPHX Final Design Document](https://www.phenix.bnl.gov/WWW/fvtx/DetectorHardware/FPHX/FPHX2_June2009Revision.doc), the DAC0-7 setting for 8-ADC thresholds above the V_ref, as in Table 2 - Register Addresses and Defaults
240  4, From [FPHX Final Design Document](https://www.phenix.bnl.gov/WWW/fvtx/DetectorHardware/FPHX/FPHX2_June2009Revision.doc) section Front-end Program Bits, the formula to translate DAC setting to comparitor voltages.
241  The result threshold table based on FPHX default value is as following
242  | FPHX Register Address | Name | Default value | Voltage - Vref (mV) | To electrons based on calibration | Electrons | Fraction to MIP |
243  |-----------------------|-----------------|---------------|---------------------|-----------------------------------|-----------|-----------------|
244  | 4 | Threshold DAC 0 | 8 | 32 | 2500 | 2000 | 5.85E-02 |
245  | 5 | Threshold DAC 1 | 16 | 64 | 5000 | 4000 | 1.17E-01 |
246  | 6 | Threshold DAC 2 | 32 | 128 | 10000 | 8000 | 2.34E-01 |
247  | 7 | Threshold DAC 3 | 48 | 192 | 15000 | 12000 | 3.51E-01 |
248  | 8 | Threshold DAC 4 | 80 | 320 | 25000 | 20000 | 5.85E-01 |
249  | 9 | Threshold DAC 5 | 112 | 448 | 35000 | 28000 | 8.18E-01 |
250  | 10 | Threshold DAC 6 | 144 | 576 | 45000 | 36000 | 1.05E+00 |
251  | 11 | Threshold DAC 7 | 176 | 704 | 55000 | 44000 | 1.29E+00 |
252  DAC0-7 threshold as fraction to MIP voltage are set to PHG4InttDigitizer::set_adc_scale as 3-bit ADC threshold as fractions to MIP energy deposition.
253  */
254  std::vector<double> userrange; // 3-bit ADC threshold relative to the mip_e at each layer.
255  userrange.push_back(0.0584625322997416);
256  userrange.push_back(0.116925064599483);
257  userrange.push_back(0.233850129198966);
258  userrange.push_back(0.35077519379845);
259  userrange.push_back(0.584625322997416);
260  userrange.push_back(0.818475452196383);
261  userrange.push_back(1.05232558139535);
262  userrange.push_back(1.28617571059432);
263 
264  // new containers
265  PHG4InttDigitizer* digiintt = new PHG4InttDigitizer();
266  digiintt->Verbosity(verbosity);
267  //digiintt->Verbosity(3);
268  for (int i = 0; i < G4INTT::n_intt_layer; i++)
269  {
270  digiintt->set_adc_scale(G4MVTX::n_maps_layer + i, userrange);
271  }
272  se->registerSubsystem(digiintt);
273 
274  return;
275 }
276 
277 void TPCInit()
278 {
279  std::cout << "G4_TrkrSimulation::TpcInit" << std::endl;
281 
282  if (Enable::TPC_ENDCAP)
283  {
286  }
287  else
288  {
289  BlackHoleGeometry::max_z = std::max(BlackHoleGeometry::max_z, 211. / 2.);
291  }
292 
293  // the mvtx is not called if disabled but the default number of layers is set to 3,
294  // so we need to set it to zero
295  if (!Enable::MVTX)
296  {
298  }
299  // same for the INTT
300  if (!Enable::INTT)
301  {
303  }
304 
305  // Set the (static) drift velocity in the cluster Z crossing correction module
307 }
308 
310 void TPC_Endcaps(PHG4Reco* g4Reco)
311 {
312  bool OverlapCheck = Enable::OVERLAPCHECK || Enable::TPC_OVERLAPCHECK;
313  bool AbsorberActive = Enable::ABSORBER || Enable::TPC_ABSORBER;
314 
315  PHG4TpcEndCapSubsystem* tpc_endcap = new PHG4TpcEndCapSubsystem("TPC_ENDCAP");
316  tpc_endcap->SuperDetector("TPC_ENDCAP");
317 
318  if (AbsorberActive) tpc_endcap->SetActive();
319  tpc_endcap->OverlapCheck(OverlapCheck);
320 
321  // tpc_endcap->set_int_param("construction_verbosity", 2);
322 
323  g4Reco->registerSubsystem(tpc_endcap);
324 
325  return;
326 }
327 
328 double TPC(PHG4Reco* g4Reco,
329  double radius)
330 {
331  std::cout << "G4_TrkrSimulation::TPC" << std::endl;
332  bool OverlapCheck = Enable::OVERLAPCHECK || Enable::TPC_OVERLAPCHECK;
333  bool AbsorberActive = Enable::ABSORBER || Enable::TPC_ABSORBER;
334 
335  PHG4TpcSubsystem* tpc = new PHG4TpcSubsystem("TPC");
336  tpc->SetActive();
337  tpc->SuperDetector("TPC");
338  tpc->set_double_param("steplimits", 1); // 1cm steps
339 
340  tpc->set_double_param("drift_velocity", G4TPC::tpc_drift_velocity_sim);
341  tpc->set_int_param("tpc_minlayer_inner", G4MVTX::n_maps_layer + G4INTT::n_intt_layer);
342  tpc->set_int_param("ntpc_layers_inner", G4TPC::n_tpc_layer_inner);
343  tpc->set_int_param("ntpc_phibins_inner", G4TPC::tpc_layer_rphi_count_inner);
344 
345  if (AbsorberActive)
346  {
347  tpc->SetAbsorberActive();
348  }
349 
350  double extended_readout_time = 0.0;
351  if(TRACKING::pp_mode)
352  {
353  extended_readout_time = TRACKING::pp_extended_readout_time;
354  }
355 
356  tpc->set_double_param("extended_readout_time", extended_readout_time);
357 
358  tpc->OverlapCheck(OverlapCheck);
359  g4Reco->registerSubsystem(tpc);
360 
361  if (Enable::TPC_ENDCAP)
362  {
363  TPC_Endcaps(g4Reco);
364  }
365 
366  radius = G4TPC::tpc_outer_radius;
367 
368  radius += no_overlapp;
369 
370  return radius;
371 }
372 
373 void TPC_Cells()
374 {
376  auto se = Fun4AllServer::instance();
377 
378  // central membrane G4Hit generation
380  {
381  auto centralMembrane = new PHG4TpcCentralMembrane;
382  centralMembrane->setCentralMembraneDelay(0);
383  centralMembrane->setCentralMembraneEventModulo(1);
384  se->registerSubsystem(centralMembrane);
385  }
386 
387  // direct laser G4Hit generation
389  {
390  auto directLaser = new PHG4TpcDirectLaser;
391 
392  // setup phi and theta steps
393  /* use 5deg steps */
394  static constexpr double deg_to_rad = M_PI/180.;
395  directLaser->SetPhiStepping( 144, 0*deg_to_rad, 360*deg_to_rad );
396  directLaser->SetThetaStepping( 36, 0*deg_to_rad, 90*deg_to_rad );
397  //directLaser->SetArbitraryThetaPhi(50*deg_to_rad, 145*deg_to_rad);
398  directLaser->SetDirectLaserAuto( true );
399  //__Variable stepping: hitting all of the central membrane____________
400  //directLaser->SetDirectLaserPatternfromFile( true );
401  //directLaser->SetFileStepping(13802);
402  //___________________________________________________________________
403 
404  directLaser->set_double_param("drift_velocity", G4TPC::tpc_drift_velocity_sim);
405  se->registerSubsystem(directLaser);
406  }
407 
408  //=========================
409  // setup Tpc readout for filling cells
410  // g4tpc/PHG4TpcElectronDrift uses
411  // g4tpc/PHG4TpcPadPlaneReadout
412  //=========================
413 
414  auto padplane = new PHG4TpcPadPlaneReadout;
415  padplane->Verbosity(verbosity);
416  double extended_readout_time = 0.0;
417  if(TRACKING::pp_mode) extended_readout_time = TRACKING::pp_extended_readout_time;
418  padplane->SetReadoutTime(extended_readout_time);
419 
420  auto edrift = new PHG4TpcElectronDrift;
421  edrift->Detector("TPC");
422  edrift->Verbosity(verbosity);
424  {
425  auto distortionMap = new PHG4TpcDistortion;
427  distortionMap->set_static_distortion_filename( G4TPC::static_distortion_filename );
428 
429  distortionMap->set_do_time_ordered_distortions( G4TPC::ENABLE_TIME_ORDERED_DISTORTIONS );
430  distortionMap->set_time_ordered_distortion_filename( G4TPC::time_ordered_distortion_filename );
431 
432  distortionMap->Init();
433  edrift->setTpcDistortion( distortionMap );
434  }
435 
436  double tpc_readout_time = 105.5/ G4TPC::tpc_drift_velocity_sim; // ns
437  edrift->set_double_param("max_time", tpc_readout_time);
438  edrift->set_double_param("extended_readout_time", extended_readout_time);
439  std::cout << "PHG4TpcElectronDrift readout window is from 0 to " << tpc_readout_time + extended_readout_time << std::endl;
440 
441  // override the default drift velocity parameter specification
442  edrift->set_double_param("drift_velocity", G4TPC::tpc_drift_velocity_sim);
443  padplane->SetDriftVelocity(G4TPC::tpc_drift_velocity_sim);
444 
445  // fudge factors to get drphi 150 microns (in mid and outer Tpc) and dz 500 microns cluster resolution
446  // They represent effects not due to ideal gas properties and ideal readout plane behavior
447  // defaults are 0.085 and 0.105, they can be changed here to get a different resolution
448 
449  edrift->registerPadPlane(padplane);
450  se->registerSubsystem(edrift);
451 
452  // Tpc digitizer
453  //=========
454  PHG4TpcDigitizer* digitpc = new PHG4TpcDigitizer();
456  double ENC = 670.0; // standard
457  digitpc->SetENC(ENC);
458  double ADC_threshold = 4.0 * ENC;
459  digitpc->SetADCThreshold(ADC_threshold); // 4 * ENC seems OK
460  digitpc->Verbosity(verbosity);
461  cout << " Tpc digitizer: Setting ENC to " << ENC << " ADC threshold to " << ADC_threshold
462  << " maps+Intt layers set to " << G4MVTX::n_maps_layer + G4INTT::n_intt_layer << endl;
463  digitpc ->set_skip_noise_flag(false);
464  se->registerSubsystem(digitpc);
465 
466 }
467 
469 {
470  if (!Enable::MVTX)
471  {
473  }
474  // same for the INTT
475  if (!Enable::INTT)
476  {
478  }
479  if (!Enable::TPC)
480  {
481  G4TPC::n_gas_layer = 0;
482  }
484  BlackHoleGeometry::max_z = std::max(BlackHoleGeometry::max_z, 220. / 2.);
486 }
487 
488 void Micromegas(PHG4Reco* g4Reco)
489 {
492  bool SupportActive = Enable::SUPPORT || Enable::MICROMEGAS_SUPPORT;
494  auto mm = new PHG4MicromegasSubsystem("MICROMEGAS", mm_layer);
495  mm->Verbosity(verbosity);
496  if (SupportActive)
497  {
498  mm->SetSupportActive();
499  }
500  mm->OverlapCheck(overlapcheck );
501  mm->SetActive();
502  g4Reco->registerSubsystem(mm);
503 }
504 
506 {
507 // the acts geometry needs to go here since it will be used by the PHG4MicromegasHitReco
509  auto se = Fun4AllServer::instance();
511  // micromegas
512  auto reco = new PHG4MicromegasHitReco;
513  reco->Verbosity(verbosity);
514  double extended_readout_time = 0.0;
515  if (TRACKING::pp_mode) extended_readout_time = TRACKING::pp_extended_readout_time;
516 
517  reco->set_double_param("micromegas_tmax", 800.0+extended_readout_time);
518  se->registerSubsystem(reco);
519 
520  se->registerSubsystem(new PHG4MicromegasDigitizer);
521 }
522 
523 #endif