source: trunk/source/visualization/Tree/src/G4ASCIITreeSceneHandler.cc @ 954

Last change on this file since 954 was 954, checked in by garnier, 15 years ago

remise a jour

File size: 13.7 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer                                           *
4// *                                                                  *
5// * The  Geant4 software  is  copyright of the Copyright Holders  of *
6// * the Geant4 Collaboration.  It is provided  under  the terms  and *
7// * conditions of the Geant4 Software License,  included in the file *
8// * LICENSE and available at  http://cern.ch/geant4/license .  These *
9// * include a list of copyright holders.                             *
10// *                                                                  *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work  make  any representation or  warranty, express or implied, *
14// * regarding  this  software system or assume any liability for its *
15// * use.  Please see the license in the file  LICENSE  and URL above *
16// * for the full disclaimer and the limitation of liability.         *
17// *                                                                  *
18// * This  code  implementation is the result of  the  scientific and *
19// * technical work of the GEANT4 collaboration.                      *
20// * By using,  copying,  modifying or  distributing the software (or *
21// * any work based  on the software)  you  agree  to acknowledge its *
22// * use  in  resulting  scientific  publications,  and indicate your *
23// * acceptance of all terms of the Geant4 Software license.          *
24// ********************************************************************
25//
26//
27// $Id: G4ASCIITreeSceneHandler.cc,v 1.34 2007/01/05 17:00:27 allison Exp $
28// GEANT4 tag $Name:  $
29//
30//
31// John Allison  5th April 2001
32// A scene handler to dump geometry hierarchy.
33// Based on a provisional G4ASCIITreeGraphicsScene (was in modeling).
34
35#include "G4ASCIITreeSceneHandler.hh"
36
37#include "G4ASCIITree.hh"
38#include "G4ASCIITreeMessenger.hh"
39#include "G4VSolid.hh"
40#include "G4PhysicalVolumeModel.hh"
41#include "G4VPhysicalVolume.hh"
42#include "G4LogicalVolume.hh"
43#include "G4VPVParameterisation.hh"
44#include "G4Polyhedron.hh"
45#include "G4UnitsTable.hh"
46#include "G4Material.hh"
47#include "G4Scene.hh"
48#include "G4ModelingParameters.hh"
49#include "G4PhysicalVolumeMassScene.hh"
50#include "G4VSensitiveDetector.hh"
51#include "G4VReadOutGeometry.hh"
52#include "G4TransportationManager.hh"
53
54G4ASCIITreeSceneHandler::G4ASCIITreeSceneHandler
55(G4VGraphicsSystem& system,
56 const G4String& name):
57  G4VTreeSceneHandler(system, name),
58  fpOutFile(0),
59  fpLastPV(0),
60  fLastCopyNo(-99),
61  fLastNonSequentialCopyNo(-99)
62{}
63
64G4ASCIITreeSceneHandler::~G4ASCIITreeSceneHandler () {}
65
66void G4ASCIITreeSceneHandler::BeginModeling () {
67
68  G4VTreeSceneHandler::BeginModeling ();  // To re-use "culling off" code.
69
70  const G4ASCIITree* pSystem = (G4ASCIITree*)GetGraphicsSystem();
71  const G4String& outFileName = pSystem -> GetOutFileName();
72  if (outFileName == "G4cout") {
73    fpOutFile = &G4cout;
74  } else {
75    fOutFile.open (outFileName);
76    fpOutFile = &fOutFile;
77  }
78
79  G4cout << "G4ASCIITreeSceneHandler::BeginModeling: writing to ";
80  if (outFileName == "G4cout") {
81    G4cout << "G4 standard output (G4cout)";
82  } else {
83    G4cout << "file \"" << outFileName << "\"";
84  }
85  G4cout << G4endl;
86
87  WriteHeader (G4cout); G4cout << G4endl;
88  if (outFileName != "G4cout") {
89    WriteHeader (fOutFile); fOutFile << std::endl;
90  }
91}
92
93void G4ASCIITreeSceneHandler::WriteHeader (std::ostream& os)
94{
95  const G4ASCIITree* pSystem = (G4ASCIITree*)GetGraphicsSystem();
96  const G4int verbosity = pSystem->GetVerbosity();
97  const G4int detail = verbosity % 10;
98  os << "#  Set verbosity with \"/vis/ASCIITree/verbose <verbosity>\":";
99  for (size_t i = 0;
100       i < G4ASCIITreeMessenger::fVerbosityGuidance.size(); ++i) {
101    os << "\n#  " << G4ASCIITreeMessenger::fVerbosityGuidance[i];
102  }
103  os << "\n#  Now printing with verbosity " << verbosity;
104  os << "\n#  Format is: PV:n";
105  if (detail >= 1) os << " / LV (SD,RO)";
106  if (detail >= 2) os << " / Solid(type)";
107  if (detail >= 3) os << ", volume, density";
108  if (detail >= 5) os << ", daughter-subtracted volume and mass";
109  os <<
110    "\n#  Abbreviations: PV = Physical Volume,     LV = Logical Volume,"
111    "\n#                 SD = Sensitive Detector,  RO = Read Out Geometry.";
112}
113
114void G4ASCIITreeSceneHandler::EndModeling () {
115  const G4ASCIITree* pSystem = (G4ASCIITree*) GetGraphicsSystem();
116  const G4int verbosity = pSystem->GetVerbosity();
117  const G4int detail = verbosity % 10;
118  const G4String& outFileName = pSystem -> GetOutFileName();
119
120  // Output left over copy number, if any...
121  if (fLastCopyNo != fLastNonSequentialCopyNo) {
122    if (fLastCopyNo == fLastNonSequentialCopyNo + 1) *fpOutFile << ',';
123    else *fpOutFile << '-';
124    *fpOutFile << fLastCopyNo;
125  }
126  // Output outstanding rest of line, if any...
127  if (!fRestOfLine.str().empty()) *fpOutFile << fRestOfLine.str();
128  fRestOfLine.str("");
129  fpLastPV = 0;
130  fLastPVName.clear();
131  fLastCopyNo = -99;
132  fLastNonSequentialCopyNo = -99;
133
134  // This detail to G4cout regardless of outFileName...
135  if (detail >= 4) {
136    G4cout << "Calculating mass(es)..." << G4endl;
137    const std::vector<G4VModel*>& models = fpScene->GetRunDurationModelList();
138    std::vector<G4VModel*>::const_iterator i;
139    for (i = models.begin(); i != models.end(); ++i) {
140      G4PhysicalVolumeModel* pvModel =
141        dynamic_cast<G4PhysicalVolumeModel*>(*i);
142      if (pvModel) {
143        if (pvModel->GetTopPhysicalVolume() ==
144            G4TransportationManager::GetTransportationManager()
145            ->GetNavigatorForTracking()->GetWorldVolume()) {
146          const G4ModelingParameters* tempMP =
147            pvModel->GetModelingParameters();
148          G4ModelingParameters mp;  // Default - no culling.
149          pvModel->SetModelingParameters (&mp);
150          G4PhysicalVolumeMassScene massScene(pvModel);
151          pvModel->DescribeYourselfTo (massScene);
152          G4double volume = massScene.GetVolume();
153          G4double mass = massScene.GetMass();
154
155          G4cout << "Overall volume of \""
156                 << pvModel->GetTopPhysicalVolume()->GetName()
157                 << "\":"
158                 << pvModel->GetTopPhysicalVolume()->GetCopyNo()
159                 << ", is "
160                 << G4BestUnit (volume, "Volume")
161                 << " and the daughter-included mass";
162          G4int requestedDepth = pvModel->GetRequestedDepth();
163          if (requestedDepth == G4PhysicalVolumeModel::UNLIMITED) {
164            G4cout << " to unlimited depth";
165          } else {
166            G4cout << ", ignoring daughters at depth "
167                   << requestedDepth
168                   << " and below,";
169          }
170          G4cout << " is " << G4BestUnit (mass, "Mass")
171                 << G4endl;
172
173          pvModel->SetModelingParameters (tempMP);
174        }
175      }
176    }
177  }
178
179  if (outFileName != "G4cout") {
180    fOutFile.close();
181    G4cout << "Output file \"" << outFileName << "\" closed." << G4endl;
182  }
183  fLVSet.clear();
184  fReplicaSet.clear();
185  G4cout << "G4ASCIITreeSceneHandler::EndModeling" << G4endl;
186  G4VTreeSceneHandler::EndModeling ();  // To re-use "culling off" code.
187}
188
189void G4ASCIITreeSceneHandler::RequestPrimitives(const G4VSolid& solid) {
190 
191  G4PhysicalVolumeModel* pPVModel =
192    dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
193  if (!pPVModel) return;  // Not from a G4PhysicalVolumeModel.
194
195  // This call comes from a G4PhysicalVolumeModel.  drawnPVPath is
196  // the path of the current drawn (non-culled) volume in terms of
197  // drawn (non-culled) ancesters.  Each node is identified by a
198  // PVNodeID object, which is a physical volume and copy number.  It
199  // is a vector of PVNodeIDs corresponding to the geometry hierarchy
200  // actually selected, i.e., not culled.
201  typedef G4PhysicalVolumeModel::G4PhysicalVolumeNodeID PVNodeID;
202  typedef std::vector<PVNodeID> PVPath;
203  const PVPath& drawnPVPath = pPVModel->GetDrawnPVPath();
204  //G4int currentDepth = pPVModel->GetCurrentDepth();
205  G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
206  G4LogicalVolume* pCurrentLV = pPVModel->GetCurrentLV();
207  G4Material* pCurrentMaterial = pPVModel->GetCurrentMaterial();
208
209  G4ASCIITree* pSystem = (G4ASCIITree*)GetGraphicsSystem();
210  G4int verbosity = pSystem->GetVerbosity();
211  G4int detail = verbosity % 10;
212
213  if (verbosity < 10 && pCurrentPV->IsReplicated()) {
214    // See if this has been a replica found before with same mother LV...
215    PVPath::const_reverse_iterator thisID = drawnPVPath.rbegin();
216    PVPath::const_reverse_iterator motherID = ++drawnPVPath.rbegin();
217    G4bool ignore = false;
218    for (ReplicaSetIterator i = fReplicaSet.begin(); i != fReplicaSet.end();
219         ++i) {
220      if (i->back().GetPhysicalVolume()->GetLogicalVolume() ==
221          thisID->GetPhysicalVolume()->GetLogicalVolume()) {
222        // For each one previously found (if more than one, they must
223        // have different mothers)...
224        // To avoid compilation errors on VC++ .Net 7.1...
225        // Previously:
226        //   PVNodeID previousMotherID = ++(i->rbegin());
227        // (Should that have been: PVNodeID::const_iterator previousMotherID?)
228        // Replace
229        //   previousMotherID == i->rend()
230        // by
231        //   i->size() <= 1
232        // Replace
233        //   previousMotherID != i->rend()
234        // by
235        //   i->size() > 1
236        // Replace
237        //   previousMotherID->
238        // by
239        //   (*i)[i->size() - 2].
240        if (motherID == drawnPVPath.rend() &&
241            i->size() <= 1)
242          ignore = true;  // Both have no mother.
243        if (motherID != drawnPVPath.rend() &&
244            i->size() > 1 &&
245            motherID->GetPhysicalVolume()->GetLogicalVolume() ==
246            (*i)[i->size() - 2].GetPhysicalVolume()->GetLogicalVolume())
247          ignore = true;  // Same mother LV...
248      }
249    }
250    if (ignore) {
251      pPVModel->CurtailDescent();
252      return;
253    }
254  }
255
256  const G4String& currentPVName = pCurrentPV->GetName();
257  const G4int currentCopyNo = pCurrentPV->GetCopyNo();
258
259  if (verbosity < 10 && 
260      currentPVName == fLastPVName &&
261      currentCopyNo != fLastCopyNo) {
262    // For low verbosity, trap series of G4PVPlacements with the same name but
263    // different copy number (replicas should have been taken out above)...
264    // Check...
265    if (pCurrentPV->IsReplicated()) {
266      G4Exception("G4ASCIITreeSceneHandler::RequestPrimitives",
267                  "",
268                  JustWarning,
269                  "Replica unexpected");
270    }
271    // Check mothers are identical...
272    else if (pCurrentLV == (fpLastPV? fpLastPV->GetLogicalVolume(): 0)) {
273      if (currentCopyNo != fLastCopyNo + 1) {
274        // Non-sequential copy number...
275        *fpOutFile << ',' << currentCopyNo;
276        fLastNonSequentialCopyNo = currentCopyNo;
277      }
278      fLastCopyNo = currentCopyNo;
279      pPVModel->CurtailDescent();
280      return;
281    }
282  }
283  fpLastPV = pCurrentPV;
284
285  // High verbosity or a new G4VPhysicalVolume...
286  // Output copy number, if any, from previous invocation...
287  if (fLastCopyNo != fLastNonSequentialCopyNo) {
288    if (fLastCopyNo == fLastNonSequentialCopyNo + 1) *fpOutFile << ',';
289    else *fpOutFile << '-';
290    *fpOutFile << fLastCopyNo;
291  }
292  // Output rest of line, if any, from previous invocation...
293  if (!fRestOfLine.str().empty()) *fpOutFile << fRestOfLine.str();
294  fRestOfLine.str("");
295  fLastPVName = currentPVName;
296  fLastCopyNo = currentCopyNo;
297  fLastNonSequentialCopyNo = currentCopyNo;
298  // Indent according to drawn path depth...
299  for (size_t i = 0; i < drawnPVPath.size(); i++ ) *fpOutFile << "  ";
300  // Start next line...
301  *fpOutFile << "\"" << currentPVName
302             << "\":" << currentCopyNo;
303
304  if (pCurrentPV->IsReplicated()) {
305    if (verbosity < 10) {
306      // Add printing for replicas (when replicas are ignored)...
307      EAxis axis;
308      G4int nReplicas;
309      G4double width;
310      G4double offset;
311      G4bool consuming;
312      pCurrentPV->GetReplicationData(axis,nReplicas,width,offset,consuming);
313      G4VPVParameterisation* pP = pCurrentPV->GetParameterisation();
314      if (pP) {
315        if (detail < 3) {
316          fReplicaSet.insert(drawnPVPath);
317          if (nReplicas > 2) fRestOfLine << '-';
318          else fRestOfLine << ',';
319          fRestOfLine << nReplicas - 1
320                      << " (" << nReplicas << " parametrised volumes)";
321        }
322      }
323      else {
324        fReplicaSet.insert(drawnPVPath);
325        if (nReplicas > 2) fRestOfLine << '-';
326        else fRestOfLine << ',';
327        fRestOfLine << nReplicas - 1
328                    << " (" << nReplicas << " replicas)";
329      }
330    }
331  } else {
332    if (fLVSet.find(pCurrentLV) != fLVSet.end()) {
333      if (verbosity <  10) {
334        // Add printing for repeated LV (if it has daughters)...
335        if (pCurrentLV->GetNoDaughters()) fRestOfLine << " (repeated LV)";
336        // ...and curtail descent.
337        pPVModel->CurtailDescent();
338      }
339    }
340  }
341
342  if (detail >= 1) {
343    fRestOfLine << " / \""
344                << pCurrentLV->GetName() << "\"";
345    G4VSensitiveDetector* sd = pCurrentLV->GetSensitiveDetector();
346    if (sd) {
347      fRestOfLine << " (SD=\"" << sd->GetName() << "\"";
348      G4VReadOutGeometry* roGeom = sd->GetROgeometry();
349      if (roGeom) {
350        fRestOfLine << ",RO=\"" << roGeom->GetName() << "\"";
351      }
352      fRestOfLine << ")";
353    }
354  }
355
356  if (detail >= 2) {
357    fRestOfLine << " / \""
358               << solid.GetName()
359               << "\"("
360               << solid.GetEntityType() << ")";
361  }
362
363  if (detail >= 3) {
364    fRestOfLine << ", "
365                << G4BestUnit(((G4VSolid&)solid).GetCubicVolume(),"Volume")
366                << ", ";
367    if (pCurrentMaterial) {
368      fRestOfLine
369        << G4BestUnit(pCurrentMaterial->GetDensity(), "Volumic Mass")
370        << " (" << pCurrentMaterial->GetName() << ")";
371    } else {
372      fRestOfLine << "(No material)";
373    }
374  }
375
376  if (detail >= 5) {
377    if (pCurrentMaterial) {
378      G4Material* pMaterial = const_cast<G4Material*>(pCurrentMaterial);
379      // ...and find daughter-subtracted mass...
380      G4double daughter_subtracted_mass = pCurrentLV->GetMass
381        (pCurrentPV->IsParameterised(),  // Force if parametrised.
382         false,  // Do not propagate - calculate for this volume minus
383         // volume of daughters.
384         pMaterial);
385      G4double daughter_subtracted_volume =
386        daughter_subtracted_mass / pCurrentMaterial->GetDensity();
387      fRestOfLine << ", "
388                  << G4BestUnit(daughter_subtracted_volume,"Volume")
389                  << ", "
390                  << G4BestUnit(daughter_subtracted_mass,"Mass");
391    }
392  }
393
394  if (fLVSet.find(pCurrentLV) == fLVSet.end()) {
395    fLVSet.insert(pCurrentLV);  // Record new logical volume.
396  }
397
398  fRestOfLine << std::endl;
399
400  return;
401}
Note: See TracBrowser for help on using the repository browser.