Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-10 02:21:25

0001 #include "SimG4Core/Geometry/interface/CMSG4CheckOverlap.h"
0002 #include "SimG4Core/Geometry/interface/CMSG4RegionReporter.h"
0003 #include "SimG4Core/Geometry/interface/CustomUIsession.h"
0004 
0005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0006 
0007 #include "G4GDMLParser.hh"
0008 #include "G4GeomTestVolume.hh"
0009 #include "G4RunManagerKernel.hh"
0010 #include "G4LogicalVolume.hh"
0011 #include "G4LogicalVolumeStore.hh"
0012 #include "G4PhysicalVolumeStore.hh"
0013 #include "G4GeometryManager.hh"
0014 #include "G4Region.hh"
0015 #include "G4RegionStore.hh"
0016 #include "G4Element.hh"
0017 #include "G4ElementTable.hh"
0018 #include "G4Material.hh"
0019 #include "G4MaterialTable.hh"
0020 #include "G4ProductionCutsTable.hh"
0021 #include "G4MaterialCutsCouple.hh"
0022 #include <CLHEP/Units/SystemOfUnits.h>
0023 #include "G4VPhysicalVolume.hh"
0024 #include "G4UnitsTable.hh"
0025 #include "G4ios.hh"
0026 #include "globals.hh"
0027 
0028 #include <string>
0029 #include <vector>
0030 #include <iostream>
0031 #include <iomanip>
0032 
0033 CMSG4CheckOverlap::CMSG4CheckOverlap(const edm::ParameterSet& p,
0034                                      std::string& regFile,
0035                                      CustomUIsession* session,
0036                                      G4VPhysicalVolume* world) {
0037   bool mat = p.getParameter<bool>("MaterialFlag");
0038   const std::string& ss = p.getParameter<std::string>("OutputBaseName");
0039   if (ss.empty()) {
0040     edm::LogWarning("SimG4CoreGeometry")
0041         << "CMSG4CheckOverlap: OutputFileBaseName is not provided - no check is performed";
0042     return;
0043   }
0044   if (mat) {
0045     const std::string sss = "Materials_" + ss + ".txt";
0046     std::ofstream fout(sss.c_str(), std::ios::out);
0047     if (fout.fail()) {
0048       edm::LogWarning("SimG4CoreGeometry")
0049           << "CMSG4CheckOverlap: file <" << sss << "> is not opened - no report provided";
0050     } else {
0051       edm::LogVerbatim("SimG4CoreGeometry") << "CMSG4CheckOverlap: output file <" << sss << "> is opened";
0052       makeReportForMaterials(fout);
0053       fout.close();
0054     }
0055   }
0056 
0057   bool reg = p.getParameter<bool>("RegionFlag");
0058   if (reg) {
0059     const std::string qqq = (regFile.empty()) ? ss : regFile;
0060     const std::string sss = "Regions_" + qqq + ".txt";
0061     CMSG4RegionReporter rrep;
0062     rrep.ReportRegions(sss);
0063   }
0064 
0065   bool geom = p.getParameter<bool>("GeomFlag");
0066   if (geom) {
0067     const std::string sss = "Geometry_" + ss + ".txt";
0068     std::ofstream fout(sss.c_str(), std::ios::out);
0069     if (fout.fail()) {
0070       edm::LogWarning("SimG4CoreGeometry")
0071           << "CMSG4CheckOverlap: file <" << sss << "> is not opened - no report provided";
0072     } else {
0073       edm::LogVerbatim("SimG4CoreGeometry") << "CMSG4CheckOverlap: output file <" << sss << "> is opened";
0074       session->sendToFile(&fout);
0075       makeReportForGeometry(fout, world);
0076       session->stopSendToFile();
0077       fout.close();
0078     }
0079   }
0080 
0081   bool gdmlFlag = p.getParameter<bool>("gdmlFlag");
0082   if (gdmlFlag) {
0083     std::string PVname = p.getParameter<std::string>("PVname");
0084     if (PVname.empty() || PVname == "world" || PVname == "World") {
0085       G4GDMLParser gdml = nullptr;
0086       gdml.SetRegionExport(true);
0087       gdml.SetEnergyCutsExport(true);
0088       gdml.SetSDExport(true);
0089       gdml.Write(ss + ".gdml", world, true);
0090     }
0091   }
0092 
0093   bool oFlag = p.getParameter<bool>("OverlapFlag");
0094   if (oFlag) {
0095     const std::string sss = "Overlaps_" + ss + ".txt";
0096     std::ofstream fout(sss.c_str(), std::ios::out);
0097     if (fout.fail()) {
0098       edm::LogWarning("SimG4CoreGeometry")
0099           << "CMSG4CheckOverlap: file <" << sss << "> is not opened - no report provided";
0100     } else {
0101       edm::LogVerbatim("SimG4CoreGeometry") << "CMSG4CheckOverlap: output file <" << ss << "> is opened";
0102       session->sendToFile(&fout);
0103       makeReportForOverlaps(fout, p, world);
0104       session->stopSendToFile();
0105       fout.close();
0106     }
0107   }
0108 }
0109 
0110 void CMSG4CheckOverlap::makeReportForMaterials(std::ofstream& fout) {
0111   int nelm = G4Element::GetNumberOfElements();
0112   int nmat = G4Material::GetNumberOfMaterials();
0113   G4ProductionCutsTable* theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
0114   int ncouples = theCoupleTable->GetTableSize();
0115   fout << "====================================================================="
0116        << "\n";
0117   fout << "NumberOfElements  " << nelm << "\n";
0118   fout << "NumberOfMaterials " << nmat << "\n";
0119   fout << "NumberOfCouples   " << ncouples << "\n";
0120   fout << "====================================================================="
0121        << "\n";
0122   fout << "ElementsDump:"
0123        << "\n";
0124   G4ElementTable* elmtab = G4Element::GetElementTable();
0125   fout << *elmtab;
0126   fout << "====================================================================="
0127        << "\n";
0128   G4MaterialTable* mattab = G4Material::GetMaterialTable();
0129   fout << "MaterialsDump:"
0130        << "\n";
0131   //fout << *mattab << "\n";
0132   for (int i = 0; i < nmat; ++i) {
0133     fout << "### Material " << i << "   " << ((*mattab)[i])->GetNumberOfElements() << " elements\n";
0134     fout << (*mattab)[i] << "\n";
0135   }
0136   fout << "====================================================================="
0137        << "\n";
0138   fout << "MaterialsCutsCoupleDump:"
0139        << "\n";
0140   const std::vector<G4double>* gcut = theCoupleTable->GetEnergyCutsVector(0);
0141   const std::vector<G4double>* ecut = theCoupleTable->GetEnergyCutsVector(1);
0142   const std::vector<G4double>* pcut = theCoupleTable->GetEnergyCutsVector(2);
0143   const std::vector<G4double>* icut = theCoupleTable->GetEnergyCutsVector(3);
0144   for (int i = 0; i < ncouples; ++i) {
0145     const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
0146     const G4ProductionCuts* aCut = couple->GetProductionCuts();
0147     fout << "Index : " << i << "  used in the geometry : ";
0148     if (couple->IsUsed()) {
0149       fout << "Yes\n";
0150     } else {
0151       fout << "No \n";
0152     }
0153     fout << " Material : " << couple->GetMaterial()->GetName() << "\n";
0154     fout << " Range cuts        : "
0155          << " gamma  " << G4BestUnit(aCut->GetProductionCut(0), "Length") << "    e-  "
0156          << G4BestUnit(aCut->GetProductionCut(1), "Length") << "    e+  "
0157          << G4BestUnit(aCut->GetProductionCut(2), "Length") << " proton "
0158          << G4BestUnit(aCut->GetProductionCut(3), "Length") << "\n";
0159     fout << " Energy thresholds : ";
0160     fout << " gamma  " << G4BestUnit((*gcut)[i], "Energy") << "    e-  " << G4BestUnit((*ecut)[i], "Energy")
0161          << "    e+  " << G4BestUnit((*pcut)[i], "Energy") << " proton " << G4BestUnit((*icut)[i], "Energy") << "\n";
0162   }
0163   fout << "======================================================================"
0164        << "\n";
0165 }
0166 
0167 void CMSG4CheckOverlap::makeReportForGeometry(std::ofstream& fout, G4VPhysicalVolume* world) {
0168   const G4RegionStore* regs = G4RegionStore::GetInstance();
0169   const G4PhysicalVolumeStore* pvs = G4PhysicalVolumeStore::GetInstance();
0170   const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
0171   int numPV = pvs->size();
0172   int numLV = lvs->size();
0173   int nreg = regs->size();
0174   fout << "====================================================================="
0175        << "\n";
0176   fout << "NumberOfRegions         " << nreg << "\n";
0177   fout << "NumberOfLogicalVolumes  " << numLV << "\n";
0178   fout << "NumberOfPhysicalVolumes " << numPV << "\n";
0179   fout << "====================================================================="
0180        << "\n";
0181   G4GeometryManager::GetInstance()->CloseGeometry(true, true, world);
0182   fout << "====================================================================="
0183        << "\n";
0184 }
0185 
0186 void CMSG4CheckOverlap::makeReportForOverlaps(std::ofstream& fout,
0187                                               const edm::ParameterSet& p,
0188                                               G4VPhysicalVolume* world) {
0189   std::vector<std::string> nodeNames = p.getParameter<std::vector<std::string>>("NodeNames");
0190   std::string PVname = p.getParameter<std::string>("PVname");
0191   std::string LVname = p.getParameter<std::string>("LVname");
0192   double tolerance = p.getParameter<double>("Tolerance") * CLHEP::mm;
0193   int nPoints = p.getParameter<int>("Resolution");
0194   bool verbose = p.getParameter<bool>("Verbose");
0195   bool regionFlag = p.getParameter<bool>("RegionFlag");
0196   bool gdmlFlag = p.getParameter<bool>("gdmlFlag");
0197   int nPrints = p.getParameter<int>("ErrorThreshold");
0198 
0199   const G4RegionStore* regStore = G4RegionStore::GetInstance();
0200 
0201   G4LogicalVolume* lv;
0202   const G4PhysicalVolumeStore* pvs = G4PhysicalVolumeStore::GetInstance();
0203   const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
0204   unsigned int numPV = pvs->size();
0205   unsigned int numLV = lvs->size();
0206   unsigned int nn = nodeNames.size();
0207 
0208   std::vector<G4String> savedgdml;
0209 
0210   fout << "====================================================================="
0211        << "\n";
0212   fout << "CMSG4OverlapCheck is initialised with " << nodeNames.size() << " nodes; "
0213        << " nPoints= " << nPoints << "; tolerance= " << tolerance / CLHEP::mm << " mm; verbose: " << verbose << "\n"
0214        << "               RegionFlag: " << regionFlag << "  PVname: " << PVname << "  LVname: " << LVname << "\n"
0215        << "               Nlv= " << numLV << "   Npv= " << numPV << "\n";
0216   fout << "====================================================================="
0217        << "\n";
0218 
0219   G4GDMLParser* gdml = nullptr;
0220   if (gdmlFlag) {
0221     gdml = new G4GDMLParser();
0222     gdml->SetRegionExport(true);
0223     gdml->SetEnergyCutsExport(true);
0224     gdml->SetSDExport(true);
0225   }
0226   if (0 < nn) {
0227     for (unsigned int ii = 0; ii < nn; ++ii) {
0228       if (nodeNames[ii].empty() || "world" == nodeNames[ii] || "World" == nodeNames[ii]) {
0229         nodeNames[ii] = world->GetName();
0230         fout << "### Check overlaps for World "
0231              << "\n";
0232         G4GeomTestVolume test(world, tolerance, nPoints, verbose);
0233         test.SetErrorsThreshold(nPrints);
0234         test.TestOverlapInTree();
0235       } else if (regionFlag) {
0236         fout << "---------------------------------------------------------------"
0237              << "\n";
0238         fout << "### Check overlaps for G4Region Node[" << ii << "] : " << nodeNames[ii] << "\n";
0239         G4Region* reg = regStore->GetRegion((G4String)nodeNames[ii]);
0240         if (!reg) {
0241           fout << "### NO G4Region found - EXIT"
0242                << "\n";
0243           return;
0244         }
0245         std::vector<G4LogicalVolume*>::iterator rootLVItr = reg->GetRootLogicalVolumeIterator();
0246         unsigned int numRootLV = reg->GetNumberOfRootVolumes();
0247         fout << "      " << numRootLV << " Root Logical Volumes in this region"
0248              << "\n";
0249 
0250         for (unsigned int iLV = 0; iLV < numRootLV; ++iLV, ++rootLVItr) {
0251           // Cover each root logical volume in this region
0252           lv = *rootLVItr;
0253           fout << "### Check overlaps for G4LogicalVolume " << lv->GetName() << "\n";
0254           for (unsigned int i = 0; i < numPV; ++i) {
0255             if (((*pvs)[i])->GetLogicalVolume() == lv) {
0256               G4String pvname = ((*pvs)[i])->GetName();
0257               G4bool isNew = true;
0258               for (unsigned int k = 0; k < savedgdml.size(); ++k) {
0259                 if (pvname == savedgdml[k]) {
0260                   isNew = false;
0261                   break;
0262                 }
0263               }
0264               if (!isNew) {
0265                 fout << "### Check overlaps for PhysVolume  " << pvname << " is skipted because was already done"
0266                      << "\n";
0267                 continue;
0268               }
0269               savedgdml.push_back(pvname);
0270               fout << "### Check overlaps for PhysVolume  " << pvname << "\n";
0271               // gdml dump only for 1 volume
0272               if (gdmlFlag) {
0273                 gdml->Write(pvname + ".gdml", (*pvs)[i], true);
0274               }
0275               G4GeomTestVolume test(((*pvs)[i]), tolerance, nPoints, verbose);
0276               test.SetErrorsThreshold(nPrints);
0277               test.TestOverlapInTree();
0278             }
0279           }
0280         }
0281       } else {
0282         fout << "### Check overlaps for PhysVolume Node[" << ii << "] : " << nodeNames[ii] << "\n";
0283         G4VPhysicalVolume* pv = pvs->GetVolume((G4String)nodeNames[ii]);
0284         G4GeomTestVolume test(pv, tolerance, nPoints, verbose);
0285         test.SetErrorsThreshold(nPrints);
0286         test.TestOverlapInTree();
0287       }
0288     }
0289   }
0290   if (!PVname.empty()) {
0291     fout << "----------- List of PhysVolumes by name -----------------"
0292          << "\n";
0293     for (unsigned int i = 0; i < numPV; ++i) {
0294       if (PVname == (*pvs)[i]->GetName()) {
0295         fout << " ##### PhysVolume " << PVname << " [" << ((*pvs)[i])->GetCopyNo()
0296              << "]  LV: " << ((*pvs)[i])->GetLogicalVolume()->GetName()
0297              << " Mother LV: " << ((*pvs)[i])->GetMotherLogical()->GetName()
0298              << " Region: " << ((*pvs)[i])->GetLogicalVolume()->GetRegion()->GetName() << "\n";
0299         fout << "       Translation: " << ((*pvs)[i])->GetObjectTranslation() << "\n";
0300         fout << "       Rotation:    " << ((*pvs)[i])->GetObjectRotationValue() << "\n";
0301         if (gdmlFlag) {
0302           gdml->Write(PVname + ".gdml", (*pvs)[i], true);
0303         }
0304       }
0305     }
0306   }
0307   if (!LVname.empty()) {
0308     fout << "---------- List of Logical Volumes by name ------------------"
0309          << "\n";
0310     for (unsigned int i = 0; i < numLV; ++i) {
0311       if (LVname == ((*lvs)[i])->GetName()) {
0312         G4int np = ((*lvs)[i])->GetNoDaughters();
0313         fout << " ##### LogVolume " << LVname << "  " << np << " daughters"
0314              << " Region: " << ((*lvs)[i])->GetRegion()->GetName() << "\n";
0315         fout << *(((*lvs)[i])->GetSolid()) << "\n";
0316         for (G4int j = 0; j < np; ++j) {
0317           G4VPhysicalVolume* pv = ((*lvs)[i])->GetDaughter(j);
0318           if (pv) {
0319             fout << "   PV: " << pv->GetName() << " [" << pv->GetCopyNo() << "]"
0320                  << " type: " << pv->VolumeType() << "  multiplicity: " << pv->GetMultiplicity()
0321                  << " LV: " << pv->GetLogicalVolume()->GetName() << "\n";
0322             fout << "       Translation: " << pv->GetObjectTranslation() << "\n";
0323             fout << "       Rotation:    " << pv->GetObjectRotationValue() << "\n";
0324             fout << *(pv->GetLogicalVolume()->GetSolid()) << "\n";
0325           }
0326         }
0327       }
0328     }
0329   }
0330   fout << "---------------- End of overlap checks ---------------------"
0331        << "\n";
0332   delete gdml;
0333 }