Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-11-30 10:17:34

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   Graph::index_type i = 0;
0110   solidMap_.clear();
0111   for (adjl_iterator git = gra.begin(); git != gra.end(); ++git) {
0112     const DDLogicalPart& ddLP = gra.nodeData(git);
0113     addSolid(ddLP);
0114     ++i;
0115     if (!git->empty()) {
0116       // ask for children of ddLP
0117       for (Graph::edge_list::const_iterator cit = git->begin(); cit != git->end(); ++cit) {
0118         const DDLogicalPart& ddcurLP = gra.nodeData(cit->first);
0119         addSolid(ddcurLP);
0120       }
0121     }
0122   }
0123   G4cout << "Finds " << solidMap_.size() << " different solids in the tree" << G4endl;
0124 }
0125 
0126 void PrintGeomSummary::update(const BeginOfRun* run) {
0127   theTopPV_ = getTopPV();
0128   if (theTopPV_) {
0129     lvs_.clear();
0130     sls_.clear();
0131     touch_.clear();
0132     fillLV(theTopPV_->GetLogicalVolume());
0133     std::string name = theTopPV_->GetName();
0134     dumpSummary(G4cout, name);
0135 
0136     pvs_.clear();
0137     fillPV(theTopPV_);
0138     G4cout << " Number of G4VPhysicalVolume's for " << name << ": " << pvs_.size() << G4endl;
0139 
0140     for (unsigned int k = 0; k < nodeNames_.size(); ++k) {
0141       const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
0142       std::vector<G4LogicalVolume*>::const_iterator lvcite;
0143       for (lvcite = lvs->begin(); lvcite != lvs->end(); lvcite++) {
0144         if ((*lvcite)->GetName() == (G4String)(nodeNames_[k])) {
0145           lvs_.clear();
0146           sls_.clear();
0147           touch_.clear();
0148           fillLV(*lvcite);
0149           dumpSummary(G4cout, nodeNames_[k]);
0150         }
0151       }
0152       const G4PhysicalVolumeStore* pvs = G4PhysicalVolumeStore::GetInstance();
0153       std::vector<G4VPhysicalVolume*>::const_iterator pvcite;
0154       for (pvcite = pvs->begin(); pvcite != pvs->end(); pvcite++) {
0155         if ((*pvcite)->GetName() == (G4String)(nodeNames_[k])) {
0156           pvs_.clear();
0157           fillPV(*pvcite);
0158           G4cout << " Number of G4VPhysicalVolume's for " << nodeNames_[k] << ": " << pvs_.size() << G4endl;
0159         }
0160       }
0161     }
0162   }
0163 }
0164 
0165 void PrintGeomSummary::addSolid(const DDLogicalPart& part) {
0166   const DDSolid& solid = part.solid();
0167   std::map<DDSolidShape, std::string>::iterator it = solidShape_.find(solid.shape());
0168   std::string name = solid.name().name();
0169   if (it == solidShape_.end())
0170     solidMap_[name] = DDSolidShape::dd_not_init;
0171   else
0172     solidMap_[name] = it->first;
0173   //G4cout << "Solid " << name << " is of shape " << solidMap_[name] << G4endl;
0174 }
0175 
0176 void PrintGeomSummary::fillLV(G4LogicalVolume* lv) {
0177   if (std::find(lvs_.begin(), lvs_.end(), lv) == lvs_.end())
0178     lvs_.push_back(lv);
0179   G4VSolid* sl = lv->GetSolid();
0180   if (std::find(sls_.begin(), sls_.end(), sl) == sls_.end())
0181     sls_.push_back(sl);
0182   touch_.push_back(lv);
0183   for (int ii = 0; ii < (int)(lv->GetNoDaughters()); ii++)
0184     fillLV(lv->GetDaughter(ii)->GetLogicalVolume());
0185 }
0186 
0187 void PrintGeomSummary::fillPV(G4VPhysicalVolume* pv) {
0188   if (std::find(pvs_.begin(), pvs_.end(), pv) == pvs_.end())
0189     pvs_.push_back(pv);
0190   for (int ii = 0; ii < (int)(pv->GetLogicalVolume()->GetNoDaughters()); ii++)
0191     fillPV(pv->GetLogicalVolume()->GetDaughter(ii));
0192 }
0193 
0194 void PrintGeomSummary::dumpSummary(std::ostream& out, std::string name) {
0195   //---------- Dump number of objects of each class
0196   out << G4endl << G4endl << "@@@@@@@@@@@@@@@@@@ Dumping Summary For Node " << name << G4endl;
0197   out << " Number of G4VSolid's: " << sls_.size() << G4endl;
0198   out << " Number of G4LogicalVolume's: " << lvs_.size() << G4endl;
0199   out << " Number of Touchable's: " << touch_.size() << G4endl;
0200   //First the solids
0201   out << G4endl << "Occurence of each type of shape among Solids" << G4endl;
0202   kount_.clear();
0203   for (std::vector<G4VSolid*>::iterator it = sls_.begin(); it != sls_.end(); ++it) {
0204     std::string name = (*it)->GetName();
0205     addName(name);
0206   }
0207   printSummary(out);
0208   //Then the logical volumes
0209   out << G4endl << "Occurence of each type of shape among Logical Volumes" << G4endl;
0210   kount_.clear();
0211   for (std::vector<G4LogicalVolume*>::iterator it = lvs_.begin(); it != lvs_.end(); ++it) {
0212     std::string name = ((*it)->GetSolid())->GetName();
0213     addName(name);
0214   }
0215   printSummary(out);
0216   //Finally the touchables
0217   out << G4endl << "Occurence of each type of shape among Touchables" << G4endl;
0218   kount_.clear();
0219   for (std::vector<G4LogicalVolume*>::iterator it = touch_.begin(); it != touch_.end(); ++it) {
0220     std::string name = ((*it)->GetSolid())->GetName();
0221     addName(name);
0222   }
0223   printSummary(out);
0224 }
0225 
0226 G4VPhysicalVolume* PrintGeomSummary::getTopPV() {
0227   return G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking()->GetWorldVolume();
0228 }
0229 
0230 void PrintGeomSummary::addName(std::string name) {
0231   bool refl(false);
0232   if (name.find("_refl") < name.size()) {
0233     refl = true;
0234     name = name.substr(0, (name.find("_refl")));
0235   }
0236   std::map<std::string, DDSolidShape>::const_iterator jt = solidMap_.find(name);
0237   DDSolidShape shape = (jt == solidMap_.end()) ? DDSolidShape::dd_not_init : jt->second;
0238   std::map<DDSolidShape, std::pair<int, int>>::iterator itr = kount_.find(shape);
0239   if (itr == kount_.end()) {
0240     kount_[shape] = (refl) ? std::pair<int, int>(0, 1) : std::pair<int, int>(1, 0);
0241   } else {
0242     kount_[shape] = (refl) ? std::pair<int, int>(((itr->second).first), ++((itr->second).second))
0243                            : std::pair<int, int>(++((itr->second).first), ((itr->second).second));
0244   }
0245 }
0246 
0247 void PrintGeomSummary::printSummary(std::ostream& out) {
0248   int k(0);
0249   for (std::map<DDSolidShape, std::pair<int, int>>::iterator itr = kount_.begin(); itr != kount_.end(); ++itr, ++k) {
0250     std::string shape = solidShape_[itr->first];
0251     out << "Shape [" << k << "]  " << shape << " # " << (itr->second).first << " : " << (itr->second).second << G4endl;
0252   }
0253 }
0254 
0255 #include "SimG4Core/Watcher/interface/SimWatcherFactory.h"
0256 #include "FWCore/PluginManager/interface/ModuleDef.h"
0257 
0258 DEFINE_SIMWATCHER(PrintGeomSummary);