Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:30:29

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