Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-06-14 22:36:24

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