Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 10:04:36

0001 #include "SimG4Core/Notification/interface/BeginOfRun.h"
0002 #include "SimG4Core/Notification/interface/Observer.h"
0003 #include "SimG4Core/Watcher/interface/SimWatcher.h"
0004 
0005 #include "FWCore/Framework/interface/EventSetup.h"
0006 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0007 #include "Geometry/Records/interface/IdealGeometryRecord.h"
0008 #include "DetectorDescription/Core/interface/DDCompactView.h"
0009 #include "DetectorDescription/Core/interface/DDFilter.h"
0010 #include "DetectorDescription/Core/interface/DDFilteredView.h"
0011 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
0012 #include "DetectorDescription/Core/interface/DDSolid.h"
0013 #include "DetectorDescription/Core/interface/DDSolidShapes.h"
0014 #include "DetectorDescription/Core/interface/DDSplit.h"
0015 #include "DetectorDescription/Core/interface/DDValue.h"
0016 
0017 #include "G4Run.hh"
0018 #include "G4PhysicalVolumeStore.hh"
0019 #include "G4LogicalVolumeStore.hh"
0020 #include "G4VPhysicalVolume.hh"
0021 #include "G4LogicalVolume.hh"
0022 #include "G4VSolid.hh"
0023 #include "G4Material.hh"
0024 #include "G4NavigationHistory.hh"
0025 #include "G4Track.hh"
0026 #include "G4VisAttributes.hh"
0027 #include "G4UserLimits.hh"
0028 #include "G4TransportationManager.hh"
0029 
0030 #include <algorithm>
0031 #include <iostream>
0032 #include <vector>
0033 #include <map>
0034 #include <set>
0035 #include <string>
0036 
0037 class PrintGeomSummary : public SimWatcher, public Observer<const BeginOfRun*> {
0038 public:
0039   PrintGeomSummary(edm::ParameterSet const& p);
0040   ~PrintGeomSummary() override = default;
0041 
0042   void registerConsumes(edm::ConsumesCollector) override;
0043   void beginRun(edm::EventSetup const&) override;
0044 
0045 private:
0046   void update(const BeginOfRun* run) override;
0047   void addSolid(const DDLogicalPart& part);
0048   void fillLV(G4LogicalVolume* lv);
0049   void fillPV(G4VPhysicalVolume* pv);
0050   void dumpSummary(std::ostream& out, std::string name);
0051   G4VPhysicalVolume* getTopPV();
0052   void addName(std::string name);
0053   void printSummary(std::ostream& out);
0054 
0055 private:
0056   edm::ESGetToken<DDCompactView, IdealGeometryRecord> ddcompToken_;
0057   std::vector<std::string> nodeNames_;
0058   std::map<DDSolidShape, std::string> solidShape_;
0059   std::map<std::string, DDSolidShape> solidMap_;
0060   G4VPhysicalVolume* theTopPV_;
0061   std::vector<G4LogicalVolume*> lvs_, touch_;
0062   std::vector<G4VSolid*> sls_;
0063   std::vector<G4VPhysicalVolume*> pvs_;
0064   std::map<DDSolidShape, std::pair<int, int>> kount_;
0065 };
0066 
0067 PrintGeomSummary::PrintGeomSummary(const edm::ParameterSet& p) : theTopPV_(nullptr) {
0068   std::vector<std::string> defNames;
0069   nodeNames_ = p.getUntrackedParameter<std::vector<std::string>>("NodeNames", defNames);
0070   G4cout << "PrintGeomSummary:: initialised for " << nodeNames_.size() << " nodes:" << G4endl;
0071   for (unsigned int ii = 0; ii < nodeNames_.size(); ii++)
0072     G4cout << "Node[" << ii << "] : " << nodeNames_[ii] << G4endl;
0073 
0074   solidShape_[DDSolidShape::ddbox] = "Box";
0075   solidShape_[DDSolidShape::ddtubs] = "Tube";
0076   solidShape_[DDSolidShape::ddtrap] = "Trapezoid";
0077   solidShape_[DDSolidShape::ddcons] = "Cone";
0078   solidShape_[DDSolidShape::ddpolycone_rz] = "Polycone_rz";
0079   solidShape_[DDSolidShape::ddpolyhedra_rz] = "Polyhedra_rz";
0080   solidShape_[DDSolidShape::ddpolycone_rrz] = "Polycone_rrz";
0081   solidShape_[DDSolidShape::ddpolyhedra_rrz] = "Polyhedra_rrz";
0082   solidShape_[DDSolidShape::ddtorus] = "Torus";
0083   solidShape_[DDSolidShape::ddunion] = "UnionSolid";
0084   solidShape_[DDSolidShape::ddsubtraction] = "SubtractionSolid";
0085   solidShape_[DDSolidShape::ddintersection] = "IntersectionSolid";
0086   solidShape_[DDSolidShape::ddshapeless] = "ShapelessSolid";
0087   solidShape_[DDSolidShape::ddpseudotrap] = "PseudoTrapezoid";
0088   solidShape_[DDSolidShape::ddtrunctubs] = "TruncatedTube";
0089   solidShape_[DDSolidShape::ddsphere] = "Sphere";
0090   solidShape_[DDSolidShape::ddellipticaltube] = "EllipticalTube";
0091   solidShape_[DDSolidShape::ddcuttubs] = "CutTubs";
0092   solidShape_[DDSolidShape::ddextrudedpolygon] = "ExtrudedPolygon";
0093   solidShape_[DDSolidShape::dd_not_init] = "Unknown";
0094 }
0095 
0096 void PrintGeomSummary::registerConsumes(edm::ConsumesCollector cc) {
0097   ddcompToken_ = cc.esConsumes<DDCompactView, IdealGeometryRecord, edm::Transition::BeginRun>();
0098   G4cout << "PrintGeomSummary::Initialize ESGetToken for DDCompactView" << G4endl;
0099 }
0100 
0101 void PrintGeomSummary::beginRun(edm::EventSetup const& es) {
0102   const DDCompactView* cpv = &es.getData(ddcompToken_);
0103 
0104   const auto& gra = cpv->graph();
0105 
0106   using Graph = DDCompactView::Graph;
0107   using adjl_iterator = Graph::const_adj_iterator;
0108 
0109   solidMap_.clear();
0110   for (adjl_iterator git = gra.begin(); git != gra.end(); ++git) {
0111     const DDLogicalPart& ddLP = gra.nodeData(git);
0112     addSolid(ddLP);
0113     if (!git->empty()) {
0114       // ask for children of ddLP
0115       for (Graph::edge_list::const_iterator cit = git->begin(); cit != git->end(); ++cit) {
0116         const DDLogicalPart& ddcurLP = gra.nodeData(cit->first);
0117         addSolid(ddcurLP);
0118       }
0119     }
0120   }
0121   G4cout << "Finds " << solidMap_.size() << " different solids in the tree" << G4endl;
0122 }
0123 
0124 void PrintGeomSummary::update(const BeginOfRun* run) {
0125   theTopPV_ = getTopPV();
0126   if (theTopPV_) {
0127     lvs_.clear();
0128     sls_.clear();
0129     touch_.clear();
0130     fillLV(theTopPV_->GetLogicalVolume());
0131     std::string name = theTopPV_->GetName();
0132     dumpSummary(G4cout, name);
0133 
0134     pvs_.clear();
0135     fillPV(theTopPV_);
0136     G4cout << " Number of G4VPhysicalVolume's for " << name << ": " << pvs_.size() << G4endl;
0137 
0138     for (unsigned int k = 0; k < nodeNames_.size(); ++k) {
0139       const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
0140       std::vector<G4LogicalVolume*>::const_iterator lvcite;
0141       for (lvcite = lvs->begin(); lvcite != lvs->end(); lvcite++) {
0142         if ((*lvcite)->GetName() == (G4String)(nodeNames_[k])) {
0143           lvs_.clear();
0144           sls_.clear();
0145           touch_.clear();
0146           fillLV(*lvcite);
0147           dumpSummary(G4cout, nodeNames_[k]);
0148         }
0149       }
0150       const G4PhysicalVolumeStore* pvs = G4PhysicalVolumeStore::GetInstance();
0151       std::vector<G4VPhysicalVolume*>::const_iterator pvcite;
0152       for (pvcite = pvs->begin(); pvcite != pvs->end(); pvcite++) {
0153         if ((*pvcite)->GetName() == (G4String)(nodeNames_[k])) {
0154           pvs_.clear();
0155           fillPV(*pvcite);
0156           G4cout << " Number of G4VPhysicalVolume's for " << nodeNames_[k] << ": " << pvs_.size() << G4endl;
0157         }
0158       }
0159     }
0160   }
0161 }
0162 
0163 void PrintGeomSummary::addSolid(const DDLogicalPart& part) {
0164   const DDSolid& solid = part.solid();
0165   std::map<DDSolidShape, std::string>::iterator it = solidShape_.find(solid.shape());
0166   std::string name = solid.name().name();
0167   if (it == solidShape_.end())
0168     solidMap_[name] = DDSolidShape::dd_not_init;
0169   else
0170     solidMap_[name] = it->first;
0171   //G4cout << "Solid " << name << " is of shape " << solidMap_[name] << G4endl;
0172 }
0173 
0174 void PrintGeomSummary::fillLV(G4LogicalVolume* lv) {
0175   if (std::find(lvs_.begin(), lvs_.end(), lv) == lvs_.end())
0176     lvs_.push_back(lv);
0177   G4VSolid* sl = lv->GetSolid();
0178   if (std::find(sls_.begin(), sls_.end(), sl) == sls_.end())
0179     sls_.push_back(sl);
0180   touch_.push_back(lv);
0181   for (int ii = 0; ii < (int)(lv->GetNoDaughters()); ii++)
0182     fillLV(lv->GetDaughter(ii)->GetLogicalVolume());
0183 }
0184 
0185 void PrintGeomSummary::fillPV(G4VPhysicalVolume* pv) {
0186   if (std::find(pvs_.begin(), pvs_.end(), pv) == pvs_.end())
0187     pvs_.push_back(pv);
0188   for (int ii = 0; ii < (int)(pv->GetLogicalVolume()->GetNoDaughters()); ii++)
0189     fillPV(pv->GetLogicalVolume()->GetDaughter(ii));
0190 }
0191 
0192 void PrintGeomSummary::dumpSummary(std::ostream& out, std::string name) {
0193   //---------- Dump number of objects of each class
0194   out << G4endl << G4endl << "@@@@@@@@@@@@@@@@@@ Dumping Summary For Node " << name << G4endl;
0195   out << " Number of G4VSolid's: " << sls_.size() << G4endl;
0196   out << " Number of G4LogicalVolume's: " << lvs_.size() << G4endl;
0197   out << " Number of Touchable's: " << touch_.size() << G4endl;
0198   //First the solids
0199   out << G4endl << "Occurence of each type of shape among Solids" << G4endl;
0200   kount_.clear();
0201   for (std::vector<G4VSolid*>::iterator it = sls_.begin(); it != sls_.end(); ++it) {
0202     std::string name = (*it)->GetName();
0203     addName(name);
0204   }
0205   printSummary(out);
0206   //Then the logical volumes
0207   out << G4endl << "Occurence of each type of shape among Logical Volumes" << G4endl;
0208   kount_.clear();
0209   for (std::vector<G4LogicalVolume*>::iterator it = lvs_.begin(); it != lvs_.end(); ++it) {
0210     std::string name = ((*it)->GetSolid())->GetName();
0211     addName(name);
0212   }
0213   printSummary(out);
0214   //Finally the touchables
0215   out << G4endl << "Occurence of each type of shape among Touchables" << G4endl;
0216   kount_.clear();
0217   for (std::vector<G4LogicalVolume*>::iterator it = touch_.begin(); it != touch_.end(); ++it) {
0218     std::string name = ((*it)->GetSolid())->GetName();
0219     addName(name);
0220   }
0221   printSummary(out);
0222 }
0223 
0224 G4VPhysicalVolume* PrintGeomSummary::getTopPV() {
0225   return G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking()->GetWorldVolume();
0226 }
0227 
0228 void PrintGeomSummary::addName(std::string name) {
0229   bool refl(false);
0230   if (name.find("_refl") < name.size()) {
0231     refl = true;
0232     name = name.substr(0, (name.find("_refl")));
0233   }
0234   std::map<std::string, DDSolidShape>::const_iterator jt = solidMap_.find(name);
0235   DDSolidShape shape = (jt == solidMap_.end()) ? DDSolidShape::dd_not_init : jt->second;
0236   std::map<DDSolidShape, std::pair<int, int>>::iterator itr = kount_.find(shape);
0237   if (itr == kount_.end()) {
0238     kount_[shape] = (refl) ? std::pair<int, int>(0, 1) : std::pair<int, int>(1, 0);
0239   } else {
0240     kount_[shape] = (refl) ? std::pair<int, int>(((itr->second).first), ++((itr->second).second))
0241                            : std::pair<int, int>(++((itr->second).first), ((itr->second).second));
0242   }
0243 }
0244 
0245 void PrintGeomSummary::printSummary(std::ostream& out) {
0246   int k(0);
0247   for (std::map<DDSolidShape, std::pair<int, int>>::iterator itr = kount_.begin(); itr != kount_.end(); ++itr, ++k) {
0248     std::string shape = solidShape_[itr->first];
0249     out << "Shape [" << k << "]  " << shape << " # " << (itr->second).first << " : " << (itr->second).second << G4endl;
0250   }
0251 }
0252 
0253 #include "SimG4Core/Watcher/interface/SimWatcherFactory.h"
0254 #include "FWCore/PluginManager/interface/ModuleDef.h"
0255 
0256 DEFINE_SIMWATCHER(PrintGeomSummary);