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