File indexing completed on 2025-12-16 09:20:20
0001 #include "PHGeomUtility.h"
0002
0003 #include "PHGeomIOTGeo.h"
0004 #include "PHGeomTGeo.h"
0005
0006 #include <fun4all/Fun4AllReturnCodes.h>
0007
0008 #include <phool/PHCompositeNode.h>
0009 #include <phool/PHDataNode.h>
0010 #include <phool/PHIODataNode.h>
0011 #include <phool/PHNodeIterator.h>
0012 #include <phool/PHObject.h>
0013 #include <phool/getClass.h>
0014 #include <phool/recoConsts.h>
0015
0016 #include <TGeoManager.h>
0017
0018 #include <uuid/uuid.h>
0019
0020 #include <unistd.h> // for generate unique local file
0021 #include <cassert>
0022 #include <cstdio>
0023 #include <cstdlib>
0024 #include <fstream>
0025 #include <iostream>
0026 #include <sstream>
0027 #include <stdexcept>
0028
0029
0030 TGeoManager *
0031 PHGeomUtility::GetTGeoManager(PHCompositeNode *topNode)
0032 {
0033 PHGeomTGeo *dst_geom = GetGeomTGeoNode(topNode, true);
0034 if (!dst_geom)
0035 {
0036 std::cout << __PRETTY_FUNCTION__
0037 << " - Error - Can NOT construct geometry node." << std::endl;
0038 exit(1);
0039 return nullptr;
0040 }
0041
0042 if (!dst_geom->isValid())
0043 {
0044
0045 dst_geom = LoadFromIONode(topNode);
0046 }
0047
0048 if (TGeoManager::GetDefaultUnits() != TGeoManager::kRootUnits)
0049 {
0050 std::cout << __PRETTY_FUNCTION__ << " TGeoManager was not constructed with RootUnits, which potentially leads to unit mismatch with Fun4All. This is considered a fatal error."
0051 << std::endl;
0052
0053 exit(1);
0054 return nullptr;
0055 }
0056
0057 UpdateIONode(topNode);
0058
0059 return dst_geom->GetGeometry();
0060 }
0061
0062 void PHGeomUtility::ExportGeomtry(PHCompositeNode *topNode,
0063 const std::string &geometry_file)
0064 {
0065 TGeoManager *tgeo = GetTGeoManager(topNode);
0066
0067 assert(tgeo);
0068
0069 tgeo->Export(geometry_file.c_str());
0070 }
0071
0072 int PHGeomUtility::ImportGeomFile(PHCompositeNode *topNode,
0073 const std::string &geometry_file)
0074 {
0075 PHGeomTGeo *dst_geom = GetGeomTGeoNode(topNode);
0076 assert(dst_geom);
0077
0078 dst_geom->Reset();
0079
0080 TGeoManager::SetVerboseLevel(GetVerbosity());
0081
0082
0083 #if ROOT_VERSION_CODE >= ROOT_VERSION(6, 23, 2)
0084 TGeoManager::LockDefaultUnits(kFALSE);
0085 TGeoManager::SetDefaultUnits(TGeoManager::kRootUnits);
0086 TGeoManager::LockDefaultUnits(kTRUE);
0087 #else
0088 TGeoManager::SetDefaultRootUnits();
0089 #endif
0090
0091 dst_geom->SetGeometry(TGeoManager::Import(geometry_file.c_str()));
0092
0093 if (dst_geom->GetGeometry() == nullptr)
0094 {
0095 std::cout << __PRETTY_FUNCTION__ << "failed to import " << geometry_file
0096 << std::endl;
0097 return Fun4AllReturnCodes::ABORTRUN;
0098 }
0099
0100 UpdateIONode(topNode);
0101
0102 return Fun4AllReturnCodes::EVENT_OK;
0103 }
0104
0105 int PHGeomUtility::ImportCurrentTGeoManager(PHCompositeNode *topNode)
0106 {
0107 PHGeomTGeo *dst_geom = GetGeomTGeoNode(topNode);
0108 assert(dst_geom);
0109
0110 if (dst_geom->GetGeometry() == gGeoManager)
0111 {
0112 return Fun4AllReturnCodes::EVENT_OK;
0113 }
0114
0115 assert(!dst_geom->isValid());
0116 dst_geom->SetGeometry(gGeoManager);
0117 TGeoManager::SetVerboseLevel(GetVerbosity());
0118
0119 return Fun4AllReturnCodes::EVENT_OK;
0120 }
0121
0122
0123 PHGeomTGeo *
0124 PHGeomUtility::GetGeomTGeoNode(PHCompositeNode *topNode, bool build_new)
0125 {
0126 PHNodeIterator iter(topNode);
0127
0128
0129 PHCompositeNode *parNode = static_cast<PHCompositeNode *>(iter.findFirst(
0130 "PHCompositeNode", "PAR"));
0131 if (!parNode)
0132 {
0133 std::ostringstream serr;
0134 serr << __PRETTY_FUNCTION__ << ": PAR Node missing, request aborting.";
0135 std::cout << serr.str() << std::endl;
0136
0137 throw std::runtime_error(serr.str());
0138
0139 return nullptr;
0140 }
0141
0142 PHGeomTGeo *dst_geom = findNode::getClass<PHGeomTGeo>(parNode,
0143 GetDSTNodeName());
0144 if (!dst_geom && build_new)
0145 {
0146 dst_geom = new PHGeomTGeo();
0147 PHDataNode<PHObject> *GeomNode = new PHDataNode<PHObject>(dst_geom,
0148 GetDSTNodeName(), "PHObject");
0149 parNode->addNode(GeomNode);
0150 }
0151
0152 return dst_geom;
0153 }
0154
0155
0156 PHGeomIOTGeo *
0157 PHGeomUtility::GetGeomIOTGeoNode(PHCompositeNode *topNode, bool build_new)
0158 {
0159 PHNodeIterator iter(topNode);
0160
0161
0162 PHCompositeNode *runNode = static_cast<PHCompositeNode *>(iter.findFirst(
0163 "PHCompositeNode", "RUN"));
0164 if (!runNode)
0165 {
0166 std::ostringstream serr;
0167 serr << __PRETTY_FUNCTION__ << ": RUN Node missing, request aborting.";
0168 std::cout << serr.str() << std::endl;
0169
0170 throw std::runtime_error(serr.str());
0171
0172 return nullptr;
0173 }
0174
0175 PHGeomIOTGeo *dst_geom = findNode::getClass<PHGeomIOTGeo>(runNode,
0176 GetDSTIONodeName());
0177 if (!dst_geom && build_new)
0178 {
0179 dst_geom = new PHGeomIOTGeo();
0180 PHIODataNode<PHObject> *GeomNode = new PHIODataNode<PHObject>(dst_geom,
0181 GetDSTIONodeName(), "PHObject");
0182 runNode->addNode(GeomNode);
0183 }
0184
0185 return dst_geom;
0186 }
0187
0188 std::string
0189 PHGeomUtility::GenerateGeometryFileName(const std::string &filename_extension)
0190 {
0191 std::ostringstream file;
0192
0193 uuid_t uu;
0194 uuid_generate(uu);
0195 char uuid[50];
0196 uuid_unparse(uu, uuid);
0197
0198 file << mg_GenerateGeometryFileNameBase << "/"
0199 << "PHGeomUtility_geom_file_" << uuid << "."
0200 << filename_extension;
0201
0202 return file.str();
0203 }
0204
0205 std::string PHGeomUtility::mg_GenerateGeometryFileNameBase = "/tmp";
0206
0207
0208 bool PHGeomUtility::RemoveGeometryFile(const std::string &file_name)
0209 {
0210 std::fstream ifile(file_name, std::ios_base::in);
0211
0212 if (ifile)
0213 {
0214 ifile.close();
0215 if (remove(file_name.c_str()) != 0)
0216 {
0217 std::cout << __PRETTY_FUNCTION__ << " - Error - can not remove file "
0218 << file_name << std::endl;
0219 return false;
0220 }
0221 return true;
0222 }
0223 return true;
0224 }
0225
0226
0227
0228 PHGeomIOTGeo *
0229 PHGeomUtility::UpdateIONode(PHCompositeNode *topNode)
0230 {
0231 PHGeomTGeo *dst_geom = GetGeomTGeoNode(topNode, false);
0232
0233 if (!dst_geom)
0234 {
0235 std::cout << __PRETTY_FUNCTION__
0236 << " - ERROR - failed to update PHGeomIOTGeo node RUN/GEOMETRY_IO due to missing PHGeomTGeo node at RUN/GEOMETRY"
0237 << std::endl;
0238 return nullptr;
0239 }
0240 if (!dst_geom->isValid())
0241 {
0242 std::cout << __PRETTY_FUNCTION__
0243 << " - ERROR - failed to update PHGeomIOTGeo node RUN/GEOMETRY_IO due to invalid PHGeomTGeo node at RUN/GEOMETRY"
0244 << std::endl;
0245 return nullptr;
0246 }
0247
0248 PHGeomIOTGeo *dst_geom_io = GetGeomIOTGeoNode(topNode, true);
0249 assert(dst_geom_io);
0250
0251 dst_geom_io->SetGeometry(dst_geom->GetGeometry()->GetTopVolume());
0252
0253 return dst_geom_io;
0254 }
0255
0256
0257
0258 PHGeomTGeo *
0259 PHGeomUtility::LoadFromIONode(PHCompositeNode *topNode)
0260 {
0261 PHGeomIOTGeo *dst_geom_io = GetGeomIOTGeoNode(topNode, false);
0262
0263 if (!dst_geom_io)
0264 {
0265 std::cout << __PRETTY_FUNCTION__
0266 << " - ERROR - failed to update PHGeomTGeo node RUN/GEOMETRY due to missing PHGeomIOTGeo node at RUN/GEOMETRY_IO"
0267 << std::endl;
0268 return nullptr;
0269 }
0270 if (!dst_geom_io->isValid())
0271 {
0272 std::cout << __PRETTY_FUNCTION__
0273 << " - ERROR - failed to update PHGeomTGeo node RUN/GEOMETRY due to invalid PHGeomIOTGeo node at RUN/GEOMETRY_IO"
0274 << std::endl;
0275 return nullptr;
0276 }
0277
0278
0279 TGeoManager::SetVerboseLevel(GetVerbosity());
0280 TGeoManager *tgeo = dst_geom_io->ConstructTGeoManager();
0281 tgeo->CloseGeometry();
0282
0283 PHGeomTGeo *dst_geom = GetGeomTGeoNode(topNode, true);
0284 assert(dst_geom);
0285 dst_geom->SetGeometry(tgeo);
0286
0287 return dst_geom;
0288 }
0289
0290
0291 void PHGeomUtility::SetVerbosity(int v)
0292 {
0293 recoConsts *rc = recoConsts::instance();
0294 rc->set_IntFlag("PHGEOMETRY_VERBOSITY", v);
0295 }
0296
0297
0298 int PHGeomUtility::GetVerbosity()
0299 {
0300 recoConsts *rc = recoConsts::instance();
0301 if (rc->FlagExist("PHGEOMETRY_VERBOSITY"))
0302 {
0303 return rc->get_IntFlag("PHGEOMETRY_VERBOSITY");
0304 }
0305 return 0;
0306 }