CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/SimG4Core/PrintGeomInfo/src/PrintGeomInfoAction.cc

Go to the documentation of this file.
00001 #include "SimG4Core/PrintGeomInfo/interface/PrintGeomInfoAction.h"
00002 
00003 #include "SimG4Core/Notification/interface/BeginOfJob.h"
00004 #include "SimG4Core/Notification/interface/BeginOfRun.h"
00005 #include "SimG4Core/Notification/interface/SimG4Exception.h"
00006 
00007 #include "FWCore/Framework/interface/EventSetup.h"
00008 #include "FWCore/Framework/interface/ESTransientHandle.h"
00009 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00010 #include "DetectorDescription/Core/interface/DDCompactView.h"
00011 #include "DetectorDescription/Core/interface/DDFilter.h"
00012 #include "DetectorDescription/Core/interface/DDFilteredView.h"
00013 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
00014 #include "DetectorDescription/Core/interface/DDSplit.h"
00015 #include "DetectorDescription/Core/interface/DDValue.h"
00016 
00017 #include "G4Run.hh"
00018 #include "G4PhysicalVolumeStore.hh"
00019 #include "G4LogicalVolumeStore.hh"
00020 #include "G4VPhysicalVolume.hh"
00021 #include "G4LogicalVolume.hh"
00022 #include "G4VSolid.hh"
00023 #include "G4Material.hh"
00024 #include "G4Track.hh"
00025 #include "G4VisAttributes.hh"
00026 #include "G4UserLimits.hh"
00027 #include "G4TransportationManager.hh"
00028 
00029 #include <set>
00030 #include <map>
00031 
00032 PrintGeomInfoAction::PrintGeomInfoAction(const edm::ParameterSet &p) {
00033 
00034   _dumpSummary = p.getUntrackedParameter<bool>("DumpSummary", true);
00035   _dumpLVTree  = p.getUntrackedParameter<bool>("DumpLVTree",  true);
00036   _dumpMaterial= p.getUntrackedParameter<bool>("DumpMaterial",false);
00037   _dumpLVList  = p.getUntrackedParameter<bool>("DumpLVList",  false);
00038   _dumpLV      = p.getUntrackedParameter<bool>("DumpLV",      false);
00039   _dumpSolid   = p.getUntrackedParameter<bool>("DumpSolid",   false);
00040   _dumpAtts    = p.getUntrackedParameter<bool>("DumpAttributes", false);
00041   _dumpPV      = p.getUntrackedParameter<bool>("DumpPV",      false);
00042   _dumpRotation= p.getUntrackedParameter<bool>("DumpRotation",false);
00043   _dumpReplica = p.getUntrackedParameter<bool>("DumpReplica", false);
00044   _dumpTouch   = p.getUntrackedParameter<bool>("DumpTouch",   false);
00045   _dumpSense   = p.getUntrackedParameter<bool>("DumpSense",   false);
00046   name  = p.getUntrackedParameter<std::string>("Name","*");
00047   nchar = name.find("*");
00048   name.assign(name,0,nchar);
00049   names = p.getUntrackedParameter<std::vector<std::string> >("Names");
00050   std::cout << "PrintGeomInfoAction:: initialised with verbosity levels:"
00051             << " Summary   " << _dumpSummary << " LVTree   " << _dumpLVTree
00052             << " LVList    " << _dumpLVList  << " Material " << _dumpMaterial
00053             << "\n                                                        "
00054             << " LV        " << _dumpLV      << " Solid    " << _dumpSolid 
00055             << " Attribs   " << _dumpAtts
00056             << "\n                                                        "
00057             << " PV        " << _dumpPV      << " Rotation " << _dumpRotation
00058             << " Replica   " << _dumpReplica
00059             << "\n                                                        "
00060             << " Touchable " << _dumpTouch << " for names (0-" << nchar 
00061             << ") = " << name 
00062             << "\n                                                        "
00063             << " Sensitive " << _dumpSense << " for " << names.size()
00064             << " namess";
00065   for (unsigned int i=0; i<names.size(); i++) std::cout << " " << names[i];
00066   std::cout << std::endl;
00067 }
00068  
00069 PrintGeomInfoAction::~PrintGeomInfoAction() {}
00070  
00071 void PrintGeomInfoAction::update(const BeginOfJob * job) {
00072 
00073   if (_dumpSense) {
00074     edm::ESTransientHandle<DDCompactView> pDD;
00075     (*job)()->get<IdealGeometryRecord>().get(pDD);
00076 
00077     std::cout << "PrintGeomInfoAction::Get Printout of Sensitive Volumes " 
00078               << "for " << names.size() << " Readout Units" << std::endl;
00079     for (unsigned int i=0; i<names.size(); i++) {
00080       std::string attribute = "ReadOutName";
00081       std::string sd        = names[i];
00082       DDSpecificsFilter filter;
00083       DDValue           ddv(attribute,sd,0);
00084       filter.setCriteria(ddv,DDSpecificsFilter::equals);
00085       DDFilteredView fv(*pDD);
00086       std::cout << "PrintGeomInfoAction:: Get Filtered view for " 
00087                 << attribute << " = " << sd << std::endl;
00088       fv.addFilter(filter);
00089       bool dodet = fv.firstChild();
00090       
00091       std::string spaces = spacesFromLeafDepth(1);
00092 
00093       while (dodet) {
00094         const DDLogicalPart & log = fv.logicalPart();
00095         std::string lvname = log.name().name();
00096         DDTranslation tran = fv.translation();
00097         std::vector<int> copy = fv.copyNumbers();
00098 
00099         unsigned int leafDepth = copy.size();
00100         std::cout << leafDepth << spaces << "### VOLUME = " << lvname 
00101                   << " Copy No";
00102         for (int k=leafDepth-1; k>=0; k--) std::cout << " " << copy[k];
00103         std::cout << " Centre at " << tran << " (r = " << tran.Rho()
00104                   << ", phi = " << tran.phi()/deg << ")" << std::endl;
00105         dodet = fv.next();
00106       }
00107     }
00108   }
00109 }
00110   
00111 void PrintGeomInfoAction::update(const BeginOfRun * run) {
00112 
00113   theTopPV = getTopPV();
00114   
00115   if (_dumpSummary)  dumpSummary(std::cout);
00116   if (_dumpLVTree)   dumpG4LVTree(std::cout);
00117     
00118   //---------- Dump list of objects of each class with detail of parameters
00119   if (_dumpMaterial) dumpMaterialList(std::cout);
00120   if (_dumpLVList)   dumpG4LVList(std::cout);
00121 
00122   //---------- Dump LV and PV information
00123   if (_dumpLV || _dumpPV || _dumpTouch) dumpHierarchyTreePVLV(std::cout);
00124 }
00125 
00126 void PrintGeomInfoAction::dumpSummary(std::ostream & out) {
00127 
00128   //---------- Dump number of objects of each class
00129   out << " @@@@@@@@@@@@@@@@@@ Dumping G4 geometry objects Summary " << std::endl;
00130   if (theTopPV == 0) {
00131     out << " No volume created " << std::endl;
00132     return;
00133   }
00134   out << " @@@ Geometry built inside world volume: " << theTopPV->GetName() << std::endl;
00135   // Get number of solids (< # LV if several LV share a solid)
00136   const G4LogicalVolumeStore * lvs = G4LogicalVolumeStore::GetInstance();
00137   std::vector<G4LogicalVolume *>::const_iterator lvcite;
00138   std::set<G4VSolid *> theSolids;
00139   for (lvcite = lvs->begin(); lvcite != lvs->end(); lvcite++) 
00140     theSolids.insert((*lvcite)->GetSolid());
00141   out << " Number of G4VSolid's: " << theSolids.size() << std::endl;
00142   out << " Number of G4LogicalVolume's: " << lvs->size() << std::endl;
00143   const G4PhysicalVolumeStore * pvs = G4PhysicalVolumeStore::GetInstance();
00144   out << " Number of G4VPhysicalVolume's: " << pvs->size() << std::endl;
00145   out << " Number of Touchable's: " << countNoTouchables() << std::endl;
00146   const G4MaterialTable * matTab = G4Material::GetMaterialTable();
00147   out << " Number of G4Material's: " << matTab->size() << std::endl;
00148 }
00149 
00150 void PrintGeomInfoAction::dumpG4LVList(std::ostream & out) {
00151 
00152   out << " @@@@@@@@@@@@@@@@ DUMPING G4LogicalVolume's List  " << std::endl;
00153   const G4LogicalVolumeStore * lvs = G4LogicalVolumeStore::GetInstance();
00154   std::vector<G4LogicalVolume*>::const_iterator lvcite;
00155   for (lvcite = lvs->begin(); lvcite != lvs->end(); lvcite++) 
00156     out << "LV:" << (*lvcite)->GetName() << "\tMaterial: " << (*lvcite)->GetMaterial()->GetName() << std::endl;
00157 }
00158 
00159 void PrintGeomInfoAction::dumpG4LVTree(std::ostream & out) {
00160 
00161   out << " @@@@@@@@@@@@@@@@ DUMPING G4LogicalVolume's Tree  " << std::endl;
00162   G4LogicalVolume * lv = getTopLV(); 
00163   dumpG4LVLeaf(lv,0,1,out);
00164 }
00165 
00166 void PrintGeomInfoAction::dumpMaterialList(std::ostream & out) {
00167 
00168   out << " @@@@@@@@@@@@@@@@ DUMPING G4Material List ";
00169   const G4MaterialTable * matTab = G4Material::GetMaterialTable();
00170   out << " with " << matTab->size() << " materials " << std::endl;
00171   std::vector<G4Material*>::const_iterator matite;
00172   for (matite = matTab->begin(); matite != matTab->end(); matite++)
00173     out << "Material: " << (*matite) << std::endl;
00174 }
00175 
00176 void PrintGeomInfoAction::dumpG4LVLeaf(G4LogicalVolume * lv, unsigned int leafDepth, unsigned int count, std::ostream & out) {
00177 
00178   for (unsigned int ii=0; ii < leafDepth; ii++) out << "  ";
00179   out << " LV:(" << leafDepth << ") " << lv->GetName() << " (" << count
00180       << ")" << std::endl;
00181   //--- If a volume is placed n types as daughter of this LV, it should only be counted once
00182   std::map<G4LogicalVolume*, unsigned int> lvCount;
00183   std::map<G4LogicalVolume*, unsigned int>::const_iterator cite;
00184   for (int ii = 0; ii < lv->GetNoDaughters(); ii++) {
00185     cite = lvCount.find(lv->GetDaughter(ii)->GetLogicalVolume());
00186     if (cite != lvCount.end()) lvCount[cite->first] = (cite->second) + 1;
00187     else lvCount.insert(std::pair< G4LogicalVolume*,unsigned int>(lv->GetDaughter(ii)->GetLogicalVolume(),1));
00188   }
00189   for (cite = lvCount.begin(); cite != lvCount.end(); cite++) 
00190     dumpG4LVLeaf((cite->first), leafDepth+1, (cite->second), out);
00191 }
00192 
00193 int PrintGeomInfoAction::countNoTouchables() {
00194 
00195   int nTouch = 0;
00196   G4LogicalVolume * lv = getTopLV();
00197   add1touchable(lv, nTouch);
00198   return nTouch;
00199 }
00200 
00201 void PrintGeomInfoAction::add1touchable(G4LogicalVolume * lv, int & nTouch) {
00202 
00203   int siz = lv->GetNoDaughters();
00204   for(int ii = 0; ii < siz; ii++)
00205     add1touchable(lv->GetDaughter(ii)->GetLogicalVolume(), ++nTouch);
00206 }
00207  
00208 void PrintGeomInfoAction::dumpHierarchyTreePVLV(std::ostream & out) {
00209 
00210   //dumps in the following order: 
00211   //    1) a LV with details
00212   //    2) list of PVs daughters of this LV with details
00213   //    3) list of LVs daughters of this LV and for each go to 1)
00214   
00215   //----- Get top PV
00216   G4LogicalVolume*  topLV = getTopLV();
00217   
00218   //----- Dump this leaf (it will recursively dump all the tree)
00219   dumpHierarchyLeafPVLV(topLV, 0, out);
00220   dumpPV(theTopPV, 0, out);
00221   
00222   //----- Dump the touchables (it will recursively dump all the tree)
00223   if (_dumpTouch) dumpTouch(theTopPV, 0, out);
00224 }
00225 
00226 void PrintGeomInfoAction::dumpHierarchyLeafPVLV(G4LogicalVolume * lv, unsigned int leafDepth, std::ostream & out) {
00227 
00228   //----- Dump this LV 
00229   dumpLV(lv, leafDepth, out);
00230 
00231   //----- Get LV daughters from list of PV daughters
00232   mmlvpv lvpvDaughters;
00233   std::set< G4LogicalVolume * > lvDaughters;
00234   int NoDaughters = lv->GetNoDaughters();
00235   while ((NoDaughters--)>0) {
00236     G4VPhysicalVolume * pvD = lv->GetDaughter(NoDaughters);
00237     lvpvDaughters.insert(mmlvpv::value_type(pvD->GetLogicalVolume(), pvD));
00238     lvDaughters.insert(pvD->GetLogicalVolume());
00239   }
00240  
00241   std::set< G4LogicalVolume * >::const_iterator scite;
00242   mmlvpv::const_iterator mmcite;
00243 
00244   //----- Dump daughters PV and LV
00245   for (scite = lvDaughters.begin(); scite != lvDaughters.end(); scite++) {
00246     std::pair< mmlvpv::iterator, mmlvpv::iterator > mmER = lvpvDaughters.equal_range(*scite);    
00247     //----- Dump daughters PV of this LV
00248     for (mmcite = mmER.first ; mmcite != mmER.second; mmcite++) 
00249       dumpPV((*mmcite).second, leafDepth+1, out);
00250     //----- Dump daughters LV
00251     dumpHierarchyLeafPVLV(*scite, leafDepth+1, out );
00252   }
00253 }
00254  
00255 void PrintGeomInfoAction::dumpLV(G4LogicalVolume * lv, unsigned int leafDepth, std::ostream & out) {
00256 
00257   std::string spaces = spacesFromLeafDepth(leafDepth);
00258 
00259   //----- dump name 
00260   if (_dumpLV) { 
00261     out << leafDepth << spaces << "$$$ VOLUME = " << lv->GetName()
00262         << "  Solid: " << lv->GetSolid()->GetName() << "  MATERIAL: "
00263         << lv->GetMaterial()->GetName() << std::endl;
00264     if (_dumpSolid)
00265       dumpSolid(lv->GetSolid(), leafDepth, out); //----- dump solid
00266 
00267     //----- dump LV info 
00268     //--- material 
00269     if (_dumpAtts) {
00270       //--- Visualisation attributes
00271       const G4VisAttributes * fVA = lv->GetVisAttributes();
00272       if (fVA!=0) {
00273         out <<  spaces << "  VISUALISATION ATTRIBUTES: " << std::endl;
00274         out <<  spaces << "    IsVisible " << fVA->IsVisible() << std::endl;
00275         out <<  spaces << "    IsDaughtersInvisible " << fVA->IsDaughtersInvisible() << std::endl;
00276         out <<  spaces << "    Colour " << fVA->GetColour() << std::endl;
00277         out <<  spaces << "    LineStyle " << fVA->GetLineStyle() << std::endl;
00278         out <<  spaces << "    LineWidth " << fVA->GetLineWidth() << std::endl;
00279         out <<  spaces << "    IsForceDrawingStyle " << fVA->IsForceDrawingStyle() << std::endl;
00280         out <<  spaces << "    ForcedDrawingStyle " << fVA->GetForcedDrawingStyle() << std::endl;
00281       }    
00282     
00283       //--- User Limits
00284       G4UserLimits * fUL = lv->GetUserLimits();
00285       G4Track dummy;
00286       if (fUL!=0) {
00287         out <<  spaces << "    MaxAllowedStep " << fUL->GetMaxAllowedStep(dummy) << std::endl;
00288         out <<  spaces << "    UserMaxTrackLength " << fUL->GetUserMaxTrackLength(dummy) << std::endl;
00289         out <<  spaces << "    UserMaxTime " << fUL->GetUserMaxTime(dummy) << std::endl;
00290         out <<  spaces << "    UserMinEkine " << fUL->GetUserMinEkine(dummy) << std::endl;
00291         out <<  spaces << "    UserMinRange " << fUL->GetUserMinRange(dummy) << std::endl;
00292       }
00293     
00294       //--- other LV info
00295       if (lv->GetSensitiveDetector()) 
00296         out << spaces << "  IS SENSITIVE DETECTOR " << std::endl;
00297       if (lv->GetFieldManager()) 
00298         out << spaces << "  FIELD ON " << std::endl;
00299 
00300       // Pointer (possibly NULL) to optimisation info objects.
00301       out <<  spaces  
00302           << "        Quality for optimisation, average number of voxels to be spent per content " 
00303           << lv->GetSmartless() << std::endl;
00304 
00305       // Pointer (possibly NULL) to G4FastSimulationManager object.
00306       if (lv->GetFastSimulationManager()) 
00307         out << spaces << "     Logical Volume is an envelope for a FastSimulationManager " 
00308             << std::endl;
00309       out << spaces << "     Weight used in the event biasing technique = " 
00310           << lv->GetBiasWeight() << std::endl;
00311     } 
00312   }
00313 }       
00314 
00315 void PrintGeomInfoAction::dumpPV(G4VPhysicalVolume * pv, unsigned int leafDepth, std::ostream & out) {
00316 
00317   std::string spaces = spacesFromLeafDepth(leafDepth);
00318 
00319   //----- PV info
00320   if (_dumpPV) {
00321     std::string mother = "World";
00322     if (pv->GetMotherLogical()) mother = pv->GetMotherLogical()->GetName();
00323     out << leafDepth << spaces << "### VOLUME = " << pv->GetName() 
00324         << " Copy No " << pv->GetCopyNo() << " in " << mother
00325         << " at " << pv->GetTranslation();
00326   }
00327   if (!pv->IsReplicated()) {
00328     if (_dumpPV) {
00329       if(pv->GetRotation() == 0) out << " with no rotation" << std::endl;
00330       else  if(!_dumpRotation)   out << " with rotation" << std::endl; //just rotation name
00331       else                       out << " with rotation " << *(pv->GetRotation()) << std::endl;
00332     }
00333   } else {
00334     if (_dumpReplica ) {
00335       out << spaces << "    It is replica: " << std::endl;
00336       EAxis axis; 
00337       int nReplicas; 
00338       double width; 
00339       double offset; 
00340       bool consuming;
00341       pv->GetReplicationData(axis, nReplicas, width, offset, consuming);
00342       out << spaces << "     axis " << axis << std::endl
00343           << spaces << "     nReplicas " << nReplicas << std::endl;
00344       if (pv->GetParameterisation() != 0) 
00345         out << spaces << "    It is parameterisation " << std::endl;
00346       else 
00347         out << spaces << "     width " << width << std::endl
00348             << spaces << "     offset " << offset << std::endl
00349             << spaces << "     consuming" <<  consuming << std::endl;
00350       if (pv->GetParameterisation() != 0) 
00351         out << spaces << "    It is parameterisation " << std::endl;
00352     }
00353   }
00354 }
00355 
00356 void PrintGeomInfoAction::dumpTouch(G4VPhysicalVolume * pv, unsigned int leafDepth, std::ostream & out) {
00357 
00358   std::string spaces = spacesFromLeafDepth(leafDepth);
00359   if (leafDepth == 0) fHistory.SetFirstEntry(pv);
00360   else fHistory.NewLevel(pv, kNormal, pv->GetCopyNo());
00361 
00362   G4ThreeVector globalpoint = fHistory.GetTopTransform().Inverse().TransformPoint(G4ThreeVector(0,0,0));
00363   G4LogicalVolume * lv = pv->GetLogicalVolume();
00364 
00365   std::string mother = "World";
00366   if (pv->GetMotherLogical()) mother = pv->GetMotherLogical()->GetName();
00367   std::string lvname = lv->GetName();
00368   lvname.assign(lvname,0,nchar);
00369   if (lvname == name)
00370     out << leafDepth << spaces << "### VOLUME = " << lv->GetName() 
00371         << " Copy No " << pv->GetCopyNo() << " in " << mother
00372         << " global position of centre " << globalpoint << " (r = " 
00373         <<  globalpoint.perp() << ", phi = " <<  globalpoint.phi()/deg
00374         << ")" << std::endl;
00375 
00376   int NoDaughters = lv->GetNoDaughters();
00377   while ((NoDaughters--)>0) {
00378     G4VPhysicalVolume * pvD = lv->GetDaughter(NoDaughters);
00379     if (!pvD->IsReplicated()) dumpTouch(pvD, leafDepth+1, out);
00380   }
00381 
00382   if (leafDepth > 0) fHistory.BackLevel();
00383 }
00384 
00385 std::string PrintGeomInfoAction::spacesFromLeafDepth(unsigned int leafDepth) {
00386 
00387   std::string spaces;
00388   unsigned int ii;
00389   for(ii = 0; ii < leafDepth; ii++) { spaces += "  "; }
00390   return spaces;
00391 }
00392 
00393 void PrintGeomInfoAction::dumpSolid(G4VSolid * sol, unsigned int leafDepth, std::ostream & out) {
00394 
00395   std::string spaces = spacesFromLeafDepth(leafDepth);
00396   out << spaces << *(sol) << std::endl;
00397 }
00398 
00399 G4VPhysicalVolume * PrintGeomInfoAction::getTopPV() {
00400   
00401   return G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking()->GetWorldVolume();
00402 }
00403 
00404 G4LogicalVolume * PrintGeomInfoAction::getTopLV() { 
00405   return theTopPV->GetLogicalVolume(); 
00406 }
00407 
00408