File indexing completed on 2025-08-05 08:13:34
0001 #include <vector>
0002
0003
0004
0005
0006 bool use_primary_vertex = false;
0007
0008 const int n_maps_layer = 3;
0009 const int n_intt_layer = 4;
0010 int n_gas_layer = 40;
0011
0012 double inner_cage_radius = 20.;
0013
0014
0015
0016
0017 double TPCDriftVelocity = 3.0 / 1000.0;
0018 double TPCShapingRMSLead = 32.0;
0019 double TPCShapingRMSTail = 48.0;
0020 double TPCADCClock = 53.0;
0021
0022 double tpc_cell_x = 0.15;
0023 double tpc_cell_y = TPCADCClock * TPCDriftVelocity;
0024
0025 int Max_si_layer;
0026
0027 void SvtxInit(int n_TPC_layers = 40, int verbosity = 0)
0028 {
0029 n_gas_layer = n_TPC_layers;
0030 Max_si_layer = n_maps_layer + n_intt_layer + n_gas_layer;
0031 }
0032
0033 double Svtx(PHG4Reco* g4Reco, double radius,
0034 const int absorberactive = 0,
0035 int verbosity = 0) {
0036
0037 if(n_maps_layer > 0)
0038 {
0039 bool maps_overlapcheck = false;
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 double maps_layer_radius[3] = {23.4, 31.5, 39.3};
0056
0057
0058
0059
0060 int stave_type[3] = {0, 0, 0};
0061 int staves_in_layer[3] = {12, 16, 20};
0062 double phi_tilt[3] = {0.304, 0.304, 0.304};
0063
0064 for (int ilayer = 0; ilayer < n_maps_layer; ilayer++)
0065 {
0066 if (verbosity)
0067 cout << "Create Maps layer " << ilayer << " with radius " << maps_layer_radius[ilayer] << " mm, stave type " << stave_type[ilayer]
0068 << " pixel size 30 x 30 microns " << " active pixel thickness 0.0018 microns" << endl;
0069
0070 PHG4MapsSubsystem *lyr = new PHG4MapsSubsystem("MAPS", ilayer, stave_type[ilayer]);
0071 lyr->Verbosity(verbosity);
0072
0073 lyr->set_double_param("layer_nominal_radius",maps_layer_radius[ilayer]);
0074 lyr->set_int_param("N_staves", staves_in_layer[ilayer]);
0075
0076
0077 lyr->set_double_param("pixel_x",0.0030);
0078 lyr->set_double_param("pixel_z",0.0030);
0079 lyr->set_double_param("pixel_thickness",0.0018);
0080 lyr->set_double_param("phitilt", phi_tilt[ilayer]);
0081
0082 lyr->set_int_param("active",1);
0083 lyr->OverlapCheck(maps_overlapcheck);
0084
0085 lyr->set_string_param("stave_geometry_file",
0086 string(getenv("CALIBRATIONROOT")) + string("/Tracking/geometry/ALICE_ITS_tgeo.gdml"));
0087
0088 g4Reco->registerSubsystem( lyr );
0089
0090 radius = maps_layer_radius[ilayer];
0091 }
0092 }
0093
0094 if(n_intt_layer > 0)
0095 {
0096
0097
0098
0099
0100 bool intt_overlapcheck = false;
0101
0102
0103
0104
0105
0106
0107
0108 const double intt_radius_max = 140.;
0109
0110
0111 std::vector<std::pair<int, int>> vpair;
0112 for(int i=0;i<n_intt_layer;i++)
0113 {
0114
0115 vpair.push_back(std::make_pair(n_maps_layer+i, i));
0116 if (verbosity) cout << "Create strip tracker layer " << vpair[i].second << " as sphenix layer " << vpair[i].first << endl;
0117 }
0118 PHG4SiliconTrackerSubsystem *sitrack = new PHG4SiliconTrackerSubsystem("SILICON_TRACKER", vpair);
0119 sitrack->Verbosity(verbosity);
0120 sitrack->SetActive(1);
0121 sitrack->OverlapCheck(intt_overlapcheck);
0122 g4Reco->registerSubsystem( sitrack);
0123
0124
0125 radius = intt_radius_max*0.1;
0126 }
0127
0128
0129
0130 PHG4CylinderSubsystem *cyl;
0131
0132 radius = inner_cage_radius;
0133
0134 double cage_length = 211.0;
0135 double n_rad_length_cage = 1.13e-02;
0136 double cage_thickness = 28.6 * n_rad_length_cage;
0137
0138
0139 cyl = new PHG4CylinderSubsystem("SVTXSUPPORT", n_maps_layer + n_intt_layer);
0140 cyl->set_double_param("radius",radius);
0141 cyl->set_int_param("lengthviarapidity",0);
0142 cyl->set_double_param("length",cage_length);
0143 cyl->set_string_param("material","G4_KAPTON");
0144 cyl->set_double_param("thickness",cage_thickness );
0145 cyl->SuperDetector("SVTXSUPPORT");
0146 cyl->Verbosity(0);
0147 g4Reco->registerSubsystem( cyl );
0148
0149 radius += cage_thickness;
0150
0151 double inner_readout_radius = 30.;
0152 if (inner_readout_radius<radius) inner_readout_radius = radius;
0153
0154 string tpcgas = "sPHENIX_TPC_Gas";
0155
0156
0157 if (inner_readout_radius - radius > 0) {
0158 cyl = new PHG4CylinderSubsystem("SVTXSUPPORT", n_maps_layer + n_intt_layer + 1);
0159 cyl->set_double_param("radius",radius);
0160 cyl->set_int_param("lengthviarapidity",0);
0161 cyl->set_double_param("length",cage_length);
0162 cyl->set_string_param("material",tpcgas.c_str());
0163 cyl->set_double_param("thickness", inner_readout_radius - radius);
0164 cyl->SuperDetector("SVTXSUPPORT");
0165 g4Reco->registerSubsystem( cyl );
0166 }
0167
0168 radius = inner_readout_radius;
0169
0170 double outer_radius = 78.;
0171 int npoints = Max_si_layer - n_maps_layer - n_intt_layer;
0172 double delta_radius = ( outer_radius - inner_readout_radius )/( (double)npoints );
0173
0174 for(int ilayer=n_maps_layer + n_intt_layer;ilayer<(n_maps_layer + n_intt_layer + npoints);++ilayer) {
0175
0176 if (verbosity)
0177 cout << "Create TPC gas layer " << ilayer << " with radius " << radius << " cm "
0178 << " thickness " << delta_radius - 0.01 << " length " << cage_length << endl;
0179
0180 cyl = new PHG4CylinderSubsystem("SVTX", ilayer);
0181 cyl->set_double_param("radius",radius);
0182 cyl->set_int_param("lengthviarapidity",0);
0183 cyl->set_double_param("length",cage_length);
0184 cyl->set_string_param("material",tpcgas.c_str());
0185 cyl->set_double_param("thickness", delta_radius - 0.01 );
0186 cyl->SetActive();
0187 cyl->SuperDetector("SVTX");
0188 g4Reco->registerSubsystem( cyl );
0189
0190 radius += delta_radius;
0191 }
0192
0193
0194 cyl = new PHG4CylinderSubsystem("SVTXSUPPORT", n_maps_layer + n_intt_layer + npoints);
0195 cyl->set_double_param("radius",radius);
0196 cyl->set_int_param("lengthviarapidity",0);
0197 cyl->set_double_param("length",cage_length);
0198 cyl->set_string_param("material","G4_KAPTON");
0199 cyl->set_double_param("thickness",cage_thickness );
0200 cyl->SuperDetector("SVTXSUPPORT");
0201 g4Reco->registerSubsystem( cyl );
0202
0203 radius += cage_thickness;
0204
0205 return radius;
0206 }
0207
0208 void Svtx_Cells(int verbosity = 0)
0209 {
0210
0211
0212
0213
0214
0215
0216
0217 gSystem->Load("libfun4all.so");
0218 gSystem->Load("libg4detectors.so");
0219
0220
0221
0222
0223
0224 Fun4AllServer *se = Fun4AllServer::instance();
0225
0226
0227
0228
0229
0230 if(n_maps_layer > 0)
0231 {
0232
0233 PHG4MapsCellReco *maps_cells = new PHG4MapsCellReco("MAPS");
0234 maps_cells->Verbosity(verbosity);
0235 for(int ilayer = 0;ilayer < n_maps_layer;ilayer++)
0236 {
0237 maps_cells->set_timing_window(ilayer,-2000,2000);
0238 }
0239 se->registerSubsystem(maps_cells);
0240 }
0241
0242 if(n_intt_layer > 0)
0243 {
0244
0245 PHG4SiliconTrackerCellReco *reco = new PHG4SiliconTrackerCellReco("SILICON_TRACKER");
0246
0247 reco->Verbosity(verbosity);
0248 se->registerSubsystem(reco);
0249 }
0250
0251
0252 if(n_gas_layer == 60)
0253 {
0254 TPCDriftVelocity = 6.0 / 1000.0;
0255 tpc_cell_x = 0.12;
0256 tpc_cell_y = 0.17;
0257 }
0258
0259
0260 const bool do_tpc_distortion = true;
0261 PHG4TPCSpaceChargeDistortion* tpc_distortion = NULL;
0262 if (do_tpc_distortion) {
0263 if (inner_cage_radius != 20. && inner_cage_radius != 30.) {
0264 cout << "Svtx_Cells - Fatal Error - TPC distortion required that "
0265 "inner_cage_radius is either 20 or 30 cm."
0266 << endl;
0267 exit(3);
0268 }
0269
0270
0271 string TPC_distortion_file =
0272 string(getenv("CALIBRATIONROOT")) +
0273 Form("/Tracking/TPC/SpaceChargeDistortion/TPCCAGE_20_78_211_2.root");
0274 PHG4TPCSpaceChargeDistortion* tpc_distortion =
0275 new PHG4TPCSpaceChargeDistortion(TPC_distortion_file);
0276
0277
0278 }
0279
0280 PHG4CylinderCellTPCReco *svtx_cells = new PHG4CylinderCellTPCReco(n_maps_layer+n_intt_layer);
0281 svtx_cells->Detector("SVTX");
0282 svtx_cells->setDistortion(tpc_distortion);
0283 if(n_gas_layer == 40)
0284 {
0285 svtx_cells->setDiffusionT(0.0130);
0286 svtx_cells->setDiffusionL(0.0130);
0287 svtx_cells->setShapingRMSLead(TPCShapingRMSLead * TPCDriftVelocity);
0288 svtx_cells->setShapingRMSTail(TPCShapingRMSTail * TPCDriftVelocity);
0289
0290
0291
0292 svtx_cells->setSmearRPhi(0.10);
0293 svtx_cells->setSmearZ(0.15);
0294 }
0295 else
0296 {
0297
0298 svtx_cells->setDiffusionT(0.0120);
0299 svtx_cells->setDiffusionL(0.0120);
0300 svtx_cells->setSmearRPhi(0.09);
0301 svtx_cells->setSmearZ(0.06);
0302 }
0303 svtx_cells->set_drift_velocity(TPCDriftVelocity);
0304 svtx_cells->setHalfLength( 105.5 );
0305 svtx_cells->setElectronsPerKeV(28);
0306 svtx_cells->Verbosity(0);
0307
0308
0309
0310
0311 for (int i=n_maps_layer + n_intt_layer;i<Max_si_layer;++i) {
0312 svtx_cells->cellsize(i, tpc_cell_x, tpc_cell_y);
0313 svtx_cells->set_timing_window(i, -35000.0, +35000.0);
0314 }
0315
0316 se->registerSubsystem(svtx_cells);
0317
0318 return;
0319 }
0320
0321 void Svtx_Reco(int verbosity = 0)
0322 {
0323
0324
0325
0326
0327 gSystem->Load("libfun4all.so");
0328 gSystem->Load("libg4hough.so");
0329
0330
0331
0332
0333
0334 Fun4AllServer *se = Fun4AllServer::instance();
0335
0336
0337
0338
0339 PHG4SvtxDigitizer* digi = new PHG4SvtxDigitizer();
0340 digi->Verbosity(0);
0341 for (int i=0;i<n_maps_layer;++i) {
0342 digi->set_adc_scale(i, 255, 0.4e-6);
0343 }
0344
0345 if(n_intt_layer > 0)
0346 {
0347
0348 std::vector<double> userrange;
0349
0350 userrange.push_back(0.05);
0351 userrange.push_back(0.10);
0352 userrange.push_back(0.15);
0353 userrange.push_back(0.20);
0354 userrange.push_back(0.25);
0355 userrange.push_back(0.30);
0356 userrange.push_back(0.35);
0357 userrange.push_back(0.40);
0358
0359 PHG4SiliconTrackerDigitizer* digiintt = new PHG4SiliconTrackerDigitizer();
0360 digiintt->Verbosity(verbosity);
0361 for(int i=0;i<n_intt_layer;i++)
0362 {
0363 digiintt->set_adc_scale(n_maps_layer+i, userrange);
0364 }
0365 se->registerSubsystem( digiintt );
0366 }
0367
0368
0369 for (int i=n_maps_layer+n_intt_layer;i<Max_si_layer;++i) {
0370 digi->set_adc_scale(i, 30000, 1.0);
0371 }
0372 se->registerSubsystem( digi );
0373
0374
0375
0376
0377
0378
0379 PHG4SvtxDeadArea* deadarea = new PHG4SvtxDeadArea();
0380
0381 for(int i = 0;i<n_maps_layer;i++)
0382 {
0383 deadarea->Verbosity(verbosity);
0384
0385 deadarea->set_hit_efficiency(i,1.0);
0386 }
0387 for(int i=n_maps_layer;i<n_maps_layer + n_intt_layer;i++)
0388 {
0389
0390 deadarea->set_hit_efficiency(i,1.0);
0391 }
0392 se->registerSubsystem( deadarea );
0393
0394
0395
0396
0397
0398 PHG4SvtxThresholds* thresholds = new PHG4SvtxThresholds();
0399 thresholds->Verbosity(verbosity);
0400
0401
0402 for(int i = 0;i<n_maps_layer;i++)
0403 {
0404
0405
0406 thresholds->set_threshold(i,0.1);
0407 }
0408
0409 for(int i=n_maps_layer;i<n_maps_layer + n_intt_layer;i++)
0410 {
0411 thresholds->set_threshold(i,0.1);
0412 thresholds->set_use_thickness_mip(i, true);
0413
0414 }
0415
0416 se->registerSubsystem( thresholds );
0417
0418
0419
0420
0421
0422 PHG4SvtxClusterizer* clusterizer = new PHG4SvtxClusterizer("PHG4SvtxClusterizer",0, n_maps_layer + n_intt_layer-1);
0423 clusterizer->Verbosity(verbosity);
0424
0425
0426 clusterizer->set_threshold(0.1);
0427
0428 for(int i=n_maps_layer;i<n_maps_layer+n_intt_layer;i++)
0429 {
0430 clusterizer->set_z_clustering(i, false);
0431 }
0432
0433 se->registerSubsystem( clusterizer );
0434
0435 PHG4TPCClusterizer* tpcclusterizer = new PHG4TPCClusterizer();
0436 tpcclusterizer->Verbosity(0);
0437 tpcclusterizer->setRangeLayers(n_maps_layer+n_intt_layer,Max_si_layer);
0438 if(n_gas_layer == 40)
0439 {
0440 tpcclusterizer->setEnergyCut(12);
0441 tpcclusterizer->setFitWindowSigmas(0.0160,0.0160);
0442 tpcclusterizer->setFitWindowMax(4,6);
0443 tpcclusterizer->setFitEnergyThreshold( 0.05 );
0444 }
0445 else
0446 {
0447
0448 tpcclusterizer->setEnergyCut(15);
0449 tpcclusterizer->setFitWindowSigmas(0.0150,0.0160);
0450 tpcclusterizer->setFitWindowMax(4,3);
0451 tpcclusterizer->setFitEnergyThreshold( 0.05 );
0452 }
0453 se->registerSubsystem( tpcclusterizer );
0454
0455
0456 const bool use_kalman_pat_rec = true;
0457 if (use_kalman_pat_rec) {
0458
0459
0460
0461
0462 PHG4KalmanPatRec* kalman_pat_rec = new PHG4KalmanPatRec("PHG4KalmanPatRec", n_maps_layer, n_intt_layer, n_gas_layer);
0463 kalman_pat_rec->Verbosity(0);
0464 se->registerSubsystem(kalman_pat_rec);
0465
0466 } else {
0467
0468
0469
0470 PHG4TruthPatRec* pat_rec = new PHG4TruthPatRec();
0471 se->registerSubsystem(pat_rec);
0472
0473 }
0474
0475
0476
0477
0478
0479 PHG4TrackKalmanFitter* kalman = new PHG4TrackKalmanFitter();
0480 kalman->Verbosity(0);
0481 if(use_primary_vertex)
0482 kalman->set_fit_primary_tracks(true);
0483 se->registerSubsystem(kalman);
0484
0485
0486
0487
0488
0489 PHG4GenFitTrackProjection *projection = new PHG4GenFitTrackProjection();
0490 projection->Verbosity(verbosity);
0491 se->registerSubsystem( projection );
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502 return;
0503 }
0504
0505 void G4_Svtx_Reco()
0506 {
0507 cout << "\033[31;1m"
0508 << "Warning: G4_Svtx_Reco() was moved to G4_Svtx.C and renamed to Svtx_Reco(), please update macros"
0509 << "\033[0m" << endl;
0510 Svtx_Reco();
0511
0512 return;
0513 }
0514
0515 void Svtx_Eval(std::string outputfile, int verbosity = 0)
0516 {
0517
0518
0519
0520
0521 gSystem->Load("libfun4all.so");
0522 gSystem->Load("libg4detectors.so");
0523 gSystem->Load("libg4hough.so");
0524 gSystem->Load("libg4eval.so");
0525
0526
0527
0528
0529
0530 Fun4AllServer *se = Fun4AllServer::instance();
0531
0532
0533
0534
0535
0536 SvtxEvaluator* eval;
0537 eval = new SvtxEvaluator("SVTXEVALUATOR", outputfile.c_str());
0538 eval->do_cluster_eval(true);
0539 eval->do_g4hit_eval(true);
0540 eval->do_hit_eval(false);
0541 eval->do_gpoint_eval(false);
0542 eval->scan_for_embedded(false);
0543 eval->Verbosity(verbosity);
0544 se->registerSubsystem( eval );
0545
0546
0547 if(use_primary_vertex)
0548 {
0549
0550
0551 SvtxEvaluator* evalp;
0552 evalp = new SvtxEvaluator("SVTXEVALUATOR", string(outputfile.c_str()) + "_primary_eval.root", "PrimaryTrackMap");
0553 evalp->do_cluster_eval(true);
0554 evalp->do_g4hit_eval(true);
0555 evalp->do_hit_eval(false);
0556 evalp->do_gpoint_eval(false);
0557 evalp->scan_for_embedded(true);
0558 evalp->Verbosity(0);
0559 se->registerSubsystem( evalp );
0560 }
0561
0562
0563
0564
0565 return;
0566 }