Geant4 Cross Reference |
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 // Code developed by: 27 // S.Guatelli, M. Large and A. Malaroda, University of Wollongong 28 // This class developed by John Allison, March 2021 29 // 30 31 #include "ICRP110PhantomVisAction.hh" 32 33 #include "G4VisManager.hh" 34 #include "ICRP110PhantomConstruction.hh" 35 #include "ICRP110PhantomPseudoScene.hh" 36 #include "G4PhysicalVolumeModel.hh" 37 #include "G4Polymarker.hh" 38 #include "G4SystemOfUnits.hh" 39 #include "Randomize.hh" 40 41 void ICRP110PhantomVisAction::Draw () 42 { 43 // Get actual vis manager 44 G4VVisManager* pVisManager = G4VVisManager::GetConcreteInstance(); 45 if (!pVisManager) return; 46 47 auto container = fpDetectorConstruction->GetPhantumContainer(); 48 49 static G4bool first = true; 50 if (first && container) { 51 first = false; 52 // Use ICRP110PhantomPseudoScene to build dataset in fPositionByColour 53 G4ModelingParameters tmpMP; 54 tmpMP.SetCulling(true); // This avoids drawing transparent... 55 tmpMP.SetCullingInvisible(true); // ... or invisble volumes. 56 const G4bool useFullExtent = true; // To avoid clculating the extent 57 G4PhysicalVolumeModel tmpPVModel 58 (container, 59 G4PhysicalVolumeModel::UNLIMITED, 60 G4Transform3D(), 61 &tmpMP, 62 useFullExtent); 63 ICRP110PhantomPseudoScene tmpScene 64 (&tmpPVModel 65 ,fPositionByMaterial 66 ,fColourByMaterial); 67 tmpPVModel.DescribeYourselfTo(tmpScene); 68 // Make list of found materials 69 for (const auto& entry: fColourByMaterial) { 70 fSetOfMaterials.insert(entry.first); 71 } 72 for (const auto& material: fSetOfMaterials) { 73 G4cout << "fSetOfMaterials: " << material->GetName() << G4endl; 74 } 75 } 76 77 // Seems the quantities in ICRP110PhantomConstruction don't have units 78 const G4double voxelHalfDimX = fpDetectorConstruction->GetVoxelHalfDimX()*mm; 79 const G4double voxelHalfDimY = fpDetectorConstruction->GetVoxelHalfDimY()*mm; 80 const G4double voxelHalfDimZ = fpDetectorConstruction->GetVoxelHalfDimZ()*mm; 81 82 static G4bool firstPrint = true; 83 G4int nDotsTotal = 0; 84 const G4int nDotsPerPositionMin = 1; 85 const G4int nDotsPerPositionMax = 10; 86 const G4double densityMin = 1.*g/cm3; 87 const G4double densityMax = 3.*g/cm3;; 88 for (const auto& material: fSetOfMaterials) { 89 auto& colour = fColourByMaterial[material]; 90 G4int nDots = 0; 91 G4Polymarker dots; 92 dots.SetVisAttributes(G4Colour(colour)); 93 dots.SetMarkerType(G4Polymarker::dots); 94 dots.SetSize(G4VMarker::screen,1.); 95 dots.SetInfo(material->GetName()); 96 const G4double currentDensity = material->GetDensity(); 97 const auto range = fPositionByMaterial.equal_range(material); 98 for (auto posByMat = range.first; posByMat != range.second; ++posByMat) { 99 G4int nDotsPerPosition 100 = nDotsPerPositionMin 101 + (nDotsPerPositionMax-nDotsPerPositionMin) 102 *(currentDensity-densityMin)/(densityMax-densityMin); 103 nDotsPerPosition = std::max(nDotsPerPositionMin,nDotsPerPosition); 104 nDotsPerPosition = std::min(nDotsPerPositionMax,nDotsPerPosition); 105 for (G4int i = 0; i < nDotsPerPosition; ++i) { 106 const G4double x = posByMat->second.getX() + (2.*G4UniformRand()-1.)*voxelHalfDimX; 107 const G4double y = posByMat->second.getY() + (2.*G4UniformRand()-1.)*voxelHalfDimY; 108 const G4double z = posByMat->second.getZ() + (2.*G4UniformRand()-1.)*voxelHalfDimZ; 109 dots.push_back(G4ThreeVector(x,y,z)); 110 ++nDots; 111 } 112 } 113 pVisManager->Draw(dots); 114 if (firstPrint) { 115 G4cout 116 << "Number of dots for material " << material->GetName() 117 << ", colour " << colour 118 << ": " << nDots << G4endl; 119 } 120 nDotsTotal += nDots; 121 } 122 if (firstPrint) { 123 G4cout << "Total number of dots: " << nDotsTotal << G4endl; 124 firstPrint = false; 125 } 126 } 127