G4ASCIITreeSceneHandler.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id$
00028 //
00029 // 
00030 // John Allison  5th April 2001
00031 // A scene handler to dump geometry hierarchy.
00032 // Based on a provisional G4ASCIITreeGraphicsScene (was in modeling).
00033 
00034 #include "G4ASCIITreeSceneHandler.hh"
00035 
00036 #include "G4ASCIITree.hh"
00037 #include "G4ASCIITreeMessenger.hh"
00038 #include "G4VSolid.hh"
00039 #include "G4PhysicalVolumeModel.hh"
00040 #include "G4VPhysicalVolume.hh"
00041 #include "G4LogicalVolume.hh"
00042 #include "G4VPVParameterisation.hh"
00043 #include "G4Polyhedron.hh"
00044 #include "G4UnitsTable.hh"
00045 #include "G4Material.hh"
00046 #include "G4Scene.hh"
00047 #include "G4ModelingParameters.hh"
00048 #include "G4PhysicalVolumeMassScene.hh"
00049 #include "G4VSensitiveDetector.hh"
00050 #include "G4VReadOutGeometry.hh"
00051 #include "G4TransportationManager.hh"
00052 
00053 G4ASCIITreeSceneHandler::G4ASCIITreeSceneHandler
00054 (G4VGraphicsSystem& system,
00055  const G4String& name):
00056   G4VTreeSceneHandler(system, name),
00057   fpOutFile(0),
00058   fpLastPV(0),
00059   fLastCopyNo(-99),
00060   fLastNonSequentialCopyNo(-99)
00061 {}
00062 
00063 G4ASCIITreeSceneHandler::~G4ASCIITreeSceneHandler () {}
00064 
00065 void G4ASCIITreeSceneHandler::BeginModeling () {
00066 
00067   G4VTreeSceneHandler::BeginModeling ();  // To re-use "culling off" code.
00068 
00069   const G4ASCIITree* pSystem = (G4ASCIITree*)GetGraphicsSystem();
00070   const G4String& outFileName = pSystem -> GetOutFileName();
00071   if (outFileName == "G4cout") {
00072     fpOutFile = &G4cout;
00073   } else {
00074     fOutFile.open (outFileName);
00075     fpOutFile = &fOutFile;
00076   }
00077 
00078   G4cout << "G4ASCIITreeSceneHandler::BeginModeling: writing to ";
00079   if (outFileName == "G4cout") {
00080     G4cout << "G4 standard output (G4cout)";
00081   } else {
00082     G4cout << "file \"" << outFileName << "\"";
00083   }
00084   G4cout << G4endl;
00085 
00086   WriteHeader (G4cout); G4cout << G4endl;
00087   if (outFileName != "G4cout") {
00088     WriteHeader (fOutFile); fOutFile << std::endl;
00089   }
00090 }
00091 
00092 void G4ASCIITreeSceneHandler::WriteHeader (std::ostream& os)
00093 {
00094   const G4ASCIITree* pSystem = (G4ASCIITree*)GetGraphicsSystem();
00095   const G4int verbosity = pSystem->GetVerbosity();
00096   const G4int detail = verbosity % 10;
00097   os << "#  Set verbosity with \"/vis/ASCIITree/verbose <verbosity>\":";
00098   for (size_t i = 0;
00099        i < G4ASCIITreeMessenger::fVerbosityGuidance.size(); ++i) {
00100     os << "\n#  " << G4ASCIITreeMessenger::fVerbosityGuidance[i];
00101   }
00102   os << "\n#  Now printing with verbosity " << verbosity;
00103   os << "\n#  Format is: PV:n";
00104   if (detail >= 1) os << " / LV (SD,RO)";
00105   if (detail >= 2) os << " / Solid(type)";
00106   if (detail >= 3) os << ", volume, density";
00107   if (detail >= 5) os << ", daughter-subtracted volume and mass";
00108   os <<
00109     "\n#  Abbreviations: PV = Physical Volume,     LV = Logical Volume,"
00110     "\n#                 SD = Sensitive Detector,  RO = Read Out Geometry.";
00111 }
00112 
00113 void G4ASCIITreeSceneHandler::EndModeling () {
00114   const G4ASCIITree* pSystem = (G4ASCIITree*) GetGraphicsSystem();
00115   const G4int verbosity = pSystem->GetVerbosity();
00116   const G4int detail = verbosity % 10;
00117   const G4String& outFileName = pSystem -> GetOutFileName();
00118 
00119   // Output left over copy number, if any...
00120   if (fLastCopyNo != fLastNonSequentialCopyNo) {
00121     if (fLastCopyNo == fLastNonSequentialCopyNo + 1) *fpOutFile << ',';
00122     else *fpOutFile << '-';
00123     *fpOutFile << fLastCopyNo;
00124   }
00125   // Output outstanding rest of line, if any...
00126   if (!fRestOfLine.str().empty()) *fpOutFile << fRestOfLine.str();
00127   fRestOfLine.str("");
00128   fpLastPV = 0;
00129   fLastPVName.clear();
00130   fLastCopyNo = -99;
00131   fLastNonSequentialCopyNo = -99;
00132 
00133   // This detail to G4cout regardless of outFileName...
00134   if (detail >= 4) {
00135     G4cout << "Calculating mass(es)..." << G4endl;
00136     const std::vector<G4Scene::Model>& models = fpScene->GetRunDurationModelList();
00137     std::vector<G4Scene::Model>::const_iterator i;
00138     for (i = models.begin(); i != models.end(); ++i) {
00139       G4PhysicalVolumeModel* pvModel =
00140         dynamic_cast<G4PhysicalVolumeModel*>(i->fpModel);
00141       if (pvModel) {
00142         if (pvModel->GetTopPhysicalVolume() ==
00143             G4TransportationManager::GetTransportationManager()
00144             ->GetNavigatorForTracking()->GetWorldVolume()) {
00145           const G4ModelingParameters* tempMP =
00146             pvModel->GetModelingParameters();
00147           G4ModelingParameters mp;  // Default - no culling.
00148           pvModel->SetModelingParameters (&mp);
00149           G4PhysicalVolumeMassScene massScene(pvModel);
00150           pvModel->DescribeYourselfTo (massScene);
00151           G4double volume = massScene.GetVolume();
00152           G4double mass = massScene.GetMass();
00153 
00154           G4cout << "Overall volume of \""
00155                  << pvModel->GetTopPhysicalVolume()->GetName()
00156                  << "\":"
00157                  << pvModel->GetTopPhysicalVolume()->GetCopyNo()
00158                  << ", is "
00159                  << G4BestUnit (volume, "Volume")
00160                  << " and the daughter-included mass";
00161           G4int requestedDepth = pvModel->GetRequestedDepth();
00162           if (requestedDepth == G4PhysicalVolumeModel::UNLIMITED) {
00163             G4cout << " to unlimited depth";
00164           } else {
00165             G4cout << ", ignoring daughters at depth "
00166                    << requestedDepth
00167                    << " and below,";
00168           }
00169           G4cout << " is " << G4BestUnit (mass, "Mass")
00170                  << G4endl;
00171 
00172           pvModel->SetModelingParameters (tempMP);
00173         }
00174       }
00175     }
00176   }
00177 
00178   if (outFileName != "G4cout") {
00179     fOutFile.close();
00180     G4cout << "Output file \"" << outFileName << "\" closed." << G4endl;
00181   }
00182   fLVSet.clear();
00183   fReplicaSet.clear();
00184   G4cout << "G4ASCIITreeSceneHandler::EndModeling" << G4endl;
00185   G4VTreeSceneHandler::EndModeling ();  // To re-use "culling off" code.
00186 }
00187 
00188 void G4ASCIITreeSceneHandler::RequestPrimitives(const G4VSolid& solid) {
00189   
00190   G4PhysicalVolumeModel* pPVModel =
00191     dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
00192   if (!pPVModel) return;  // Not from a G4PhysicalVolumeModel.
00193 
00194   // This call comes from a G4PhysicalVolumeModel.  drawnPVPath is
00195   // the path of the current drawn (non-culled) volume in terms of
00196   // drawn (non-culled) ancesters.  Each node is identified by a
00197   // PVNodeID object, which is a physical volume and copy number.  It
00198   // is a vector of PVNodeIDs corresponding to the geometry hierarchy
00199   // actually selected, i.e., not culled.
00200   // The following typedef's already set in header file...
00201   //typedef G4PhysicalVolumeModel::G4PhysicalVolumeNodeID PVNodeID;
00202   //typedef std::vector<PVNodeID> PVPath;
00203   const PVPath& drawnPVPath = pPVModel->GetDrawnPVPath();
00204   //G4int currentDepth = pPVModel->GetCurrentDepth();
00205   G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
00206   G4LogicalVolume* pCurrentLV = pPVModel->GetCurrentLV();
00207   G4Material* pCurrentMaterial = pPVModel->GetCurrentMaterial();
00208 
00209   G4ASCIITree* pSystem = (G4ASCIITree*)GetGraphicsSystem();
00210   G4int verbosity = pSystem->GetVerbosity();
00211   G4int detail = verbosity % 10;
00212 
00213   if (verbosity < 10 && pCurrentPV->IsReplicated()) {
00214     // See if this has been a replica found before with same mother LV...
00215     PVPath::const_reverse_iterator thisID = drawnPVPath.rbegin();
00216     PVPath::const_reverse_iterator motherID = ++drawnPVPath.rbegin();
00217     G4bool ignore = false;
00218     for (ReplicaSetIterator i = fReplicaSet.begin(); i != fReplicaSet.end();
00219          ++i) {
00220       if (i->back().GetPhysicalVolume()->GetLogicalVolume() ==
00221           thisID->GetPhysicalVolume()->GetLogicalVolume()) {
00222         // For each one previously found (if more than one, they must
00223         // have different mothers)...
00224         // To avoid compilation errors on VC++ .Net 7.1...
00225         // Previously:
00226         //   PVNodeID previousMotherID = ++(i->rbegin());
00227         // (Should that have been: PVNodeID::const_iterator previousMotherID?)
00228         // Replace
00229         //   previousMotherID == i->rend()
00230         // by
00231         //   i->size() <= 1
00232         // Replace
00233         //   previousMotherID != i->rend()
00234         // by
00235         //   i->size() > 1
00236         // Replace
00237         //   previousMotherID->
00238         // by
00239         //   (*i)[i->size() - 2].
00240         if (motherID == drawnPVPath.rend() &&
00241             i->size() <= 1)
00242           ignore = true;  // Both have no mother.
00243         if (motherID != drawnPVPath.rend() &&
00244             i->size() > 1 &&
00245             motherID->GetPhysicalVolume()->GetLogicalVolume() ==
00246             (*i)[i->size() - 2].GetPhysicalVolume()->GetLogicalVolume())
00247           ignore = true;  // Same mother LV...
00248       }
00249     }
00250     if (ignore) {
00251       pPVModel->CurtailDescent();
00252       return;
00253     }
00254   }
00255 
00256   const G4String& currentPVName = pCurrentPV->GetName();
00257   const G4int currentCopyNo = pCurrentPV->GetCopyNo();
00258 
00259   if (verbosity < 10 && 
00260       currentPVName == fLastPVName &&
00261       currentCopyNo != fLastCopyNo) {
00262     // For low verbosity, trap series of G4PVPlacements with the same name but
00263     // different copy number (replicas should have been taken out above)...
00264     // Check...
00265     if (pCurrentPV->IsReplicated()) {
00266       G4Exception("G4ASCIITreeSceneHandler::RequestPrimitives",
00267                   "vistree0001",
00268                   JustWarning,
00269                   "Replica unexpected");
00270     }
00271     // Check mothers are identical...
00272     else if (pCurrentLV == (fpLastPV? fpLastPV->GetLogicalVolume(): 0)) {
00273       if (currentCopyNo != fLastCopyNo + 1) {
00274         // Non-sequential copy number...
00275         *fpOutFile << ',' << currentCopyNo;
00276         fLastNonSequentialCopyNo = currentCopyNo;
00277       }
00278       fLastCopyNo = currentCopyNo;
00279       pPVModel->CurtailDescent();
00280       return;
00281     }
00282   }
00283   fpLastPV = pCurrentPV;
00284 
00285   // High verbosity or a new G4VPhysicalVolume...
00286   // Output copy number, if any, from previous invocation...
00287   if (fLastCopyNo != fLastNonSequentialCopyNo) {
00288     if (fLastCopyNo == fLastNonSequentialCopyNo + 1) *fpOutFile << ',';
00289     else *fpOutFile << '-';
00290     *fpOutFile << fLastCopyNo;
00291   }
00292   // Output rest of line, if any, from previous invocation...
00293   if (!fRestOfLine.str().empty()) *fpOutFile << fRestOfLine.str();
00294   fRestOfLine.str("");
00295   fLastPVName = currentPVName;
00296   fLastCopyNo = currentCopyNo;
00297   fLastNonSequentialCopyNo = currentCopyNo;
00298   // Indent according to drawn path depth...
00299   for (size_t i = 0; i < drawnPVPath.size(); i++ ) *fpOutFile << "  ";
00300   // Start next line...
00301   *fpOutFile << "\"" << currentPVName
00302              << "\":" << currentCopyNo;
00303 
00304   if (pCurrentPV->IsReplicated()) {
00305     if (verbosity < 10) {
00306       // Add printing for replicas (when replicas are ignored)...
00307       EAxis axis;
00308       G4int nReplicas;
00309       G4double width;
00310       G4double offset;
00311       G4bool consuming;
00312       pCurrentPV->GetReplicationData(axis,nReplicas,width,offset,consuming);
00313       G4VPVParameterisation* pP = pCurrentPV->GetParameterisation();
00314       if (pP) {
00315         if (detail < 3) {
00316           fReplicaSet.insert(drawnPVPath);
00317           if (nReplicas > 2) fRestOfLine << '-';
00318           else fRestOfLine << ',';
00319           fRestOfLine << nReplicas - 1
00320                       << " (" << nReplicas << " parametrised volumes)";
00321         }
00322       }
00323       else {
00324         fReplicaSet.insert(drawnPVPath);
00325         if (nReplicas > 2) fRestOfLine << '-';
00326         else fRestOfLine << ',';
00327         fRestOfLine << nReplicas - 1
00328                     << " (" << nReplicas << " replicas)";
00329       }
00330     }
00331   } else {
00332     if (fLVSet.find(pCurrentLV) != fLVSet.end()) {
00333       if (verbosity <  10) {
00334         // Add printing for repeated LV (if it has daughters)...
00335         if (pCurrentLV->GetNoDaughters()) fRestOfLine << " (repeated LV)";
00336         // ...and curtail descent.
00337         pPVModel->CurtailDescent();
00338       }
00339     }
00340   }
00341 
00342   if (detail >= 1) {
00343     fRestOfLine << " / \""
00344                 << pCurrentLV->GetName() << "\"";
00345     G4VSensitiveDetector* sd = pCurrentLV->GetSensitiveDetector();
00346     if (sd) {
00347       fRestOfLine << " (SD=\"" << sd->GetName() << "\"";
00348       G4VReadOutGeometry* roGeom = sd->GetROgeometry();
00349       if (roGeom) {
00350         fRestOfLine << ",RO=\"" << roGeom->GetName() << "\"";
00351       }
00352       fRestOfLine << ")";
00353     }
00354   }
00355 
00356   if (detail >= 2) {
00357     fRestOfLine << " / \""
00358                << solid.GetName()
00359                << "\"("
00360                << solid.GetEntityType() << ")";
00361   }
00362 
00363   if (detail >= 3) {
00364     fRestOfLine << ", "
00365                 << G4BestUnit(((G4VSolid&)solid).GetCubicVolume(),"Volume")
00366                 << ", ";
00367     if (pCurrentMaterial) {
00368       fRestOfLine
00369         << G4BestUnit(pCurrentMaterial->GetDensity(), "Volumic Mass")
00370         << " (" << pCurrentMaterial->GetName() << ")";
00371     } else {
00372       fRestOfLine << "(No material)";
00373     }
00374   }
00375 
00376   if (detail >= 5) {
00377     if (pCurrentMaterial) {
00378       G4Material* pMaterial = const_cast<G4Material*>(pCurrentMaterial);
00379       // ...and find daughter-subtracted mass...
00380       G4double daughter_subtracted_mass = pCurrentLV->GetMass
00381         (pCurrentPV->IsParameterised(),  // Force if parametrised.
00382          false,  // Do not propagate - calculate for this volume minus
00383          // volume of daughters.
00384          pMaterial);
00385       G4double daughter_subtracted_volume =
00386         daughter_subtracted_mass / pCurrentMaterial->GetDensity();
00387       fRestOfLine << ", "
00388                   << G4BestUnit(daughter_subtracted_volume,"Volume")
00389                   << ", "
00390                   << G4BestUnit(daughter_subtracted_mass,"Mass");
00391     }
00392   }
00393 
00394   if (fLVSet.find(pCurrentLV) == fLVSet.end()) {
00395     fLVSet.insert(pCurrentLV);  // Record new logical volume.
00396   }
00397 
00398   fRestOfLine << std::endl;
00399 
00400   return;
00401 }

Generated on Mon May 27 17:47:41 2013 for Geant4 by  doxygen 1.4.7