File indexing completed on 2023-03-17 11:25:03
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 "DataFormats/Math/interface/angle_units.h"
0008 #include "Geometry/Records/interface/IdealGeometryRecord.h"
0009 #include "DetectorDescription/Core/interface/DDCompactView.h"
0010 #include "DetectorDescription/Core/interface/DDFilter.h"
0011 #include "DetectorDescription/Core/interface/DDFilteredView.h"
0012 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
0013 #include "DetectorDescription/Core/interface/DDSplit.h"
0014 #include "DetectorDescription/Core/interface/DDValue.h"
0015 #include "DetectorDescription/DDCMS/interface/DDCompactView.h"
0016 #include "DetectorDescription/DDCMS/interface/DDFilteredView.h"
0017
0018 #include "DD4hep/DD4hepUnits.h"
0019 #include "DD4hep/Filter.h"
0020
0021 #include "G4LogicalVolumeStore.hh"
0022 #include "G4LogicalVolume.hh"
0023 #include "G4VSolid.hh"
0024 #include "G4Material.hh"
0025 #include "G4NavigationHistory.hh"
0026 #include "G4PhysicalVolumeStore.hh"
0027 #include "G4Region.hh"
0028 #include "G4RegionStore.hh"
0029 #include "G4Run.hh"
0030 #include "G4Track.hh"
0031 #include "G4TransportationManager.hh"
0032 #include "G4UserLimits.hh"
0033 #include "G4VisAttributes.hh"
0034 #include "G4VPhysicalVolume.hh"
0035
0036 #include <algorithm>
0037 #include <fstream>
0038 #include <map>
0039 #include <set>
0040 #include <string>
0041 #include <vector>
0042
0043 using angle_units::operators::convertRadToDeg;
0044
0045 typedef std::multimap<G4LogicalVolume *, G4VPhysicalVolume *, std::less<G4LogicalVolume *> > mmlvpv;
0046
0047 class PrintGeomInfoAction : public SimWatcher, public Observer<const BeginOfRun *> {
0048 public:
0049 PrintGeomInfoAction(edm::ParameterSet const &p);
0050 ~PrintGeomInfoAction() override = default;
0051
0052 void registerConsumes(edm::ConsumesCollector) override;
0053 void beginRun(edm::EventSetup const &) override;
0054
0055 private:
0056 void update(const BeginOfRun *run) override;
0057 void dumpSummary(std::ostream &out = G4cout);
0058 void dumpG4LVList(std::ostream &out = G4cout);
0059 void dumpG4LVTree(std::ostream &out = G4cout);
0060 void dumpG4Region(std::ostream &out = G4cout);
0061 void dumpMaterialList(std::ostream &out = G4cout);
0062 void dumpG4LVLeaf(G4LogicalVolume *lv, unsigned int leafDepth, unsigned int count, std::ostream &out = G4cout);
0063 int countNoTouchables();
0064 void add1touchable(G4LogicalVolume *lv, int &nTouch);
0065 void dumpHierarchyTreePVLV(std::ostream &out = G4cout);
0066 void dumpHierarchyLeafPVLV(G4LogicalVolume *lv, unsigned int leafDepth, std::ostream &out = G4cout);
0067 void dumpLV(G4LogicalVolume *lv, unsigned int leafDepth, std::ostream &out = G4cout);
0068 void dumpPV(G4VPhysicalVolume *pv, unsigned int leafDepth, std::ostream &out = G4cout);
0069 void dumpSolid(G4VSolid *sol, unsigned int leafDepth, std::ostream &out = G4cout);
0070 void dumpTouch(G4VPhysicalVolume *pv, unsigned int leafDepth, std::ostream &out = G4cout);
0071 void dumpInFile();
0072 void getTouch(G4VPhysicalVolume *pv, unsigned int leafDepth, unsigned int copym, std::vector<std::string> &touches);
0073 std::string spacesFromLeafDepth(unsigned int leafDepth);
0074 G4VPhysicalVolume *getTopPV();
0075 G4LogicalVolume *getTopLV();
0076
0077 private:
0078 edm::ESGetToken<cms::DDCompactView, IdealGeometryRecord> dd4hepToken_;
0079 edm::ESGetToken<DDCompactView, IdealGeometryRecord> dddToken_;
0080
0081 bool dumpSummary_, dumpLVTree_, dumpLVList_, dumpMaterial_;
0082 bool dumpLV_, dumpSolid_, dumpAtts_, dumpPV_;
0083 bool dumpRotation_, dumpReplica_, dumpTouch_;
0084 bool dumpSense_, dumpParams_, dumpRegion_, dd4hep_;
0085 std::string name_;
0086 int nchar_;
0087 std::string fileMat_, fileSolid_, fileLV_, filePV_, fileTouch_, fileRegion_;
0088 bool fileDetail_;
0089 std::vector<std::string> names_;
0090 G4VPhysicalVolume *theTopPV_;
0091 G4NavigationHistory fHistory_;
0092 };
0093
0094 PrintGeomInfoAction::PrintGeomInfoAction(const edm::ParameterSet &p) {
0095 dumpSummary_ = p.getUntrackedParameter<bool>("DumpSummary", true);
0096 dumpLVTree_ = p.getUntrackedParameter<bool>("DumpLVTree", true);
0097 dumpLVList_ = p.getUntrackedParameter<bool>("DumpLVList", false);
0098 dumpMaterial_ = p.getUntrackedParameter<bool>("DumpMaterial", false);
0099 dumpLV_ = p.getUntrackedParameter<bool>("DumpLV", false);
0100 dumpSolid_ = p.getUntrackedParameter<bool>("DumpSolid", false);
0101 dumpAtts_ = p.getUntrackedParameter<bool>("DumpAttributes", false);
0102 dumpPV_ = p.getUntrackedParameter<bool>("DumpPV", false);
0103 dumpRotation_ = p.getUntrackedParameter<bool>("DumpRotation", false);
0104 dumpReplica_ = p.getUntrackedParameter<bool>("DumpReplica", false);
0105 dumpTouch_ = p.getUntrackedParameter<bool>("DumpTouch", false);
0106 dumpSense_ = p.getUntrackedParameter<bool>("DumpSense", false);
0107 dumpParams_ = p.getUntrackedParameter<bool>("DumpParams", false);
0108 dumpRegion_ = p.getUntrackedParameter<bool>("DumpRegion", false);
0109 dd4hep_ = p.getUntrackedParameter<bool>("DD4hep", false);
0110 name_ = p.getUntrackedParameter<std::string>("Name", "*");
0111 names_ = p.getUntrackedParameter<std::vector<std::string> >("Names");
0112 fileMat_ = p.getUntrackedParameter<std::string>("MaterialFileName", "");
0113 fileSolid_ = p.getUntrackedParameter<std::string>("SolidFileName", "");
0114 fileLV_ = p.getUntrackedParameter<std::string>("LVFileName", "");
0115 filePV_ = p.getUntrackedParameter<std::string>("PVFileName", "");
0116 fileTouch_ = p.getUntrackedParameter<std::string>("TouchFileName", "");
0117 fileRegion_ = p.getUntrackedParameter<std::string>("RegionFileName", "");
0118 fileDetail_ = p.getUntrackedParameter<bool>("FileDetail", false);
0119 nchar_ = name_.find('*');
0120 name_.assign(name_, 0, nchar_);
0121 G4cout << "PrintGeomInfoAction:: initialised for dd4hep " << dd4hep_ << " with verbosity levels:"
0122 << " Summary " << dumpSummary_ << " LVTree " << dumpLVTree_ << " LVList " << dumpLVList_ << " Material "
0123 << dumpMaterial_ << G4endl << " "
0124 << " LV " << dumpLV_ << " Solid " << dumpSolid_ << " Attribs " << dumpAtts_ << G4endl
0125 << " "
0126 << " PV " << dumpPV_ << " Rotation " << dumpRotation_ << " Replica " << dumpReplica_ << G4endl
0127 << " "
0128 << " Touchable " << dumpTouch_ << " Rgion " << dumpRegion_ << " for names (0-" << nchar_ << ") = " << name_
0129 << G4endl << " "
0130 << " Sensitive " << dumpSense_ << " Files " << fileMat_ << ":" << fileSolid_ << ":" << fileLV_ << ":"
0131 << filePV_ << ":" << fileTouch_ << " FileDetail " << fileDetail_ << " fileRegion " << fileRegion_ << G4endl
0132 << " for " << names_.size() << " names:";
0133 for (unsigned int i = 0; i < names_.size(); i++)
0134 G4cout << " " << names_[i];
0135 G4cout << G4endl;
0136 }
0137
0138 void PrintGeomInfoAction::registerConsumes(edm::ConsumesCollector cc) {
0139 if (dd4hep_) {
0140 dd4hepToken_ = cc.esConsumes<cms::DDCompactView, IdealGeometryRecord, edm::Transition::BeginRun>();
0141 G4cout << "PrintGeomInfoAction::Initialize ESGetToken for cms::DDCompactView" << G4endl;
0142 } else {
0143 dddToken_ = cc.esConsumes<DDCompactView, IdealGeometryRecord, edm::Transition::BeginRun>();
0144 G4cout << "PrintGeomInfoAction::Initialize ESGetToken for DDCompactView" << G4endl;
0145 }
0146 }
0147
0148 void PrintGeomInfoAction::beginRun(edm::EventSetup const &es) {
0149 if (dumpSense_) {
0150 if (dd4hep_) {
0151 const cms::DDCompactView *pDD = &es.getData(dd4hepToken_);
0152
0153 G4cout << "PrintGeomInfoAction::Get Printout of Sensitive Volumes "
0154 << "for " << names_.size() << " Readout Units" << G4endl;
0155 for (unsigned int i = 0; i < names_.size(); i++) {
0156 std::string sd = names_[i];
0157 const cms::DDFilter filter("ReadOutName", sd);
0158 cms::DDFilteredView fv(*pDD, filter);
0159 G4cout << "PrintGeomInfoAction:: Get Filtered view for ReadOutName = " << sd << G4endl;
0160 G4cout << "Lengths are in mm, angles in degrees" << G4endl;
0161
0162 std::string spaces = spacesFromLeafDepth(1);
0163
0164 while (fv.firstChild()) {
0165 auto tran = fv.translation() / dd4hep::mm;
0166 std::vector<int> copy = fv.copyNos();
0167 auto lvname = fv.name();
0168 unsigned int leafDepth = copy.size();
0169 G4cout << leafDepth << spaces << "### VOLUME = " << lvname << " Copy No";
0170 for (unsigned int k = 0; k < leafDepth; ++k)
0171 G4cout << " " << copy[k];
0172 if (dumpParams_) {
0173 G4cout << " parameters";
0174 for (double val : fv.parameters()) {
0175 if (std::abs(val) < 1.0) {
0176 G4cout << std::setprecision(5);
0177 } else
0178 G4cout << std::setprecision(6);
0179 G4cout << " " << val;
0180 }
0181 G4cout << G4endl;
0182 } else {
0183 G4cout << " Centre at " << tran << " (r = " << tran.Rho() << ", phi = " << convertRadToDeg(tran.phi())
0184 << ")" << G4endl;
0185 }
0186 }
0187 }
0188 } else {
0189 const DDCompactView *pDD = &es.getData(dddToken_);
0190
0191 G4cout << "PrintGeomInfoAction::Get Printout of Sensitive Volumes "
0192 << "for " << names_.size() << " Readout Units" << G4endl;
0193 for (unsigned int i = 0; i < names_.size(); i++) {
0194 std::string attribute = "ReadOutName";
0195 std::string sd = names_[i];
0196 DDSpecificsMatchesValueFilter filter{DDValue(attribute, sd, 0)};
0197 DDFilteredView fv(*pDD, filter);
0198 G4cout << "PrintGeomInfoAction:: Get Filtered view for " << attribute << " = " << sd << G4endl;
0199 G4cout << "Lengths are in mm, angles in degrees" << G4endl;
0200 bool dodet = fv.firstChild();
0201
0202 std::string spaces = spacesFromLeafDepth(1);
0203
0204 while (dodet) {
0205 const DDLogicalPart &log = fv.logicalPart();
0206 std::string lvname = log.name().name();
0207 DDTranslation tran = fv.translation();
0208 std::vector<int> copy = fv.copyNumbers();
0209
0210 unsigned int leafDepth = copy.size();
0211 G4cout << leafDepth << spaces << "### VOLUME = " << lvname << " Copy No";
0212 for (int k = leafDepth - 1; k >= 0; k--)
0213 G4cout << " " << copy[k];
0214 G4cout << " Centre at " << tran << " (r = " << tran.Rho() << ", phi = " << convertRadToDeg(tran.phi()) << ")"
0215 << G4endl;
0216 dodet = fv.next();
0217 }
0218 }
0219 }
0220 }
0221 }
0222
0223 void PrintGeomInfoAction::update(const BeginOfRun *run) {
0224
0225 theTopPV_ = getTopPV();
0226
0227 if (dumpSummary_)
0228 dumpSummary(G4cout);
0229 if (dumpLVTree_)
0230 dumpG4LVTree(G4cout);
0231
0232
0233 if (dumpMaterial_)
0234 dumpMaterialList(G4cout);
0235 if (dumpLVList_)
0236 dumpG4LVList(G4cout);
0237
0238
0239 if (dumpLV_ || dumpPV_ || dumpTouch_)
0240 dumpHierarchyTreePVLV(G4cout);
0241
0242
0243 if (dumpRegion_)
0244 dumpG4Region(G4cout);
0245
0246 dumpInFile();
0247 }
0248
0249 void PrintGeomInfoAction::dumpSummary(std::ostream &out) {
0250
0251 out << " @@@@@@@@@@@@@@@@@@ Dumping G4 geometry objects Summary " << G4endl;
0252 if (theTopPV_ == nullptr) {
0253 out << " No volume created " << G4endl;
0254 return;
0255 }
0256 out << " @@@ Geometry built inside world volume: " << theTopPV_->GetName() << G4endl;
0257
0258 const G4LogicalVolumeStore *lvs = G4LogicalVolumeStore::GetInstance();
0259 std::vector<G4LogicalVolume *>::const_iterator lvcite;
0260 std::set<G4VSolid *> theSolids;
0261 for (lvcite = lvs->begin(); lvcite != lvs->end(); lvcite++)
0262 theSolids.insert((*lvcite)->GetSolid());
0263 out << " Number of G4VSolid's: " << theSolids.size() << G4endl;
0264 out << " Number of G4LogicalVolume's: " << lvs->size() << G4endl;
0265 const G4PhysicalVolumeStore *pvs = G4PhysicalVolumeStore::GetInstance();
0266 out << " Number of G4VPhysicalVolume's: " << pvs->size() << G4endl;
0267 out << " Number of Touchable's: " << countNoTouchables() << G4endl;
0268 const G4MaterialTable *matTab = G4Material::GetMaterialTable();
0269 out << " Number of G4Material's: " << matTab->size() << G4endl;
0270 const G4RegionStore *regs = G4RegionStore::GetInstance();
0271 out << " Number of G4Region's: " << regs->size() << G4endl;
0272 }
0273
0274 void PrintGeomInfoAction::dumpG4LVList(std::ostream &out) {
0275 out << " @@@@@@@@@@@@@@@@ DUMPING G4LogicalVolume's List " << G4endl;
0276 const G4LogicalVolumeStore *lvs = G4LogicalVolumeStore::GetInstance();
0277 std::vector<G4LogicalVolume *>::const_iterator lvcite;
0278 for (lvcite = lvs->begin(); lvcite != lvs->end(); lvcite++)
0279 out << "LV:" << (*lvcite)->GetName() << "\tMaterial: " << (*lvcite)->GetMaterial()->GetName() << G4endl;
0280 }
0281
0282 void PrintGeomInfoAction::dumpG4LVTree(std::ostream &out) {
0283 out << " @@@@@@@@@@@@@@@@ DUMPING G4LogicalVolume's Tree " << G4endl;
0284 G4LogicalVolume *lv = getTopLV();
0285 dumpG4LVLeaf(lv, 0, 1, out);
0286 }
0287
0288 void PrintGeomInfoAction::dumpG4Region(std::ostream &out) {
0289 out << " @@@@@@@@@@@@@@@@ DUMPING G4Region Tree " << G4endl;
0290 const G4RegionStore *regs = G4RegionStore::GetInstance();
0291 std::vector<G4Region *>::const_iterator regite;
0292 for (regite = regs->begin(); regite != regs->end(); regite++)
0293 out << "Region: " << (*regite)->GetName() << " with " << (*regite)->GetNumberOfMaterials() << " materials and "
0294 << (*regite)->GetNumberOfRootVolumes() << " root volumes" << G4endl;
0295 }
0296
0297 void PrintGeomInfoAction::dumpMaterialList(std::ostream &out) {
0298 out << " @@@@@@@@@@@@@@@@ DUMPING G4Material List ";
0299 const G4MaterialTable *matTab = G4Material::GetMaterialTable();
0300 out << " with " << matTab->size() << " materials " << G4endl;
0301 std::vector<G4Material *>::const_iterator matite;
0302 for (matite = matTab->begin(); matite != matTab->end(); matite++)
0303 out << "Material: " << (*matite) << G4endl;
0304 }
0305
0306 void PrintGeomInfoAction::dumpG4LVLeaf(G4LogicalVolume *lv,
0307 unsigned int leafDepth,
0308 unsigned int count,
0309 std::ostream &out) {
0310 for (unsigned int ii = 0; ii < leafDepth; ii++)
0311 out << " ";
0312 out << " LV:(" << leafDepth << ") " << lv->GetName() << " (" << count << ")" << G4endl;
0313
0314 std::map<G4LogicalVolume *, unsigned int> lvCount;
0315 std::map<G4LogicalVolume *, unsigned int>::const_iterator cite;
0316 int siz = lv->GetNoDaughters();
0317 for (int ii = 0; ii < siz; ii++) {
0318 cite = lvCount.find(lv->GetDaughter(ii)->GetLogicalVolume());
0319 if (cite != lvCount.end())
0320 lvCount[cite->first] = (cite->second) + 1;
0321 else
0322 lvCount.insert(std::pair<G4LogicalVolume *, unsigned int>(lv->GetDaughter(ii)->GetLogicalVolume(), 1));
0323 }
0324 for (cite = lvCount.begin(); cite != lvCount.end(); cite++)
0325 dumpG4LVLeaf((cite->first), leafDepth + 1, (cite->second), out);
0326 }
0327
0328 int PrintGeomInfoAction::countNoTouchables() {
0329 int nTouch = 0;
0330 G4LogicalVolume *lv = getTopLV();
0331 add1touchable(lv, nTouch);
0332 return nTouch;
0333 }
0334
0335 void PrintGeomInfoAction::add1touchable(G4LogicalVolume *lv, int &nTouch) {
0336 int siz = lv->GetNoDaughters();
0337 for (int ii = 0; ii < siz; ii++)
0338 add1touchable(lv->GetDaughter(ii)->GetLogicalVolume(), ++nTouch);
0339 }
0340
0341 void PrintGeomInfoAction::dumpHierarchyTreePVLV(std::ostream &out) {
0342
0343
0344
0345
0346
0347
0348 G4LogicalVolume *topLV = getTopLV();
0349
0350
0351 dumpHierarchyLeafPVLV(topLV, 0, out);
0352 dumpPV(theTopPV_, 0, out);
0353
0354
0355 if (dumpTouch_)
0356 dumpTouch(theTopPV_, 0, out);
0357 }
0358
0359 void PrintGeomInfoAction::dumpHierarchyLeafPVLV(G4LogicalVolume *lv, unsigned int leafDepth, std::ostream &out) {
0360
0361 dumpLV(lv, leafDepth, out);
0362
0363
0364 mmlvpv lvpvDaughters;
0365 std::set<G4LogicalVolume *> lvDaughters;
0366 int NoDaughters = lv->GetNoDaughters();
0367 while ((NoDaughters--) > 0) {
0368 G4VPhysicalVolume *pvD = lv->GetDaughter(NoDaughters);
0369 lvpvDaughters.insert(mmlvpv::value_type(pvD->GetLogicalVolume(), pvD));
0370 lvDaughters.insert(pvD->GetLogicalVolume());
0371 }
0372
0373 std::set<G4LogicalVolume *>::const_iterator scite;
0374 mmlvpv::const_iterator mmcite;
0375
0376
0377 for (scite = lvDaughters.begin(); scite != lvDaughters.end(); scite++) {
0378 std::pair<mmlvpv::iterator, mmlvpv::iterator> mmER = lvpvDaughters.equal_range(*scite);
0379
0380 for (mmcite = mmER.first; mmcite != mmER.second; mmcite++)
0381 dumpPV((*mmcite).second, leafDepth + 1, out);
0382
0383 dumpHierarchyLeafPVLV(*scite, leafDepth + 1, out);
0384 }
0385 }
0386
0387 void PrintGeomInfoAction::dumpLV(G4LogicalVolume *lv, unsigned int leafDepth, std::ostream &out) {
0388 std::string spaces = spacesFromLeafDepth(leafDepth);
0389
0390
0391 if (dumpLV_) {
0392 out << leafDepth << spaces << "$$$ VOLUME = " << lv->GetName() << " Solid: " << lv->GetSolid()->GetName()
0393 << " MATERIAL: " << lv->GetMaterial()->GetName() << G4endl;
0394 if (dumpSolid_)
0395 dumpSolid(lv->GetSolid(), leafDepth, out);
0396
0397
0398
0399 if (dumpAtts_) {
0400
0401 const G4VisAttributes *fVA = lv->GetVisAttributes();
0402 if (fVA != nullptr) {
0403 out << spaces << " VISUALISATION ATTRIBUTES: " << G4endl;
0404 out << spaces << " IsVisible " << fVA->IsVisible() << G4endl;
0405 out << spaces << " IsDaughtersInvisible " << fVA->IsDaughtersInvisible() << G4endl;
0406 out << spaces << " Colour " << fVA->GetColour() << G4endl;
0407 out << spaces << " LineStyle " << fVA->GetLineStyle() << G4endl;
0408 out << spaces << " LineWidth " << fVA->GetLineWidth() << G4endl;
0409 out << spaces << " IsForceDrawingStyle " << fVA->IsForceDrawingStyle() << G4endl;
0410 out << spaces << " ForcedDrawingStyle " << fVA->GetForcedDrawingStyle() << G4endl;
0411 }
0412
0413
0414 G4UserLimits *fUL = lv->GetUserLimits();
0415 G4Track dummy;
0416 if (fUL != nullptr) {
0417 out << spaces << " MaxAllowedStep " << fUL->GetMaxAllowedStep(dummy) << G4endl;
0418 out << spaces << " UserMaxTrackLength " << fUL->GetUserMaxTrackLength(dummy) << G4endl;
0419 out << spaces << " UserMaxTime " << fUL->GetUserMaxTime(dummy) << G4endl;
0420 out << spaces << " UserMinEkine " << fUL->GetUserMinEkine(dummy) << G4endl;
0421 out << spaces << " UserMinRange " << fUL->GetUserMinRange(dummy) << G4endl;
0422 }
0423
0424
0425 if (lv->GetSensitiveDetector())
0426 out << spaces << " IS SENSITIVE DETECTOR " << G4endl;
0427 if (lv->GetFieldManager())
0428 out << spaces << " FIELD ON " << G4endl;
0429
0430
0431 out << spaces << " Quality for optimisation, average number of voxels to be spent per content "
0432 << lv->GetSmartless() << G4endl;
0433
0434
0435 if (lv->GetFastSimulationManager())
0436 out << spaces << " Logical Volume is an envelope for a FastSimulationManager " << G4endl;
0437 out << spaces << " Weight used in the event biasing technique = " << lv->GetBiasWeight() << G4endl;
0438 }
0439 }
0440 }
0441
0442 void PrintGeomInfoAction::dumpPV(G4VPhysicalVolume *pv, unsigned int leafDepth, std::ostream &out) {
0443 std::string spaces = spacesFromLeafDepth(leafDepth);
0444
0445
0446 if (dumpPV_) {
0447 std::string mother = "World";
0448 if (pv->GetMotherLogical())
0449 mother = pv->GetMotherLogical()->GetName();
0450 out << leafDepth << spaces << "### VOLUME = " << pv->GetName() << " Copy No " << pv->GetCopyNo() << " in " << mother
0451 << " at " << pv->GetTranslation();
0452 }
0453 if (!pv->IsReplicated()) {
0454 if (dumpPV_) {
0455 if (pv->GetRotation() == nullptr)
0456 out << " with no rotation" << G4endl;
0457 else if (!dumpRotation_)
0458 out << " with rotation" << G4endl;
0459 else
0460 out << " with rotation " << *(pv->GetRotation()) << G4endl;
0461 }
0462 } else {
0463 if (dumpReplica_) {
0464 out << spaces << " It is replica: " << G4endl;
0465 EAxis axis;
0466 int nReplicas;
0467 double width;
0468 double offset;
0469 bool consuming;
0470 pv->GetReplicationData(axis, nReplicas, width, offset, consuming);
0471 out << spaces << " axis " << axis << G4endl << spaces << " nReplicas " << nReplicas << G4endl;
0472 if (pv->GetParameterisation() != nullptr)
0473 out << spaces << " It is parameterisation " << G4endl;
0474 else
0475 out << spaces << " width " << width << G4endl << spaces << " offset " << offset << G4endl << spaces
0476 << " consuming" << consuming << G4endl;
0477 if (pv->GetParameterisation() != nullptr)
0478 out << spaces << " It is parameterisation " << G4endl;
0479 }
0480 }
0481 }
0482
0483 void PrintGeomInfoAction::dumpSolid(G4VSolid *sol, unsigned int leafDepth, std::ostream &out) {
0484 std::string spaces = spacesFromLeafDepth(leafDepth);
0485 out << spaces << *(sol) << G4endl;
0486 }
0487
0488 void PrintGeomInfoAction::dumpTouch(G4VPhysicalVolume *pv, unsigned int leafDepth, std::ostream &out) {
0489 std::string spaces = spacesFromLeafDepth(leafDepth);
0490 if (leafDepth == 0)
0491 fHistory_.SetFirstEntry(pv);
0492 else
0493 fHistory_.NewLevel(pv, kNormal, pv->GetCopyNo());
0494
0495 G4ThreeVector globalpoint = fHistory_.GetTopTransform().Inverse().TransformPoint(G4ThreeVector(0, 0, 0));
0496 G4LogicalVolume *lv = pv->GetLogicalVolume();
0497
0498 std::string mother = "World";
0499 if (pv->GetMotherLogical())
0500 mother = pv->GetMotherLogical()->GetName();
0501 std::string lvname = lv->GetName();
0502 lvname.assign(lvname, 0, nchar_);
0503 if (lvname == name_)
0504 out << leafDepth << spaces << "### VOLUME = " << lv->GetName() << " Copy No " << pv->GetCopyNo() << " in " << mother
0505 << " global position of centre " << globalpoint << " (r = " << globalpoint.perp()
0506 << ", phi = " << convertRadToDeg(globalpoint.phi()) << ")" << G4endl;
0507
0508 int NoDaughters = lv->GetNoDaughters();
0509 while ((NoDaughters--) > 0) {
0510 G4VPhysicalVolume *pvD = lv->GetDaughter(NoDaughters);
0511 if (!pvD->IsReplicated())
0512 dumpTouch(pvD, leafDepth + 1, out);
0513 }
0514
0515 if (leafDepth > 0)
0516 fHistory_.BackLevel();
0517 }
0518
0519 void PrintGeomInfoAction::dumpInFile() {
0520
0521 if (theTopPV_ != nullptr) {
0522 if (!fileMat_.empty()) {
0523 const G4MaterialTable *matTab = G4Material::GetMaterialTable();
0524 std::ofstream fout(fileMat_.c_str());
0525 for (std::vector<G4Material *>::const_iterator matite = matTab->begin(); matite != matTab->end(); matite++) {
0526 if (!fileDetail_)
0527 fout << (*matite)->GetName() << G4endl;
0528 else
0529 fout << (*matite)->GetName() << " " << (*matite)->GetRadlen() << " " << (*matite)->GetNuclearInterLength()
0530 << G4endl;
0531 }
0532 fout.close();
0533 }
0534 const G4LogicalVolumeStore *lvs = G4LogicalVolumeStore::GetInstance();
0535 if (!fileSolid_.empty()) {
0536 std::ofstream fout(fileSolid_.c_str());
0537 for (std::vector<G4LogicalVolume *>::const_iterator lvcite = lvs->begin(); lvcite != lvs->end(); lvcite++)
0538 if (!fileDetail_)
0539 fout << (*lvcite)->GetSolid()->GetName() << G4endl;
0540 else
0541 fout << (*lvcite)->GetSolid()->GetName() << " " << (*lvcite)->GetSolid()->GetCubicVolume() << G4endl;
0542 fout.close();
0543 }
0544 if (!fileLV_.empty()) {
0545 std::ofstream fout(fileLV_.c_str());
0546 for (std::vector<G4LogicalVolume *>::const_iterator lvcite = lvs->begin(); lvcite != lvs->end(); lvcite++)
0547 if (!fileDetail_)
0548 fout << (*lvcite)->GetName() << G4endl;
0549 else
0550 fout << (*lvcite)->GetName() << " " << (*lvcite)->GetMass(false, false) << G4endl;
0551 fout.close();
0552 }
0553 if (!filePV_.empty()) {
0554 const G4PhysicalVolumeStore *pvs = G4PhysicalVolumeStore::GetInstance();
0555 std::ofstream fout(filePV_.c_str());
0556 for (std::vector<G4VPhysicalVolume *>::const_iterator pvcite = pvs->begin(); pvcite != pvs->end(); pvcite++) {
0557 if (fileDetail_) {
0558 if (dd4hep_)
0559 fout << (*pvcite)->GetName() << " " << (*pvcite)->GetTranslation().x() << " "
0560 << (*pvcite)->GetTranslation().y() << " " << (*pvcite)->GetTranslation().z() << G4endl;
0561 else
0562 fout << (*pvcite)->GetName() << " " << (*pvcite)->GetCopyNo() << " " << (*pvcite)->GetTranslation().x()
0563 << " " << (*pvcite)->GetTranslation().y() << " " << (*pvcite)->GetTranslation().z() << G4endl;
0564 } else {
0565 if (dd4hep_)
0566 fout << (*pvcite)->GetName() << G4endl;
0567 else
0568 fout << (*pvcite)->GetName() << " " << (*pvcite)->GetCopyNo() << G4endl;
0569 }
0570 }
0571 fout.close();
0572 }
0573 if (!fileTouch_.empty()) {
0574 std::ofstream fout(fileTouch_.c_str());
0575 std::vector<std::string> touches;
0576 getTouch(theTopPV_, 0, 1, touches);
0577 std::sort(touches.begin(), touches.end());
0578 for (const auto &touch : touches)
0579 fout << touch << G4endl;
0580 fout.close();
0581 }
0582 if (!fileRegion_.empty()) {
0583 const G4RegionStore *regs = G4RegionStore::GetInstance();
0584 std::ofstream fout(fileRegion_.c_str());
0585 for (std::vector<G4Region *>::const_iterator regite = regs->begin(); regite != regs->end(); regite++) {
0586 if (!fileDetail_)
0587 fout << (*regite)->GetName() << G4endl;
0588 else
0589 fout << (*regite)->GetName() << " " << (*regite)->GetNumberOfMaterials() << " "
0590 << (*regite)->GetNumberOfRootVolumes() << G4endl;
0591 }
0592 fout.close();
0593 }
0594 }
0595 }
0596
0597 void PrintGeomInfoAction::getTouch(G4VPhysicalVolume *pv,
0598 unsigned int leafDepth,
0599 unsigned int copym,
0600 std::vector<std::string> &touches) {
0601 if (leafDepth == 0)
0602 fHistory_.SetFirstEntry(pv);
0603 else
0604 fHistory_.NewLevel(pv, kNormal, pv->GetCopyNo());
0605
0606 std::string mother = "World";
0607 if (pv->GetMotherLogical())
0608 mother = static_cast<std::string>(dd4hep::dd::noNamespace(pv->GetMotherLogical()->GetName()));
0609
0610 G4LogicalVolume *lv = pv->GetLogicalVolume();
0611 std::string lvname = static_cast<std::string>(dd4hep::dd::noNamespace(lv->GetName()));
0612 unsigned int copy = static_cast<unsigned int>(pv->GetCopyNo());
0613
0614 std::string name = lvname + ":" + std::to_string(copy) + "_" + mother + ":" + std::to_string(copym);
0615 touches.emplace_back(name);
0616
0617 int NoDaughters = lv->GetNoDaughters();
0618 while ((NoDaughters--) > 0) {
0619 G4VPhysicalVolume *pvD = lv->GetDaughter(NoDaughters);
0620 if (!pvD->IsReplicated())
0621 getTouch(pvD, leafDepth + 1, copy, touches);
0622 }
0623
0624 if (leafDepth > 0)
0625 fHistory_.BackLevel();
0626 }
0627
0628 std::string PrintGeomInfoAction::spacesFromLeafDepth(unsigned int leafDepth) {
0629 std::string spaces;
0630 unsigned int ii;
0631 for (ii = 0; ii < leafDepth; ii++) {
0632 spaces += " ";
0633 }
0634 return spaces;
0635 }
0636
0637 G4VPhysicalVolume *PrintGeomInfoAction::getTopPV() {
0638 return G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking()->GetWorldVolume();
0639 }
0640
0641 G4LogicalVolume *PrintGeomInfoAction::getTopLV() { return theTopPV_->GetLogicalVolume(); }
0642
0643 #include "SimG4Core/Watcher/interface/SimWatcherFactory.h"
0644 #include "FWCore/PluginManager/interface/ModuleDef.h"
0645
0646 DEFINE_SIMWATCHER(PrintGeomInfoAction);