File indexing completed on 2025-08-06 08:18:24
0001
0002
0003
0004
0005
0006
0007
0008 #include "MakeActsGeometry.h"
0009
0010 #include <trackbase/AlignmentTransformation.h>
0011 #include <trackbase/InttDefs.h>
0012 #include <trackbase/MvtxDefs.h>
0013 #include <trackbase/TpcDefs.h>
0014 #include <trackbase/TrkrDefs.h>
0015 #include <trackbase/alignmentTransformationContainer.h>
0016 #include <trackbase/sPHENIXActsDetectorElement.h>
0017
0018 #include <intt/CylinderGeomIntt.h>
0019
0020 #include <mvtx/CylinderGeom_Mvtx.h>
0021
0022 #include <micromegas/CylinderGeomMicromegas.h>
0023
0024 #include <micromegas/MicromegasDefs.h>
0025
0026 #include <g4detectors/PHG4CylinderGeom.h> // for PHG4CylinderGeom
0027 #include <g4detectors/PHG4CylinderGeomContainer.h>
0028 #include <g4detectors/PHG4TpcCylinderGeom.h>
0029 #include <g4detectors/PHG4TpcCylinderGeomContainer.h>
0030
0031 #include <g4mvtx/PHG4MvtxMisalignment.h>
0032
0033 #include <phgeom/PHGeomIOTGeo.h>
0034 #include <phgeom/PHGeomTGeo.h>
0035 #include <phgeom/PHGeomUtility.h>
0036
0037 #include <fun4all/Fun4AllReturnCodes.h>
0038 #include <fun4all/Fun4AllServer.h>
0039
0040 #include <ffamodules/CDBInterface.h>
0041
0042 #include <phool/PHCompositeNode.h>
0043 #include <phool/PHDataNode.h>
0044 #include <phool/PHNode.h>
0045 #include <phool/PHNodeIterator.h>
0046 #include <phool/PHObject.h>
0047 #include <phool/getClass.h>
0048 #include <phool/phool.h>
0049
0050 #include <Acts/Geometry/GeometryContext.hpp>
0051 #include <Acts/Geometry/TrackingVolume.hpp>
0052 #include <Acts/MagneticField/MagneticFieldContext.hpp>
0053 #include <Acts/Surfaces/PerigeeSurface.hpp>
0054 #include <Acts/Surfaces/PlaneSurface.hpp>
0055 #include <Acts/Surfaces/Surface.hpp>
0056 #include <Acts/Utilities/CalibrationContext.hpp>
0057
0058 #include <ActsExamples/Framework/IContextDecorator.hpp>
0059
0060 #pragma GCC diagnostic push
0061 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
0062 #pragma GCC diagnostic ignored "-Wuninitialized"
0063 #include <trackbase/CommonOptions.h>
0064 #pragma GCC diagnostic pop
0065
0066 #include <trackbase/MagneticFieldOptions.h>
0067 #include <ActsExamples/Utilities/Options.hpp>
0068
0069 #include <ActsExamples/TGeoDetector/JsonTGeoDetectorConfig.hpp>
0070
0071 #include <Acts/Material/IMaterialDecorator.hpp>
0072 #include <Acts/Plugins/Json/JsonMaterialDecorator.hpp>
0073 #include <Acts/Plugins/Json/MaterialMapJsonConverter.hpp>
0074 #include <trackbase/MaterialWiper.h>
0075
0076 #include <TGeoManager.h>
0077 #include <TMatrixT.h>
0078 #include <TObject.h>
0079 #include <TSystem.h>
0080 #include <TVector3.h>
0081
0082 #include <cmath>
0083 #include <cstddef>
0084 #include <cstdlib>
0085 #include <filesystem>
0086 #include <iostream>
0087 #include <map>
0088 #include <memory>
0089 #include <utility>
0090 #include <vector>
0091
0092 namespace
0093 {
0094
0095
0096 TrackingVolumePtr find_volume_by_name(const Acts::TrackingVolume *master, const std::string &name)
0097 {
0098
0099 if (master->volumeName().empty() || master->volumeName()[0] != '{')
0100 {
0101 return nullptr;
0102 }
0103
0104
0105 for (const auto &child : master->confinedVolumes()->arrayObjects())
0106 {
0107 if (child->volumeName() == name)
0108 {
0109 return child;
0110 }
0111 else if (auto found = find_volume_by_name(child.get(), name))
0112 {
0113 return found;
0114 }
0115 }
0116
0117
0118 return nullptr;
0119 }
0120
0121 template <class T>
0122 inline constexpr T square(const T &x)
0123 {
0124 return x * x;
0125 }
0126
0127 template <class T>
0128 inline T get_r(const T &x, const T &y)
0129 {
0130 return std::sqrt(square(x) + square(y));
0131 }
0132
0133 }
0134
0135 MakeActsGeometry::MakeActsGeometry(const std::string &name)
0136 : SubsysReco(name)
0137 {
0138 for (int layer = 0; layer < 57; layer++)
0139 {
0140 m_misalignmentFactor.insert(std::make_pair(layer, 1.));
0141 }
0142 }
0143
0144 int MakeActsGeometry::Init(PHCompositeNode * )
0145 {
0146 return Fun4AllReturnCodes::EVENT_OK;
0147 }
0148
0149 int MakeActsGeometry::InitRun(PHCompositeNode *topNode)
0150 {
0151 m_geomContainerTpc =
0152 findNode::getClass<PHG4TpcCylinderGeomContainer>(topNode, "CYLINDERCELLGEOM_SVTX");
0153
0154
0155 AlignmentTransformation alignment_transformation;
0156 alignment_transformation.createAlignmentTransformContainer(topNode);
0157
0158
0159 if (mvtxParam)
0160 {
0161 alignment_transformation.setMVTXParams(m_mvtxDevs);
0162 }
0163 if (inttParam)
0164 {
0165 alignment_transformation.setINTTParams(m_inttDevs);
0166 }
0167 if (tpcParam)
0168 {
0169 alignment_transformation.setTPCParams(m_tpcDevs);
0170 }
0171 if (mmParam)
0172 {
0173 alignment_transformation.setMMParams(m_mmDevs);
0174 }
0175
0176 if (buildAllGeometry(topNode) != Fun4AllReturnCodes::EVENT_OK)
0177 {
0178 return Fun4AllReturnCodes::ABORTEVENT;
0179 }
0180
0181
0182 ActsTrackingGeometry trackingGeometry;
0183 trackingGeometry.tGeometry = m_tGeometry;
0184 trackingGeometry.magField = m_magneticField;
0185 trackingGeometry.getGeoContext() = m_geoCtxt;
0186 trackingGeometry.tpcSurfStepPhi = m_surfStepPhi;
0187 trackingGeometry.tpcSurfStepZ = m_surfStepZ;
0188
0189
0190 ActsSurfaceMaps surfMaps;
0191 surfMaps.m_siliconSurfaceMap = m_clusterSurfaceMapSilicon;
0192 surfMaps.m_tpcSurfaceMap = m_clusterSurfaceMapTpcEdit;
0193 surfMaps.m_mmSurfaceMap = m_clusterSurfaceMapMmEdit;
0194 surfMaps.m_tGeoNodeMap = m_clusterNodeMap;
0195
0196
0197 for (const auto &[hitsetid, surfaceVector] : m_clusterSurfaceMapTpcEdit)
0198 {
0199 for (const auto &surface : surfaceVector)
0200 {
0201 surfMaps.m_tpcVolumeIds.insert(surface->geometryId().volume());
0202 }
0203 }
0204
0205
0206 for (const auto &[hitsetid, surface] : m_clusterSurfaceMapMmEdit)
0207 {
0208 surfMaps.m_micromegasVolumeIds.insert(surface->geometryId().volume());
0209 }
0210
0211 m_actsGeometry->setGeometry(trackingGeometry);
0212 m_actsGeometry->setSurfMaps(surfMaps);
0213 m_actsGeometry->set_drift_velocity(m_drift_velocity);
0214 m_actsGeometry->set_tpc_tzero(m_tpc_tzero);
0215
0216 if (Verbosity() > 1)
0217 {
0218 alignment_transformation.verbosity();
0219 }
0220 alignment_transformation.createMap(topNode);
0221
0222 for (auto &[layer, factor] : m_misalignmentFactor)
0223 {
0224 alignment_transformation.misalignmentFactor(layer, factor);
0225 }
0226
0227
0228 if (Verbosity())
0229 {
0230 for (const auto &id : surfMaps.m_tpcVolumeIds)
0231 {
0232 std::cout << "MakeActsGeometry::InitRun - TPC volume id: " << id << std::endl;
0233 }
0234
0235 for (const auto &id : surfMaps.m_micromegasVolumeIds)
0236 {
0237 std::cout << "MakeActsGeometry::InitRun - Micromegas volume id: " << id << std::endl;
0238 }
0239 }
0240
0241 return Fun4AllReturnCodes::EVENT_OK;
0242 }
0243
0244 int MakeActsGeometry::buildAllGeometry(PHCompositeNode *topNode)
0245 {
0246
0247
0248
0249
0250 if (getNodes(topNode) != Fun4AllReturnCodes::EVENT_OK)
0251 {
0252 return Fun4AllReturnCodes::ABORTEVENT;
0253 }
0254
0255 setPlanarSurfaceDivisions();
0256
0257
0258 editTPCGeometry(topNode);
0259
0260
0261 if (Verbosity() > 3)
0262 {
0263 PHGeomUtility::ExportGeomtry(topNode, "sPHENIXActsGeom.root");
0264 PHGeomUtility::ExportGeomtry(topNode, "sPHENIXActsGeom.gdml");
0265 }
0266
0267 if (createNodes(topNode) != Fun4AllReturnCodes::EVENT_OK)
0268 {
0269 return Fun4AllReturnCodes::ABORTEVENT;
0270 }
0271
0272
0273 buildActsSurfaces();
0274
0275
0276
0277
0278 return Fun4AllReturnCodes::EVENT_OK;
0279 }
0280
0281 void MakeActsGeometry::editTPCGeometry(PHCompositeNode *topNode)
0282 {
0283
0284
0285 PHGeomTGeo *geomNode = PHGeomUtility::GetGeomTGeoNode(topNode, true);
0286 assert(geomNode);
0287
0288
0289 if (geomNode->isValid())
0290 {
0291 geomNode->Reset();
0292 }
0293
0294 PHGeomIOTGeo *dstGeomIO = PHGeomUtility::GetGeomIOTGeoNode(topNode, false);
0295 assert(dstGeomIO);
0296 assert(dstGeomIO->isValid());
0297
0298 TGeoManager *geoManager = dstGeomIO->ConstructTGeoManager();
0299 geomNode->SetGeometry(geoManager);
0300 assert(geoManager);
0301
0302 if (TGeoManager::GetDefaultUnits() != TGeoManager::EDefaultUnits::kRootUnits)
0303 {
0304 std::cerr << "There is a potential unit mismatch in the ROOT geometry."
0305 << " It is dangerous to continue and may lead to inconsistencies in the Acts geometry. Exiting."
0306 << std::endl;
0307 gSystem->Exit(1);
0308 }
0309
0310 TGeoVolume *World_vol = geoManager->GetTopVolume();
0311
0312
0313
0314
0315 TGeoNode *tpc_envelope_node = nullptr;
0316 TGeoNode *tpc_gas_north_node = nullptr;
0317
0318
0319 if (Verbosity() > 3)
0320 {
0321 std::cout << "EditTPCGeometry - searching under volume: ";
0322 World_vol->Print();
0323 }
0324 for (int i = 0; i < World_vol->GetNdaughters(); i++)
0325 {
0326 TString node_name = World_vol->GetNode(i)->GetName();
0327 if (node_name.BeginsWith("tpc_envelope"))
0328 {
0329 if (Verbosity())
0330 {
0331 std::cout << "EditTPCGeometry - found " << node_name << std::endl;
0332 }
0333
0334 tpc_envelope_node = World_vol->GetNode(i);
0335 break;
0336 }
0337 }
0338
0339 assert(tpc_envelope_node);
0340
0341
0342 TGeoVolume *tpc_envelope_vol = tpc_envelope_node->GetVolume();
0343 assert(tpc_envelope_vol);
0344 if (Verbosity() > 3)
0345 {
0346 std::cout << "EditTPCGeometry - searching under volume: ";
0347 tpc_envelope_vol->Print();
0348 }
0349
0350 for (int i = 0; i < tpc_envelope_vol->GetNdaughters(); i++)
0351 {
0352 TString node_name = tpc_envelope_vol->GetNode(i)->GetName();
0353
0354 if (node_name.BeginsWith("tpc_gas_north"))
0355 {
0356 if (Verbosity())
0357 {
0358 std::cout << "EditTPCGeometry - found " << node_name << std::endl;
0359 }
0360
0361 tpc_gas_north_node = tpc_envelope_vol->GetNode(i);
0362 break;
0363 }
0364 }
0365
0366 assert(tpc_gas_north_node);
0367 TGeoVolume *tpc_gas_north_vol = tpc_gas_north_node->GetVolume();
0368 assert(tpc_gas_north_vol);
0369
0370 int nfakesurfaces = 0;
0371 for (int i = 0; i < tpc_gas_north_vol->GetNdaughters(); i++)
0372 {
0373 TString node_name = tpc_gas_north_vol->GetNode(i)->GetName();
0374 if (node_name.BeginsWith("tpc_gas_measurement_"))
0375 {
0376 nfakesurfaces++;
0377 }
0378 }
0379
0380
0381
0382 if (nfakesurfaces > 0)
0383 {
0384 return;
0385 }
0386
0387 if (Verbosity() > 3)
0388 {
0389 std::cout << "EditTPCGeometry - gas volume: ";
0390 tpc_gas_north_vol->Print();
0391 }
0392
0393
0394 addActsTpcSurfaces(tpc_gas_north_vol, geoManager);
0395
0396
0397 geoManager->CloseGeometry();
0398
0399
0400 PHGeomUtility::UpdateIONode(topNode);
0401 }
0402
0403 void MakeActsGeometry::addActsTpcSurfaces(TGeoVolume *tpc_gas_vol,
0404 TGeoManager *geoManager)
0405 {
0406 TGeoMedium *tpc_gas_medium = tpc_gas_vol->GetMedium();
0407 assert(tpc_gas_medium);
0408
0409
0410 std::cout << "MakeActsGeometry::addActsTpcSurfaces - m_nSurfPhi: " << m_nSurfPhi << std::endl;
0411
0412 TGeoVolume *tpc_gas_measurement_vol[m_nTpcLayers];
0413 double tan_half_phi = tan(m_surfStepPhi / 2.0);
0414 int copy = 0;
0415 for (unsigned int ilayer = 0; ilayer < m_nTpcLayers; ++ilayer)
0416 {
0417
0418 std::string bname = "tpc_gas_measurement_" + std::to_string(ilayer);
0419
0420
0421 double box_r_phi = 2.0 * tan_half_phi *
0422 (m_layerRadius[ilayer] - m_layerThickness[ilayer] / 2.0);
0423
0424 tpc_gas_measurement_vol[ilayer] = geoManager->MakeBox(bname.c_str(), tpc_gas_medium,
0425 m_layerThickness[ilayer] * half_width_clearance_thick,
0426 box_r_phi * half_width_clearance_phi,
0427 m_surfStepZ * half_width_clearance_z);
0428
0429 tpc_gas_measurement_vol[ilayer]->SetLineColor(kBlack);
0430 tpc_gas_measurement_vol[ilayer]->SetFillColor(kYellow);
0431 tpc_gas_measurement_vol[ilayer]->SetVisibility(kTRUE);
0432
0433 if (Verbosity() > 3)
0434 {
0435 std::cout << " Made box for layer " << ilayer
0436 << " with dx " << m_layerThickness[ilayer] << " dy "
0437 << box_r_phi << " ref arc "
0438 << m_surfStepPhi * m_layerRadius[ilayer] << " dz "
0439 << m_surfStepZ << std::endl;
0440 tpc_gas_measurement_vol[ilayer]->Print();
0441 tpc_gas_measurement_vol[ilayer]->CheckOverlaps();
0442 }
0443
0444 for (unsigned int iz = 0; iz < m_nSurfZ; ++iz)
0445 {
0446
0447 double z_center = 0.0;
0448
0449 for (unsigned int imod = 0; imod < m_nTpcModulesPerLayer; ++imod)
0450 {
0451 for (unsigned int iphi = 0; iphi < m_nSurfPhi; ++iphi)
0452 {
0453 double min_phi = m_modulePhiStart +
0454 (double) imod * m_moduleStepPhi +
0455 (double) iphi * m_surfStepPhi;
0456 double phi_center = min_phi + m_surfStepPhi / 2.0;
0457 double phi_center_degrees = phi_center * 180.0 / M_PI;
0458
0459
0460
0461 double x_center = m_layerRadius[ilayer] * cos(phi_center);
0462 double y_center = m_layerRadius[ilayer] * sin(phi_center);
0463
0464 std::string rot_name = "tpc_gas_rotation_" + std::to_string(copy);
0465 TGeoCombiTrans *tpc_gas_measurement_location = new TGeoCombiTrans(x_center, y_center, z_center,
0466 new TGeoRotation(rot_name.c_str(),
0467 phi_center_degrees,
0468 0, 0));
0469
0470 tpc_gas_vol->AddNode(tpc_gas_measurement_vol[ilayer],
0471 copy, tpc_gas_measurement_location);
0472
0473 copy++;
0474 if (Verbosity() > 3)
0475 {
0476 std::cout << "Box center : (" << x_center << ", " << y_center
0477 << ", " << z_center << ")"
0478 << " and in rphiz "
0479 << sqrt(x_center * x_center + y_center * y_center)
0480 << ", " << atan2(y_center, x_center) << ", "
0481 << z_center << std::endl;
0482 std::cout << "Box dimensions " << m_layerThickness[ilayer] * half_width_clearance_thick
0483 << " , " << box_r_phi / (m_layerRadius[ilayer] - m_layerThickness[ilayer] / 2.) * half_width_clearance_phi
0484 << ", " << m_surfStepZ * half_width_clearance_z << " and in xyz "
0485 << m_layerThickness[ilayer] * half_width_clearance_thick * cos(box_r_phi / (m_layerRadius[ilayer] - m_layerThickness[ilayer] / 2.) * half_width_clearance_phi) << ", "
0486 << m_layerThickness[ilayer] * half_width_clearance_thick * sin(box_r_phi / (m_layerRadius[ilayer] - m_layerThickness[ilayer] / 2.) * half_width_clearance_phi) << ", "
0487 << m_surfStepZ * half_width_clearance_z << std::endl;
0488 }
0489 }
0490 }
0491 }
0492 }
0493 }
0494
0495
0496
0497
0498 void MakeActsGeometry::buildActsSurfaces()
0499 {
0500
0501 const int argc = 20;
0502 char *arg[argc];
0503 m_magFieldRescale = 1;
0504
0505 std::cout << PHWHERE << "Magnetic field " << m_magField
0506 << " with rescale " << m_magFieldRescale << std::endl;
0507
0508 std::string responseFile, materialFile;
0509 setMaterialResponseFile(responseFile, materialFile);
0510
0511
0512 std::istringstream stringline(m_magField);
0513 double fieldstrength = std::numeric_limits<double>::quiet_NaN();
0514 stringline >> fieldstrength;
0515
0516 std::ostringstream fld;
0517 fld.str("");
0518 fld << "0:0:" << m_magField;
0519 std::string argstr[argc]{
0520 "-n1",
0521 "--geo-tgeo-jsonconfig", responseFile,
0522 "--mat-input-type", "file",
0523 "--mat-input-file", materialFile,
0524 "--bf-constant-tesla", fld.str().c_str(),
0525 "--bf-bscalor"};
0526
0527 argstr[9] = std::to_string(m_magFieldRescale);
0528
0529
0530 if (stringline.fail())
0531 {
0532 if (std::filesystem::path(m_magField).extension() != ".root")
0533 {
0534 m_magField = CDBInterface::instance()->getUrl(m_magField);
0535 }
0536 if (std::filesystem::exists(m_magField))
0537 {
0538 argstr[7] = "--bf-map-file";
0539 argstr[8] = m_magField;
0540 argstr[9] = "--bf-map-tree";
0541 argstr[10] = "fieldmap";
0542 argstr[11] = "--bf-map-lengthscale-mm";
0543 argstr[12] = "10";
0544 argstr[13] = "--bf-map-fieldscale-tesla";
0545 argstr[14] = std::to_string(m_magFieldRescale);
0546 }
0547 }
0548
0549 std::cout << "Mag field now " << m_magField << " with rescale "
0550 << m_magFieldRescale << std::endl;
0551
0552
0553 for (int i = 0; i < argc; ++i)
0554 {
0555 if (Verbosity() > 1)
0556 {
0557 std::cout << argstr[i] << ", ";
0558 }
0559
0560 arg[i] = strdup(argstr[i].c_str());
0561 }
0562
0563
0564
0565
0566
0567 makeGeometry(argc, arg, m_detector);
0568
0569 for (auto &i : arg)
0570 {
0571
0572 free(i);
0573 }
0574 }
0575 void MakeActsGeometry::setMaterialResponseFile(std::string &responseFile,
0576 std::string &materialFile)
0577 {
0578 responseFile = "tgeo-sphenix-mms.json";
0579 materialFile = "sphenix-mm-material.json";
0580
0581 std::ifstream file;
0582
0583 file.open(responseFile);
0584 if (!file.is_open())
0585 {
0586 std::cout << responseFile
0587 << " not found locally, use CDB version"
0588 << std::endl;
0589 responseFile = CDBInterface::instance()->getUrl("ACTSGEOMETRYCONFIG");
0590 }
0591
0592 file.open(materialFile);
0593 if (!file.is_open())
0594 {
0595 std::cout << materialFile
0596 << " not found locally, use CDB version"
0597 << std::endl;
0598 materialFile = CDBInterface::instance()->getUrl("ACTSMATERIALMAP");
0599 }
0600
0601 std::cout << "using Acts material file : " << materialFile
0602 << std::endl;
0603 std::cout << "Using Acts TGeoResponse file : " << responseFile
0604 << std::endl;
0605
0606 return;
0607 }
0608 void MakeActsGeometry::makeGeometry(int argc, char *argv[],
0609 ActsExamples::TGeoDetectorWithOptions &detector)
0610 {
0611
0612 boost::program_options::options_description desc;
0613 ActsExamples::Options::addGeometryOptions(desc);
0614 ActsExamples::Options::addMaterialOptions(desc);
0615 ActsExamples::Options::addMagneticFieldOptions(desc);
0616
0617
0618 detector.addOptions(desc);
0619 auto vm = ActsExamples::Options::parse(desc, argc, argv);
0620
0621
0622 auto geometry = build(vm, detector);
0623
0624
0625 m_tGeometry = geometry.first;
0626 if (m_useField)
0627 {
0628 m_magneticField = ActsExamples::Options::readMagneticField(vm);
0629 }
0630 else
0631 {
0632 m_magneticField = nullptr;
0633 }
0634
0635 m_geoCtxt = Acts::GeometryContext();
0636
0637 unpackVolumes();
0638
0639 return;
0640 }
0641
0642 std::pair<std::shared_ptr<const Acts::TrackingGeometry>,
0643 std::vector<std::shared_ptr<ActsExamples::IContextDecorator>>>
0644 MakeActsGeometry::build(const boost::program_options::variables_map &vm,
0645 ActsExamples::TGeoDetectorWithOptions &detector)
0646 {
0647
0648 std::shared_ptr<const Acts::IMaterialDecorator> matDeco = nullptr;
0649
0650
0651 auto fileName = vm["mat-input-file"].template as<std::string>();
0652
0653 if (fileName.find(".json") != std::string::npos ||
0654 fileName.find(".cbor") != std::string::npos)
0655 {
0656
0657 Acts::MaterialMapJsonConverter::Config jsonGeoConvConfig;
0658
0659 matDeco = std::make_shared<const Acts::JsonMaterialDecorator>(
0660 jsonGeoConvConfig, fileName, Acts::Logging::FATAL);
0661 }
0662 else
0663 {
0664 matDeco = std::make_shared<const Acts::MaterialWiper>();
0665 }
0666
0667 ActsExamples::TGeoDetector::Config config;
0668
0669 config.elementFactory = sPHENIXElementFactory;
0670
0671 config.fileName = vm["geo-tgeo-filename"].as<std::string>();
0672
0673 config.surfaceLogLevel = Acts::Logging::FATAL;
0674 config.layerLogLevel = Acts::Logging::FATAL;
0675 config.volumeLogLevel = Acts::Logging::FATAL;
0676
0677 const auto path = vm["geo-tgeo-jsonconfig"].template as<std::string>();
0678
0679 readTGeoLayerBuilderConfigsFile(path, config);
0680
0681
0682 return detector.m_detector.finalize(config, matDeco);
0683 }
0684
0685 void MakeActsGeometry::readTGeoLayerBuilderConfigsFile(const std::string &path,
0686 ActsExamples::TGeoDetector::Config &config)
0687 {
0688 if (path.empty())
0689 {
0690 std::cout << "There is no acts geometry response file loaded. Cannot build, exiting"
0691 << std::endl;
0692 exit(1);
0693 }
0694
0695 nlohmann::json djson;
0696 std::ifstream infile(path, std::ifstream::in | std::ifstream::binary);
0697 infile >> djson;
0698
0699 config.unitScalor = djson["geo-tgeo-unit-scalor"];
0700
0701 config.buildBeamPipe = djson["geo-tgeo-build-beampipe"];
0702 if (config.buildBeamPipe)
0703 {
0704 const auto beamPipeParameters =
0705 djson["geo-tgeo-beampipe-parameters"].get<std::array<double, 3>>();
0706 config.beamPipeRadius = beamPipeParameters[0];
0707 config.beamPipeHalflengthZ = beamPipeParameters[1];
0708 config.beamPipeLayerThickness = beamPipeParameters[2];
0709 }
0710
0711
0712 for (const auto &volume : djson["Volumes"])
0713 {
0714 auto &vol = config.volumes.emplace_back();
0715 vol = volume;
0716 }
0717 }
0718
0719 void MakeActsGeometry::unpackVolumes()
0720 {
0721
0722
0723 auto vol = m_tGeometry->highestTrackingVolume();
0724
0725 if (Verbosity() > 3)
0726 {
0727 std::cout << "MakeActsGeometry::unpackVolumes - top volume: " << vol->volumeName() << std::endl;
0728 std::cout << "Before: Mvtx: m_clusterSurfaceMapSilicon size " << m_clusterSurfaceMapSilicon.size() << std::endl;
0729 std::cout << "Before: m_clusterSurfaceMapTpc size " << m_clusterSurfaceMapTpcEdit.size() << std::endl;
0730 }
0731 {
0732
0733 auto mmBarrel = find_volume_by_name(vol, "MICROMEGAS::Barrel");
0734 assert(mmBarrel);
0735 makeMmMapPairs(mmBarrel);
0736 }
0737 {
0738
0739 auto mvtxBarrel = find_volume_by_name(vol, "MVTX::Barrel");
0740 assert(mvtxBarrel);
0741 makeMvtxMapPairs(mvtxBarrel);
0742 if (Verbosity() > 3)
0743 {
0744 std::cout << "After: Mvtx: m_clusterSurfaceMapSilicon size " << m_clusterSurfaceMapSilicon.size() << std::endl;
0745 }
0746 }
0747
0748 {
0749
0750 if (Verbosity() > 3)
0751 {
0752 std::cout << "Before: INTT: m_clusterSurfaceMapSilicon size " << m_clusterSurfaceMapSilicon.size() << std::endl;
0753 }
0754 auto inttBarrel = find_volume_by_name(vol, "Silicon::Barrel");
0755 assert(inttBarrel);
0756 makeInttMapPairs(inttBarrel);
0757 if (Verbosity() > 3)
0758 {
0759 std::cout << "After: INTT: m_clusterSurfaceMapSilicon size " << m_clusterSurfaceMapSilicon.size() << std::endl;
0760 }
0761 }
0762
0763 {
0764
0765 auto tpcBarrel = find_volume_by_name(vol, "TPC::Barrel");
0766 assert(tpcBarrel);
0767 makeTpcMapPairs(tpcBarrel);
0768 if (Verbosity() > 3)
0769 {
0770 std::cout << "After: m_clusterSurfaceMapTpc size " << m_clusterSurfaceMapTpcEdit.size() << std::endl;
0771 }
0772 }
0773
0774 return;
0775 }
0776
0777 void MakeActsGeometry::makeTpcMapPairs(TrackingVolumePtr &tpcVolume)
0778 {
0779 if (Verbosity() > 10)
0780 {
0781 std::cout << "MakeActsGeometry::makeTpcMapPairs - tpcVolume: " << tpcVolume->volumeName() << std::endl;
0782 }
0783
0784 auto tpcLayerArray = tpcVolume->confinedLayers();
0785 auto tpcLayerVector = tpcLayerArray->arrayObjects();
0786
0787
0788 for (auto &i : tpcLayerVector)
0789 {
0790 auto surfaceArray = i->surfaceArray();
0791 if (surfaceArray == nullptr)
0792 {
0793 continue;
0794 }
0795
0796
0797 auto surfaceVector = surfaceArray->surfaces();
0798 for (auto &j : surfaceVector)
0799 {
0800 auto surf = j->getSharedPtr();
0801 auto vec3d = surf->center(m_geoCtxt);
0802
0803
0804 std::vector<double> world_center = {vec3d(0) / 10.0,
0805 vec3d(1) / 10.0,
0806 vec3d(2) / 10.0};
0807
0808 TrkrDefs::hitsetkey hitsetkey = getTpcHitSetKeyFromCoords(world_center);
0809 unsigned int layer = TrkrDefs::getLayer(hitsetkey);
0810
0811
0812
0813
0814 std::map<unsigned int, std::vector<Surface>>::iterator mapIter;
0815
0816 mapIter = m_clusterSurfaceMapTpcEdit.find(layer);
0817
0818 if (mapIter != m_clusterSurfaceMapTpcEdit.end())
0819 {
0820 mapIter->second.push_back(surf);
0821 }
0822 else
0823 {
0824
0825 std::vector<Surface> dumvec;
0826 dumvec.push_back(surf);
0827 std::pair<unsigned int, std::vector<Surface>> tmp =
0828 std::make_pair(layer, dumvec);
0829 m_clusterSurfaceMapTpcEdit.insert(tmp);
0830 }
0831 }
0832 }
0833 }
0834
0835
0836 void MakeActsGeometry::makeMmMapPairs(TrackingVolumePtr &mmVolume)
0837 {
0838 if (Verbosity())
0839 {
0840 std::cout << "MakeActsGeometry::makeMmMapPairs - mmVolume: " << mmVolume->volumeName() << std::endl;
0841 }
0842 const auto mmLayerArray = mmVolume->confinedLayers();
0843 const auto mmLayerVector = mmLayerArray->arrayObjects();
0844
0845
0846 for (const auto &i : mmLayerVector)
0847 {
0848 auto surfaceArray = i->surfaceArray();
0849 if (!surfaceArray)
0850 {
0851 continue;
0852 }
0853
0854
0855
0856 const auto surfaceVector = surfaceArray->surfaces();
0857
0858 for (auto j : surfaceVector)
0859 {
0860 auto surface = j->getSharedPtr();
0861 auto vec3d = surface->center(m_geoCtxt);
0862
0863
0864 TVector3 world_center(
0865 vec3d(0) / Acts::UnitConstants::cm,
0866 vec3d(1) / Acts::UnitConstants::cm,
0867 vec3d(2) / Acts::UnitConstants::cm);
0868
0869
0870 int layer = -1;
0871 CylinderGeomMicromegas *layergeom = nullptr;
0872 const auto range = m_geomContainerMicromegas->get_begin_end();
0873 double delta_r_min = -1;
0874 for (auto iter = range.first; iter != range.second; ++iter)
0875 {
0876 auto this_layergeom = static_cast<CylinderGeomMicromegas *>(iter->second);
0877 const double delta_r = std::abs(this_layergeom->get_radius() - get_r(world_center.x(), world_center.y()));
0878 if (delta_r_min < 0 || delta_r < delta_r_min)
0879 {
0880 layer = iter->first;
0881 layergeom = this_layergeom;
0882 delta_r_min = delta_r;
0883 }
0884 }
0885
0886 if (!layergeom)
0887 {
0888 std::cout << "MakeActsGeometry::makeMmMapPairs - could not file CylinderGeomMicromegas matching ACTS surface" << std::endl;
0889 continue;
0890 }
0891
0892
0893 int tileid = layergeom->find_tile_cylindrical(world_center);
0894 if (tileid < 0)
0895 {
0896 std::cout << "MakeActsGeometry::makeMmMapPairs - could not file Micromegas tile matching ACTS surface" << std::endl;
0897 continue;
0898 }
0899
0900 if (Verbosity())
0901 {
0902 std::cout << "MakeActsGeometry::makeMmMapPairs - layer: " << layer << " tileid: " << tileid << std::endl;
0903 }
0904
0905
0906 const auto segmentation_type = layergeom->get_segmentation_type();
0907
0908
0909 const auto hitsetkey = MicromegasDefs::genHitSetKey(layer, segmentation_type, tileid);
0910 const auto [iter, inserted] = m_clusterSurfaceMapMmEdit.insert(std::make_pair(hitsetkey, surface));
0911 assert(inserted);
0912 }
0913 }
0914 }
0915
0916 void MakeActsGeometry::makeInttMapPairs(TrackingVolumePtr &inttVolume)
0917 {
0918 if (Verbosity() > 10)
0919 {
0920 std::cout << "MakeActsGeometry::makeInttMapPairs - inttVolume: " << inttVolume->volumeName() << std::endl;
0921 }
0922
0923 std::cout << "Use Intt survey geometry? m_inttSurvey =" << m_inttSurvey << std::endl;
0924
0925 auto inttLayerArray = inttVolume->confinedLayers();
0926
0927 auto inttLayerVector = inttLayerArray->arrayObjects();
0928
0929 for (auto &i : inttLayerVector)
0930 {
0931
0932 auto surfaceArray = i->surfaceArray();
0933 if (surfaceArray == nullptr)
0934 {
0935 continue;
0936 }
0937
0938
0939 auto surfaceVector = surfaceArray->surfaces();
0940
0941 for (auto &j : surfaceVector)
0942 {
0943 auto surf = j->getSharedPtr();
0944 auto vec3d = surf->center(m_geoCtxt);
0945
0946 double ref_rad[4] = {-1., -1., -1., -1.};
0947 if (m_inttSurvey)
0948 {
0949 ref_rad[0] = 7.453;
0950 ref_rad[1] = 8.046;
0951 ref_rad[2] = 9.934;
0952 ref_rad[3] = 10.569;
0953 }
0954 else
0955 {
0956 ref_rad[0] = 7.188;
0957 ref_rad[1] = 7.732;
0958 ref_rad[2] = 9.680;
0959 ref_rad[3] = 10.262;
0960 }
0961
0962 const double tolerance = (m_inttSurvey) ? 0.15 : 0.1;
0963
0964 std::vector<double> world_center = {vec3d(0) / 10.0, vec3d(1) / 10.0, vec3d(2) / 10.0};
0965
0966
0967
0968
0969 double layer_rad = (m_inttSurvey) ? sqrt(pow(world_center[0] - m_inttbarrelcenter_survey_x, 2) + pow(world_center[1] - m_inttbarrelcenter_survey_y, 2)) : sqrt(pow(world_center[0], 2) + pow(world_center[1], 2));
0970
0971 unsigned int layer = 0;
0972 for (unsigned int i2 = 0; i2 < 4; ++i2)
0973 {
0974 if (fabs(layer_rad - ref_rad[i2]) < tolerance)
0975 {
0976 layer = i2 + 3;
0977 }
0978 }
0979
0980 TrkrDefs::hitsetkey hitsetkey = getInttHitSetKeyFromCoords(layer, world_center);
0981
0982
0983 std::pair<TrkrDefs::hitsetkey, Surface> tmp = make_pair(hitsetkey, surf);
0984 m_clusterSurfaceMapSilicon.insert(tmp);
0985
0986 if (Verbosity() > 10)
0987 {
0988
0989 unsigned int ladderPhi = InttDefs::getLadderPhiId(hitsetkey);
0990 unsigned int ladderZ = InttDefs::getLadderZId(hitsetkey);
0991
0992 std::cout << "Layer radius " << layer_rad << " layer " << layer << " ladderPhi " << ladderPhi << " ladderZ " << ladderZ << " hitsetkey " << hitsetkey
0993 << " recover surface from m_clusterSurfaceMapSilicon " << std::endl;
0994 std::cout << " surface type " << surf->type() << std::endl;
0995 auto assoc_layer = surf->associatedLayer();
0996 std::cout << std::endl
0997 << " Layer type " << assoc_layer->layerType() << std::endl;
0998
0999 auto assoc_det_element = surf->associatedDetectorElement();
1000 if (assoc_det_element != nullptr)
1001 {
1002 std::cout << " Associated detElement has non-null pointer "
1003 << assoc_det_element << std::endl;
1004 std::cout << std::endl
1005 << " Associated detElement found, thickness = "
1006 << assoc_det_element->thickness() << std::endl;
1007 }
1008 else
1009 {
1010 std::cout << std::endl
1011 << " Associated detElement is nullptr " << std::endl;
1012 }
1013 }
1014 }
1015 }
1016 }
1017
1018 void MakeActsGeometry::makeMvtxMapPairs(TrackingVolumePtr &mvtxVolume)
1019 {
1020 if (Verbosity() > 10)
1021 {
1022 std::cout << "MakeActsGeometry::makeMvtxMapPairs - mvtxVolume: " << mvtxVolume->volumeName() << std::endl;
1023 }
1024
1025
1026 auto mvtxBarrelLayerArray = mvtxVolume->confinedLayers();
1027
1028
1029 auto mvtxLayerVector1 = mvtxBarrelLayerArray->arrayObjects();
1030
1031
1032
1033 for (auto &i : mvtxLayerVector1)
1034 {
1035
1036 auto surfaceArray = i->surfaceArray();
1037 if (surfaceArray == nullptr)
1038 {
1039 continue;
1040 }
1041
1042 if (m_mvtxapplymisalign)
1043 {
1044 std::cout << "MakeActsGeometry::makeMvtxMapPairs - apply misalignment" << std::endl;
1045 PHG4MvtxMisalignment *mvtxmisalignment = new PHG4MvtxMisalignment();
1046 mvtxmisalignment->setAlignmentFile(CDBInterface::instance()->getUrl("MVTX_ALIGNMENT"));
1047 mvtxmisalignment->LoadMvtxStaveAlignmentParameters();
1048 v_globaldisplacement = mvtxmisalignment->get_GlobalDisplacement();
1049
1050
1051 delete mvtxmisalignment;
1052 }
1053
1054 std::cout << "MakeActsGeometry::makeMvtxMapPairs - Apply misalignment: " << m_mvtxapplymisalign << "; Global displacement: (" << v_globaldisplacement[0] << ", " << v_globaldisplacement[1] << ", " << v_globaldisplacement[2] << ")" << std::endl;
1055
1056
1057
1058 auto surfaceVector = surfaceArray->surfaces();
1059 for (auto &j : surfaceVector)
1060 {
1061 auto surf = j->getSharedPtr();
1062
1063 auto vec3d = surf->center(m_geoCtxt);
1064 std::vector<double> world_center = {(vec3d(0) - v_globaldisplacement[0]) / 10.0, (vec3d(1) - v_globaldisplacement[1]) / 10.0, (vec3d(2) - v_globaldisplacement[2]) / 10.0};
1065 double layer_rad = sqrt(pow(world_center[0], 2) + pow(world_center[1], 2));
1066 if (Verbosity() > 0)
1067 {
1068 std::cout << "[DEBUG] MVTX surface center (before misalignment): (x,y,z)=(" << vec3d(0) / 10. << "," << vec3d(1) / 10. << "," << vec3d(2) / 10. << "), layer_rad=" << sqrt(pow(vec3d(0) / 10., 2) + pow(vec3d(1) / 10., 2)) << std::endl;
1069 std::cout << "[DEBUG] MVTX surface center: (x,y,z)=(" << world_center[0] << "," << world_center[1] << "," << world_center[2] << "), layer_rad=" << layer_rad << std::endl;
1070 }
1071
1072 auto detelement = surf->associatedDetectorElement();
1073 if(!detelement)
1074 {
1075 std::cout << PHWHERE << " Did not find associatedDetectorElement, have to quit! " << std::endl;
1076 exit(1);
1077 }
1078
1079 Acts::GeometryIdentifier id = detelement->surface().geometryId();
1080 unsigned int volume = id.volume();
1081 unsigned int actslayer = id.layer();
1082
1083 unsigned int sphlayer = 0;
1084 unsigned int stave = 0;
1085 unsigned int chip = 0;
1086 unsigned int sensor = id.sensitive() - 1;
1087 if (!m_mvtxapplymisalign)
1088 {
1089 sphlayer = base_layer_map.find(volume)->second + actslayer / 2 - 1;
1090 stave = sensor / 9;
1091 chip = sensor % 9;
1092 }
1093 else
1094 {
1095 stave = sensor / mvtx_chips_per_stave;
1096 chip = sensor % mvtx_chips_per_stave;
1097 if(sensor > 107 && sensor < 252)
1098 {
1099 sphlayer = 1;
1100 stave = (sensor-108) / mvtx_chips_per_stave;
1101 chip = (sensor-108) % mvtx_chips_per_stave;
1102 }
1103 else if(sensor > 251)
1104 {
1105 sphlayer = 2;
1106 stave = (sensor-252) / mvtx_chips_per_stave;
1107 chip = (sensor-252) % mvtx_chips_per_stave;
1108 }
1109 }
1110 int dummy_strobe = 0;
1111 TrkrDefs::hitsetkey hitsetkey= MvtxDefs::genHitSetKey(sphlayer, stave, chip, dummy_strobe);
1112
1113 if(Verbosity() > 10)
1114 {
1115 std::cout << "detelement: volume " << volume << " actslayer " << actslayer << " sphlayer " << sphlayer
1116 << " sensor " << sensor << " stave " << stave << " chip " << chip << std::endl;
1117 }
1118
1119
1120 std::pair<TrkrDefs::hitsetkey, Surface> tmp = make_pair(hitsetkey, surf);
1121 m_clusterSurfaceMapSilicon.insert(tmp);
1122
1123 if (Verbosity() > 10)
1124 {
1125 unsigned int stavecheck = MvtxDefs::getStaveId(hitsetkey);
1126 unsigned int chipcheck = MvtxDefs::getChipId(hitsetkey);
1127
1128 double surface_phi = atan2(vec3d(1), vec3d(0));
1129
1130
1131 std::cout << "hitsetkey " << hitsetkey << " Layer radius " << layer_rad << " Layer "
1132 << sphlayer << " stave " << stavecheck << " chip " << chipcheck
1133 << " surface phi " << surface_phi
1134 << " recover surface from m_clusterSurfaceMapSilicon "
1135 << std::endl;
1136
1137 std::map<TrkrDefs::hitsetkey, Surface>::iterator surf_iter = m_clusterSurfaceMapSilicon.find(hitsetkey);
1138 std::cout << " surface type " << surf_iter->second->type()
1139 << std::endl;
1140 auto assoc_layer = surf->associatedLayer();
1141 std::cout << std::endl
1142 << " Layer type "
1143 << assoc_layer->layerType() << std::endl;
1144
1145 auto assoc_det_element = surf->associatedDetectorElement();
1146 if (assoc_det_element != nullptr)
1147 {
1148 std::cout << " Associated detElement has non-null pointer "
1149 << assoc_det_element << std::endl;
1150 std::cout << std::endl
1151 << " Associated detElement found, thickness = "
1152 << assoc_det_element->thickness() << std::endl;
1153 }
1154 else
1155 {
1156 std::cout << std::endl
1157 << " Associated detElement is nullptr " << std::endl;
1158 }
1159 }
1160 }
1161 }
1162 }
1163
1164 TrkrDefs::hitsetkey MakeActsGeometry::getTpcHitSetKeyFromCoords(std::vector<double> &world)
1165 {
1166
1167
1168 unsigned int layer = 999;
1169 double layer_rad = sqrt(pow(world[0], 2) + pow(world[1], 2));
1170 for (unsigned int ilayer = 0; ilayer < m_nTpcLayers; ++ilayer)
1171 {
1172 double tpc_ref_radius_low =
1173 m_layerRadius[ilayer] - m_layerThickness[ilayer] / 2.0;
1174 double tpc_ref_radius_high =
1175 m_layerRadius[ilayer] + m_layerThickness[ilayer] / 2.0;
1176 if (layer_rad >= tpc_ref_radius_low && layer_rad < tpc_ref_radius_high)
1177 {
1178 layer = ilayer;
1179 break;
1180 }
1181 }
1182
1183 if (layer >= m_nTpcLayers)
1184 {
1185 std::cout << PHWHERE
1186 << "Error: undefined layer, do nothing world = "
1187 << world[0] << " " << world[1] << " " << world[2]
1188 << " layer " << layer << std::endl;
1189 return Fun4AllReturnCodes::ABORTEVENT;
1190 }
1191
1192 layer += 7;
1193
1194
1195 unsigned int side;
1196 if (world[2] < 0)
1197 {
1198 side = 0;
1199 }
1200 else
1201 {
1202 side = 1;
1203 }
1204
1205
1206 unsigned int readout_mod = 999;
1207 double phi_world = atan2(world[1], world[0]);
1208 for (unsigned int imod = 0; imod < m_nTpcModulesPerLayer; ++imod)
1209 {
1210 double min_phi = m_modulePhiStart + (double) imod * m_moduleStepPhi;
1211 double max_phi = m_modulePhiStart + (double) (imod + 1) * m_moduleStepPhi;
1212 if (phi_world >= min_phi && phi_world < max_phi)
1213 {
1214 readout_mod = imod;
1215 break;
1216 }
1217 }
1218 if (readout_mod >= m_nTpcModulesPerLayer)
1219 {
1220 std::cout << PHWHERE
1221 << "Error: readout_mod is undefined, do nothing phi_world = "
1222 << phi_world << std::endl;
1223 return Fun4AllReturnCodes::ABORTEVENT;
1224 }
1225
1226 TrkrDefs::hitsetkey hitset_key = TpcDefs::genHitSetKey(layer, readout_mod, side);
1227 if (Verbosity() > 3)
1228 {
1229 if (layer == 30)
1230 {
1231 std::cout << " world = " << world[0] << " " << world[1]
1232 << " " << world[2] << " phi_world "
1233 << phi_world * 180 / M_PI << " layer " << layer
1234 << " readout_mod " << readout_mod << " side " << side
1235 << " hitsetkey " << hitset_key << std::endl;
1236 }
1237 }
1238
1239 return hitset_key;
1240 }
1241
1242 TrkrDefs::hitsetkey MakeActsGeometry::getMvtxHitSetKeyFromCoords(unsigned int layer, std::vector<double> &world)
1243 {
1244
1245
1246 CylinderGeom_Mvtx *layergeom = dynamic_cast<CylinderGeom_Mvtx *>(m_geomContainerMvtx->GetLayerGeom(layer));
1247 if (!layergeom)
1248 {
1249 std::cout << PHWHERE << "Did not get layergeom for layer "
1250 << layer << std::endl;
1251 return 0;
1252 }
1253
1254 unsigned int stave = 0;
1255 unsigned int chip = 0;
1256 layergeom->get_sensor_indices_from_world_coords(world, stave, chip);
1257
1258 unsigned int strobe = 0;
1259 TrkrDefs::hitsetkey mvtx_hitsetkey = MvtxDefs::genHitSetKey(layer, stave, chip, strobe);
1260
1261 return mvtx_hitsetkey;
1262 }
1263
1264 TrkrDefs::hitsetkey MakeActsGeometry::getInttHitSetKeyFromCoords(unsigned int layer, std::vector<double> &world)
1265 {
1266
1267
1268 CylinderGeomIntt *layergeom = dynamic_cast<CylinderGeomIntt *>(m_geomContainerIntt->GetLayerGeom(layer));
1269 if (!layergeom)
1270 {
1271 std::cout << PHWHERE << "Did not get layergeom for layer "
1272 << layer << std::endl;
1273 return 0;
1274 }
1275
1276 double location[3] = {world[0], world[1], world[2]};
1277 int segment_z_bin = 0;
1278 int segment_phi_bin = 0;
1279 layergeom->find_indices_from_segment_center(segment_z_bin,
1280 segment_phi_bin, location);
1281
1282 int crossing = 0;
1283 TrkrDefs::hitsetkey intt_hitsetkey = InttDefs::genHitSetKey(layer, segment_z_bin, segment_phi_bin, crossing);
1284
1285 return intt_hitsetkey;
1286 }
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376 void MakeActsGeometry::getInttKeyFromNode(TGeoNode *gnode)
1377 {
1378 int layer = -1;
1379 int itype = -1;
1380 int ladder_phi = -1;
1381 int zposneg = -1;
1382 int ladder_z = -1;
1383
1384 std::string s = gnode->GetName();
1385 std::string delimiter = "_";
1386 std::string posz("posz");
1387 std::string negz("negz");
1388
1389 size_t pos = 0;
1390 std::string token;
1391
1392 int counter = 0;
1393 while ((pos = s.find(delimiter)) != std::string::npos)
1394 {
1395 token = s.substr(0, pos);
1396
1397 s.erase(0, pos + delimiter.length());
1398 if (counter == 1)
1399 {
1400 layer = std::atoi(token.c_str()) + 3;
1401 }
1402 if (counter == 2)
1403 {
1404 itype = std::atoi(token.c_str());
1405 }
1406 if (counter == 3)
1407 {
1408 ladder_phi = std::atoi(token.c_str());
1409 if (s.compare(0, negz.length(), negz) == 0)
1410 {
1411 zposneg = 0;
1412 }
1413 if (s.compare(0, posz.length(), posz) == 0)
1414 {
1415 zposneg = 1;
1416 }
1417 }
1418 counter++;
1419 }
1420
1421 ladder_z = itype + zposneg * 2;
1422
1423
1424 int ndaught = gnode->GetNdaughters();
1425 if (ndaught == 0)
1426 {
1427 std::cout << PHWHERE << "OOPS: Did not find INTT sensor! Quit."
1428 << std::endl;
1429 exit(1);
1430 }
1431
1432 std::string intt_refactive("siactive");
1433 TGeoNode *sensor_node = nullptr;
1434 for (int i = 0; i < ndaught; ++i)
1435 {
1436 std::string node_str = gnode->GetDaughter(i)->GetName();
1437
1438 if (node_str.compare(0, intt_refactive.length(), intt_refactive) == 0)
1439 {
1440 sensor_node = gnode->GetDaughter(i);
1441 break;
1442 }
1443 }
1444
1445
1446 int crossing = 0;
1447 TrkrDefs::hitsetkey node_key = InttDefs::genHitSetKey(layer, ladder_z, ladder_phi, crossing);
1448
1449 std::pair<TrkrDefs::hitsetkey, TGeoNode *> tmp = std::make_pair(
1450 node_key, sensor_node);
1451 m_clusterNodeMap.insert(tmp);
1452
1453 if (Verbosity() > 1)
1454 {
1455 std::cout << " INTT layer " << layer << " ladder_phi " << ladder_phi
1456 << " itype " << itype << " zposneg " << zposneg
1457 << " ladder_z " << ladder_z << " name "
1458 << sensor_node->GetName() << std::endl;
1459 }
1460
1461 return;
1462 }
1463 void MakeActsGeometry::getTpcKeyFromNode(TGeoNode * )
1464 {
1465 }
1466 void MakeActsGeometry::getMvtxKeyFromNode(TGeoNode *gnode)
1467 {
1468 int counter = 0;
1469 int impr = -1;
1470 int layer = -1;
1471 int stave = -1;
1472 int chip = -1;
1473
1474 std::string s = gnode->GetName();
1475 std::string delimiter = "_";
1476
1477 size_t pos = 0;
1478 std::string token;
1479
1480 while ((pos = s.find(delimiter)) != std::string::npos)
1481 {
1482 token = s.substr(0, pos);
1483
1484 s.erase(0, pos + delimiter.length());
1485 if (counter == 3)
1486 {
1487 impr = std::atoi(token.c_str());
1488 }
1489
1490 counter++;
1491 }
1492
1493
1494
1495
1496 impr -= 1;
1497
1498 if (impr < 12)
1499 {
1500 layer = 0;
1501 stave = impr;
1502 }
1503 else if (impr > 11 && impr < 28)
1504 {
1505 layer = 1;
1506 stave = impr - 12;
1507 }
1508 else
1509 {
1510 layer = 2;
1511 stave = impr - 28;
1512 }
1513
1514
1515 TGeoNode *module_node = gnode->GetDaughter(0);
1516 int mnd = module_node->GetNdaughters();
1517 std::string mvtx_chip("MVTXChip");
1518 for (int i = 0; i < mnd; ++i)
1519 {
1520 std::string dstr = module_node->GetDaughter(i)->GetName();
1521 if (dstr.compare(0, mvtx_chip.length(), mvtx_chip) == 0)
1522 {
1523 if (Verbosity() > 3)
1524 {
1525 std::cout << "Found MVTX layer " << layer << " stave " << stave
1526 << " chip " << i << " with node name "
1527 << module_node->GetDaughter(i)->GetName() << std::endl;
1528 }
1529
1530
1531 unsigned int strobe = 0;
1532 TrkrDefs::hitsetkey node_key = MvtxDefs::genHitSetKey(layer,
1533 stave, i, strobe);
1534
1535
1536 TGeoNode *sensor_node = module_node->GetDaughter(i)->GetDaughter(0);
1537 std::pair<TrkrDefs::hitsetkey, TGeoNode *> tmp = std::make_pair(
1538 node_key, sensor_node);
1539 m_clusterNodeMap.insert(tmp);
1540
1541 if (Verbosity() > 3)
1542 {
1543 std::cout << " MVTX layer " << layer << " stave " << stave
1544 << " chip " << chip << " name "
1545 << sensor_node->GetName() << std::endl;
1546 }
1547 }
1548 }
1549
1550 return;
1551 }
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632 void MakeActsGeometry::setPlanarSurfaceDivisions()
1633 {
1634
1635
1636 m_surfStepZ = (m_maxSurfZ - m_minSurfZ) / (double) m_nSurfZ;
1637 m_moduleStepPhi = 2.0 * M_PI / 12.0;
1638 m_modulePhiStart = -M_PI;
1639 m_surfStepPhi = 2.0 * M_PI / (double) (m_nSurfPhi * m_nTpcModulesPerLayer);
1640
1641 int layer = 0;
1642 PHG4TpcCylinderGeomContainer::ConstRange layerrange = m_geomContainerTpc->get_begin_end();
1643 for (PHG4TpcCylinderGeomContainer::ConstIterator layeriter = layerrange.first;
1644 layeriter != layerrange.second;
1645 ++layeriter)
1646 {
1647 m_layerRadius[layer] = layeriter->second->get_radius();
1648 m_layerThickness[layer] = layeriter->second->get_thickness();
1649 layer++;
1650 }
1651 }
1652
1653 int MakeActsGeometry::createNodes(PHCompositeNode *topNode)
1654 {
1655 PHNodeIterator iter(topNode);
1656
1657 PHCompositeNode *parNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "PAR"));
1658
1659
1660 if (!parNode)
1661 {
1662 std::cout << "PAR Node missing, creating it" << std::endl;
1663 parNode = new PHCompositeNode("PAR");
1664 topNode->addNode(parNode);
1665 }
1666
1667 PHNodeIterator pariter(parNode);
1668
1669 PHCompositeNode *svtxNode = dynamic_cast<PHCompositeNode *>(pariter.findFirst("PHCompositeNode", "SVTX"));
1670
1671
1672 if (!svtxNode)
1673 {
1674 svtxNode = new PHCompositeNode("SVTX");
1675 parNode->addNode(svtxNode);
1676 }
1677
1678 m_actsGeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
1679 if (!m_actsGeometry)
1680 {
1681 m_actsGeometry = new ActsGeometry();
1682 PHDataNode<ActsGeometry> *tGeoNode = new PHDataNode<ActsGeometry>(m_actsGeometry, "ActsGeometry");
1683 svtxNode->addNode(tGeoNode);
1684 }
1685
1686 return Fun4AllReturnCodes::EVENT_OK;
1687 }
1688
1689
1690
1691
1692
1693 int MakeActsGeometry::getNodes(PHCompositeNode *topNode)
1694 {
1695 m_geoManager = PHGeomUtility::GetTGeoManager(topNode);
1696 if (!m_geoManager)
1697 {
1698 std::cout << PHWHERE << " Did not find TGeoManager, quit! "
1699 << std::endl;
1700 return Fun4AllReturnCodes::ABORTEVENT;
1701 }
1702
1703 m_geomContainerMvtx = findNode::getClass<
1704 PHG4CylinderGeomContainer>(topNode, "CYLINDERGEOM_MVTX");
1705 if (!m_geomContainerMvtx)
1706 {
1707 std::cout << PHWHERE
1708 << " CYLINDERGEOM_MVTX node not found on node tree"
1709 << std::endl;
1710 return Fun4AllReturnCodes::ABORTEVENT;
1711 }
1712
1713 m_geomContainerTpc =
1714 findNode::getClass<PHG4TpcCylinderGeomContainer>(topNode, "CYLINDERCELLGEOM_SVTX");
1715 if (!m_geomContainerTpc)
1716 {
1717 std::cout << PHWHERE
1718 << "ERROR: Can't find node CYLINDERCELLGEOM_SVTX"
1719 << std::endl;
1720 topNode->print();
1721 auto se = Fun4AllServer::instance();
1722 se->Print();
1723 return Fun4AllReturnCodes::ABORTRUN;
1724 }
1725
1726 m_geomContainerIntt = findNode::getClass<
1727 PHG4CylinderGeomContainer>(topNode, "CYLINDERGEOM_INTT");
1728 if (!m_geomContainerIntt)
1729 {
1730 std::cout << PHWHERE
1731 << " CYLINDERGEOM_INTT node not found on node tree"
1732 << std::endl;
1733 return Fun4AllReturnCodes::ABORTEVENT;
1734 }
1735
1736 m_geomContainerMicromegas = findNode::getClass<PHG4CylinderGeomContainer>(topNode, "CYLINDERGEOM_MICROMEGAS_FULL");
1737 if (!m_geomContainerMicromegas)
1738 {
1739 std::cout << PHWHERE
1740 << " CYLINDERGEOM_MICROMEGAS_FULL node not found on node tree"
1741 << std::endl;
1742 return Fun4AllReturnCodes::ABORTEVENT;
1743 }
1744
1745 return Fun4AllReturnCodes::EVENT_OK;
1746 }