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
00119 if (_dumpMaterial) dumpMaterialList(std::cout);
00120 if (_dumpLVList) dumpG4LVList(std::cout);
00121
00122
00123 if (_dumpLV || _dumpPV || _dumpTouch) dumpHierarchyTreePVLV(std::cout);
00124 }
00125
00126 void PrintGeomInfoAction::dumpSummary(std::ostream & out) {
00127
00128
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
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
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
00211
00212
00213
00214
00215
00216 G4LogicalVolume* topLV = getTopLV();
00217
00218
00219 dumpHierarchyLeafPVLV(topLV, 0, out);
00220 dumpPV(theTopPV, 0, out);
00221
00222
00223 if (_dumpTouch) dumpTouch(theTopPV, 0, out);
00224 }
00225
00226 void PrintGeomInfoAction::dumpHierarchyLeafPVLV(G4LogicalVolume * lv, unsigned int leafDepth, std::ostream & out) {
00227
00228
00229 dumpLV(lv, leafDepth, out);
00230
00231
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
00245 for (scite = lvDaughters.begin(); scite != lvDaughters.end(); scite++) {
00246 std::pair< mmlvpv::iterator, mmlvpv::iterator > mmER = lvpvDaughters.equal_range(*scite);
00247
00248 for (mmcite = mmER.first ; mmcite != mmER.second; mmcite++)
00249 dumpPV((*mmcite).second, leafDepth+1, out);
00250
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
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);
00266
00267
00268
00269 if (_dumpAtts) {
00270
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
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
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
00301 out << spaces
00302 << " Quality for optimisation, average number of voxels to be spent per content "
00303 << lv->GetSmartless() << std::endl;
00304
00305
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
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;
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