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

Last change on this file since 1166 was 954, checked in by garnier, 17 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.