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
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
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
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
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
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
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);