File indexing completed on 2025-12-17 09:24:00
0001 #ifndef MACRO_G4CEMCSPACAL_C
0002 #define MACRO_G4CEMCSPACAL_C
0003
0004 #include <GlobalVariables.C>
0005
0006 #include <QA.C>
0007
0008 #include <phparameter/PHParameterUtils.h>
0009
0010 #include <g4detectors/PHG4CylinderCellReco.h>
0011 #include <g4detectors/PHG4CylinderGeom_Spacalv1.h>
0012 #include <g4detectors/PHG4CylinderSubsystem.h>
0013 #include <g4detectors/PHG4FullProjSpacalCellReco.h>
0014 #include <g4detectors/PHG4SpacalSubsystem.h>
0015
0016 #include <g4calo/RawTowerBuilder.h>
0017 #include <g4calo/RawTowerDigitizer.h>
0018
0019 #include <g4eval/CaloEvaluator.h>
0020
0021 #include <g4main/PHG4Reco.h>
0022 #include <g4main/PHG4Utils.h>
0023
0024 #include <calowaveformsim/CaloWaveformSim.h>
0025
0026 #include <calobase/TowerInfoDefs.h>
0027
0028 #include <caloreco/CaloTowerBuilder.h>
0029 #include <caloreco/CaloTowerCalib.h>
0030 #include <caloreco/CaloTowerStatus.h>
0031 #include <caloreco/CaloWaveformProcessing.h>
0032 #include <caloreco/RawClusterBuilderGraph.h>
0033 #include <caloreco/RawClusterBuilderTemplate.h>
0034 #include <caloreco/RawClusterPositionCorrection.h>
0035 #include <caloreco/RawTowerCalibration.h>
0036
0037 #include <simqa_modules/QAG4SimulationCalorimeter.h>
0038
0039 #include <fun4all/Fun4AllServer.h>
0040
0041 #include <Rtypes.h> // resolves R__LOAD_LIBRARY for clang-tidy
0042 #include <TSystem.h>
0043
0044 R__LOAD_LIBRARY(libcalo_reco.so)
0045 R__LOAD_LIBRARY(libg4calo.so)
0046 R__LOAD_LIBRARY(libCaloWaveformSim.so)
0047 R__LOAD_LIBRARY(libg4detectors.so)
0048 R__LOAD_LIBRARY(libg4eval.so)
0049 R__LOAD_LIBRARY(libsimqa_modules.so)
0050
0051 double CEmc_2DProjectiveSpacal(PHG4Reco *g4Reco, double radius, int crossings);
0052
0053 namespace Enable
0054 {
0055 bool CEMC = false;
0056 bool CEMC_ABSORBER = false;
0057 bool CEMC_OVERLAPCHECK = false;
0058 bool CEMC_CELL = false;
0059 bool CEMC_TOWER = false;
0060 bool CEMC_CLUSTER = false;
0061 bool CEMC_EVAL = false;
0062 bool CEMC_QA = false;
0063 bool CEMC_G4Hit = true;
0064 bool CEMC_TOWERINFO = false;
0065 int CEMC_VERBOSITY = 0;
0066 }
0067
0068 namespace G4CEMC
0069 {
0070 int Min_cemc_layer = 1;
0071 int Max_cemc_layer = 1;
0072
0073
0074 RawTowerDigitizer::enu_digi_algorithm TowerDigi = RawTowerDigitizer::kSimple_photon_digitization;
0075
0076
0077
0078
0079
0080
0081
0082
0083 int Cemc_spacal_configuration = PHG4CylinderGeom_Spacalv1::k2DProjectiveSpacal;
0084
0085 enum enu_Cemc_clusterizer
0086 {
0087 kCemcGraphClusterizer,
0088
0089 kCemcTemplateClusterizer
0090 };
0091
0092
0093 enu_Cemc_clusterizer Cemc_clusterizer = kCemcTemplateClusterizer;
0094
0095
0096 bool useTowerInfoV2 = true;
0097
0098 }
0099
0100
0101
0102 void CEmcInit(const int i = 0)
0103 {
0104 }
0105
0106
0107 double
0108 CEmc(PHG4Reco *g4Reco, double radius, const int crossings)
0109 {
0110 return CEmc_2DProjectiveSpacal( g4Reco, radius, crossings);
0111 }
0112
0113
0114 double
0115 CEmc_2DProjectiveSpacal(PHG4Reco *g4Reco, double radius, const int )
0116 {
0117 bool AbsorberActive = Enable::ABSORBER || Enable::CEMC_ABSORBER;
0118 bool OverlapCheck = Enable::OVERLAPCHECK || Enable::CEMC_OVERLAPCHECK;
0119
0120 double emc_inner_radius = 92;
0121 double cemcthickness = 22.50000 - no_overlapp;
0122
0123
0124 double emc_outer_radius = emc_inner_radius + cemcthickness;
0125 assert(emc_outer_radius < 116);
0126
0127 if (radius > emc_inner_radius)
0128 {
0129 std::cout << "inconsistency: preshower radius+thickness: " << radius
0130 << " larger than emc inner radius: " << emc_inner_radius << std::endl;
0131 gSystem->Exit(-1);
0132 }
0133
0134
0135 radius = emc_inner_radius;
0136
0137
0138 PHG4CylinderSubsystem *cyl = new PHG4CylinderSubsystem("CEMC_ELECTRONICS", 0);
0139 cyl->set_double_param("radius", radius);
0140 cyl->set_string_param("material", "G4_TEFLON");
0141 cyl->set_double_param("thickness", 1.5 - no_overlapp);
0142 cyl->SuperDetector("CEMC_ELECTRONICS");
0143 cyl->OverlapCheck(OverlapCheck);
0144 if (AbsorberActive)
0145 {
0146 cyl->SetActive();
0147 }
0148 g4Reco->registerSubsystem(cyl);
0149
0150 radius += 1.5;
0151 cemcthickness -= 1.5 + no_overlapp;
0152
0153
0154 cyl = new PHG4CylinderSubsystem("CEMC_SPT", 0);
0155 cyl->SuperDetector("CEMC_SPT");
0156 cyl->set_double_param("radius", radius + cemcthickness - 0.5);
0157 cyl->set_string_param("material", "SS310");
0158 cyl->set_double_param("thickness", 0.5 - no_overlapp);
0159 cyl->OverlapCheck(OverlapCheck);
0160 if (AbsorberActive)
0161 {
0162 cyl->SetActive();
0163 }
0164 g4Reco->registerSubsystem(cyl);
0165
0166
0167
0168 double sptlen = PHG4Utils::GetLengthForRapidityCoverage(radius + cemcthickness);
0169 BlackHoleGeometry::max_z = std::max(BlackHoleGeometry::max_z, sptlen);
0170 BlackHoleGeometry::min_z = std::min(BlackHoleGeometry::min_z, -sptlen);
0171 BlackHoleGeometry::max_radius = std::max(BlackHoleGeometry::max_radius, radius + cemcthickness);
0172
0173 cemcthickness -= 0.5 + no_overlapp;
0174
0175 int ilayer = 0;
0176 PHG4SpacalSubsystem *cemc;
0177
0178 cemc = new PHG4SpacalSubsystem("CEMC", ilayer);
0179
0180 cemc->set_int_param("virualize_fiber", 0);
0181 cemc->set_int_param("azimuthal_seg_visible", 1);
0182 cemc->set_int_param("construction_verbose", 0);
0183 cemc->Verbosity(0);
0184 cemc->UseCalibFiles(PHG4DetectorSubsystem::xml);
0185 cemc->SetCalibrationFileDir(std::string(getenv("CALIBRATIONROOT")) + std::string("/CEMC/Geometry_2023ProjTilted/"));
0186 cemc->set_double_param("radius", radius);
0187 cemc->set_double_param("thickness", cemcthickness);
0188 if (G4CEMC::Cemc_spacal_configuration == PHG4CylinderGeom_Spacalv1::k2DProjectiveSpacal)
0189 {
0190 cemc->set_int_param("saveg4hit", Enable::CEMC_G4Hit);
0191 }
0192
0193 cemc->SetActive();
0194 cemc->SuperDetector("CEMC");
0195 if (AbsorberActive)
0196 {
0197 cemc->SetAbsorberActive();
0198 }
0199 cemc->OverlapCheck(OverlapCheck);
0200
0201 g4Reco->registerSubsystem(cemc);
0202
0203 if (ilayer > G4CEMC::Max_cemc_layer)
0204 {
0205 std::cout << "layer discrepancy, current layer " << ilayer
0206 << " max cemc layer: " << G4CEMC::Max_cemc_layer << std::endl;
0207 }
0208
0209 radius += cemcthickness;
0210 radius += no_overlapp;
0211
0212 return radius;
0213 }
0214
0215 void CEMC_Cells()
0216 {
0217 int verbosity = std::max(Enable::VERBOSITY, Enable::CEMC_VERBOSITY);
0218
0219 Fun4AllServer *se = Fun4AllServer::instance();
0220
0221 if (G4CEMC::Cemc_spacal_configuration == PHG4CylinderGeom_Spacalv1::k1DProjectiveSpacal)
0222 {
0223 PHG4CylinderCellReco *cemc_cells = new PHG4CylinderCellReco("CEMCCYLCELLRECO");
0224 cemc_cells->Detector("CEMC");
0225 cemc_cells->Verbosity(verbosity);
0226 for (int i = G4CEMC::Min_cemc_layer; i <= G4CEMC::Max_cemc_layer; i++)
0227 {
0228
0229 const double radius = 95;
0230 cemc_cells->cellsize(i, 2 * M_PI / 256. * radius, 2 * M_PI / 256. * radius);
0231 }
0232 se->registerSubsystem(cemc_cells);
0233 }
0234 else if (G4CEMC::Cemc_spacal_configuration == PHG4CylinderGeom_Spacalv1::k2DProjectiveSpacal)
0235 {
0236 if (!Enable::CEMC_G4Hit)
0237 {
0238 return;
0239 }
0240 PHG4FullProjSpacalCellReco *cemc_cells = new PHG4FullProjSpacalCellReco("CEMCCYLCELLRECO");
0241 cemc_cells->Detector("CEMC");
0242 cemc_cells->Verbosity(verbosity);
0243 cemc_cells->get_light_collection_model().load_data_file(
0244 std::string(getenv("CALIBRATIONROOT")) + std::string("/CEMC/LightCollection/Prototype3Module.xml"),
0245 "data_grid_light_guide_efficiency", "data_grid_fiber_trans");
0246 se->registerSubsystem(cemc_cells);
0247 }
0248 else
0249 {
0250 std::cout << "G4_CEmc_Spacal.C::CEmc - Fatal Error - unrecognized SPACAL configuration #"
0251 << G4CEMC::Cemc_spacal_configuration << ". Force exiting..." << std::endl;
0252 gSystem->Exit(-1);
0253 return;
0254 }
0255
0256 return;
0257 }
0258
0259 void CEMC_Towers()
0260 {
0261 int verbosity = std::max(Enable::VERBOSITY, Enable::CEMC_VERBOSITY);
0262
0263 Fun4AllServer *se = Fun4AllServer::instance();
0264
0265 if (!Enable::CEMC_TOWERINFO)
0266 {
0267 if (Enable::CEMC_G4Hit)
0268 {
0269 RawTowerBuilder *TowerBuilder = new RawTowerBuilder("EmcRawTowerBuilder");
0270 TowerBuilder->Detector("CEMC");
0271 TowerBuilder->set_sim_tower_node_prefix("SIM");
0272 TowerBuilder->Verbosity(verbosity);
0273 se->registerSubsystem(TowerBuilder);
0274 }
0275 double sampling_fraction = 1;
0276
0277
0278
0279 sampling_fraction = 2e-02;
0280 const double photoelectron_per_GeV = 500;
0281
0282 RawTowerDigitizer *TowerDigitizer = new RawTowerDigitizer("EmcRawTowerDigitizer");
0283 TowerDigitizer->Detector("CEMC");
0284 TowerDigitizer->Verbosity(verbosity);
0285 TowerDigitizer->set_digi_algorithm(G4CEMC::TowerDigi);
0286 TowerDigitizer->set_variable_pedestal(true);
0287
0288
0289 TowerDigitizer->set_photonelec_ADC(1);
0290 TowerDigitizer->set_photonelec_yield_visible_GeV(photoelectron_per_GeV / sampling_fraction);
0291 TowerDigitizer->set_variable_zero_suppression(true);
0292
0293 if (!Enable::CEMC_G4Hit)
0294 {
0295 TowerDigitizer->set_towerinfo(RawTowerDigitizer::ProcessTowerType::kTowerInfoOnly);
0296 }
0297 if (Enable::CDB)
0298 {
0299 PHParameterUtils::FillPHParametersFromCDB(TowerDigitizer->GetParameters(), "EMCTOWERCALIB");
0300 }
0301 else
0302 {
0303 TowerDigitizer->GetParameters().ReadFromFile("CEMC", "xml", 0, 0,
0304 std::string(getenv("CALIBRATIONROOT")) + std::string("/CEMC/TowerCalibCombinedParams_2020/"));
0305 }
0306 se->registerSubsystem(TowerDigitizer);
0307
0308 RawTowerCalibration *TowerCalibration = new RawTowerCalibration("EmcRawTowerCalibration");
0309 TowerCalibration->Detector("CEMC");
0310 TowerCalibration->set_usetowerinfo_v2(G4CEMC::useTowerInfoV2);
0311 TowerCalibration->Verbosity(verbosity);
0312 if (!Enable::CEMC_G4Hit)
0313 {
0314 TowerCalibration->set_towerinfo(RawTowerCalibration::ProcessTowerType::kTowerInfoOnly);
0315 }
0316 if (G4CEMC::TowerDigi == RawTowerDigitizer::kNo_digitization)
0317 {
0318
0319 TowerCalibration->set_calib_const_GeV_ADC(1.0 / sampling_fraction);
0320 }
0321 else
0322 {
0323 TowerCalibration->set_calib_algorithm(RawTowerCalibration::kTower_by_tower_calibration);
0324 if (Enable::CDB)
0325 {
0326 PHParameterUtils::FillPHParametersFromCDB(TowerCalibration->GetCalibrationParameters(), "EMCTOWERCALIB");
0327 }
0328 else
0329 {
0330 TowerCalibration->GetCalibrationParameters().ReadFromFile("CEMC", "xml", 0, 0,
0331 std::string(getenv("CALIBRATIONROOT")) + std::string("/CEMC/TowerCalibCombinedParams_2020/"));
0332 }
0333 TowerCalibration->set_variable_GeV_ADC(true);
0334
0335 TowerCalibration->set_variable_pedestal(true);
0336
0337 }
0338 se->registerSubsystem(TowerCalibration);
0339 }
0340 else
0341 {
0342 CaloWaveformSim *caloWaveformSim = new CaloWaveformSim();
0343 caloWaveformSim->set_detector_type(CaloTowerDefs::CEMC);
0344 caloWaveformSim->set_detector("CEMC");
0345 caloWaveformSim->set_nsamples(12);
0346 caloWaveformSim->set_pedestalsamples(12);
0347 caloWaveformSim->set_timewidth(0.2);
0348 caloWaveformSim->set_peakpos(6);
0349 caloWaveformSim->get_light_collection_model().load_data_file(
0350 std::string(getenv("CALIBRATIONROOT")) +
0351 std::string("/CEMC/LightCollection/Prototype3Module.xml"),
0352 "data_grid_light_guide_efficiency", "data_grid_fiber_trans");
0353
0354 if (Input::BEAM_CONFIGURATION == Input::pp_ZEROANGLE)
0355 {
0356 caloWaveformSim->set_pedestal_scale(0.75);
0357 }
0358 if (Input::BEAM_CONFIGURATION == Input::pp_COLLISION)
0359 {
0360 caloWaveformSim->set_pedestal_scale(0.77);
0361 }
0362
0363
0364 se->registerSubsystem(caloWaveformSim);
0365
0366 CaloTowerBuilder *ca2 = new CaloTowerBuilder();
0367 ca2->set_detector_type(CaloTowerDefs::CEMC);
0368 ca2->set_nsamples(12);
0369 ca2->set_dataflag(false);
0370 ca2->set_processing_type(CaloWaveformProcessing::TEMPLATE);
0371 ca2->set_builder_type(CaloTowerDefs::kWaveformTowerSimv1);
0372
0373 ca2->set_softwarezerosuppression(true, 60);
0374 se->registerSubsystem(ca2);
0375
0376 CaloTowerStatus *statusEMC = new CaloTowerStatus("CEMCSTATUS");
0377 statusEMC->set_detector_type(CaloTowerDefs::CEMC);
0378 statusEMC->set_time_cut(1);
0379 se->registerSubsystem(statusEMC);
0380
0381 CaloTowerCalib *calibEMC = new CaloTowerCalib("CEMCCALIB");
0382 calibEMC->set_detector_type(CaloTowerDefs::CEMC);
0383 calibEMC->set_outputNodePrefix("TOWERINFO_CALIB_");
0384 se->registerSubsystem(calibEMC);
0385 }
0386 return;
0387 }
0388
0389 void CEMC_Clusters()
0390 {
0391 int verbosity = std::max(Enable::VERBOSITY, Enable::CEMC_VERBOSITY);
0392
0393 Fun4AllServer *se = Fun4AllServer::instance();
0394
0395 if (G4CEMC::Cemc_clusterizer == G4CEMC::kCemcTemplateClusterizer)
0396 {
0397 RawClusterBuilderTemplate *ClusterBuilder = new RawClusterBuilderTemplate("EmcRawClusterBuilderTemplate");
0398 ClusterBuilder->Detector("CEMC");
0399 ClusterBuilder->Verbosity(verbosity);
0400 ClusterBuilder->set_threshold_energy(0.030);
0401 std::string emc_prof = getenv("CALIBRATIONROOT");
0402 emc_prof += "/EmcProfile/CEMCprof_Thresh30MeV.root";
0403 ClusterBuilder->LoadProfile(emc_prof);
0404 if (!Enable::CEMC_G4Hit)
0405 {
0406 ClusterBuilder->set_UseTowerInfo(1);
0407 }
0408
0409 se->registerSubsystem(ClusterBuilder);
0410 }
0411 else if (G4CEMC::Cemc_clusterizer == G4CEMC::kCemcGraphClusterizer)
0412 {
0413 RawClusterBuilderGraph *ClusterBuilder = new RawClusterBuilderGraph("EmcRawClusterBuilderGraph");
0414 ClusterBuilder->Detector("CEMC");
0415 ClusterBuilder->Verbosity(verbosity);
0416 se->registerSubsystem(ClusterBuilder);
0417 }
0418 else
0419 {
0420 std::cout << "CEMC_Clusters - unknown clusterizer setting!" << std::endl;
0421 exit(1);
0422 }
0423
0424 RawClusterPositionCorrection *clusterCorrection = new RawClusterPositionCorrection("CEMC");
0425 if (!Enable::CEMC_G4Hit || Enable::CEMC_TOWERINFO)
0426 {
0427 clusterCorrection->set_UseTowerInfo(1);
0428 }
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446 clusterCorrection->Verbosity(verbosity);
0447 se->registerSubsystem(clusterCorrection);
0448
0449 return;
0450 }
0451 void CEMC_Eval(const std::string &outputfile)
0452 {
0453 int verbosity = std::max(Enable::VERBOSITY, Enable::CEMC_VERBOSITY);
0454
0455 Fun4AllServer *se = Fun4AllServer::instance();
0456
0457 CaloEvaluator *eval = new CaloEvaluator("CEMCEVALUATOR", "CEMC", outputfile);
0458 eval->Verbosity(verbosity);
0459 eval->set_use_towerinfo(Enable::CEMC_TOWERINFO);
0460 se->registerSubsystem(eval);
0461
0462 return;
0463 }
0464
0465 void CEMC_QA()
0466 {
0467 int verbosity = std::max(Enable::QA_VERBOSITY, Enable::CEMC_VERBOSITY);
0468
0469 Fun4AllServer *se = Fun4AllServer::instance();
0470 QAG4SimulationCalorimeter *qa = new QAG4SimulationCalorimeter("CEMC");
0471 qa->Verbosity(verbosity);
0472 if (Enable::CEMC_TOWERINFO)
0473 {
0474 qa->set_flags(QAG4SimulationCalorimeter::kProcessTowerinfo);
0475 }
0476 se->registerSubsystem(qa);
0477
0478 return;
0479 }
0480
0481 #endif