File indexing completed on 2024-04-06 12:30:29
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
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
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
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
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
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
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);