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 27 // User Classes 28 #include "Par04ParallelFastWorld.hh" 29 30 #include "Par04ParallelFastSensitiveDetector.hh" 31 #include "Par04ParallelFullWorld.hh" 32 33 // G4 Classes 34 #include "G4AutoDelete.hh" 35 #include "G4Colour.hh" 36 #include "G4LogicalVolume.hh" 37 #include "G4Material.hh" 38 #include "G4NistManager.hh" 39 #include "G4PVPlacement.hh" 40 #include "G4PVReplica.hh" 41 #include "G4SDManager.hh" 42 #include "G4SystemOfUnits.hh" 43 #include "G4ThreeVector.hh" 44 #include "G4Tubs.hh" 45 #include "G4UnitsTable.hh" 46 #include "G4VPhysicalVolume.hh" 47 #include "G4VisAttributes.hh" 48 #include "globals.hh" 49 50 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 51 52 Par04ParallelFastWorld::Par04ParallelFastWorld(G4String aWorldName, 53 const Par04DetectorConstruction* aMassDetector, 54 const Par04ParallelFullWorld* aParallelFull) 55 : G4VUserParallelWorld(aWorldName), fMassDetector(aMassDetector), fParallelFull(aParallelFull) 56 { 57 fNbOfLayers = fMassDetector->GetNbOfLayers(); 58 } 59 60 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 61 62 Par04ParallelFastWorld::~Par04ParallelFastWorld() = default; 63 64 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 65 66 void Par04ParallelFastWorld::Construct() 67 { 68 // In parallel world material does not matter 69 G4Material* dummy = nullptr; 70 71 // Build parallel geometry: 72 auto parallelLogicalVolume = GetWorld()->GetLogicalVolume(); 73 74 G4double detectorInnerRadius = fMassDetector->GetInnerRadius(); 75 G4double detectorLength = fMassDetector->GetLength(); 76 G4double fullLayerThickness = 77 fMassDetector->GetAbsorberThickness(0) + fMassDetector->GetAbsorberThickness(1); 78 fLayerThickness = fullLayerThickness; 79 // Get an updated value 80 fNbOfLayers = fMassDetector->GetNbOfLayers(); 81 fNbOfSlices = fParallelFull->GetNbOfSlices(); 82 fNbOfRows = fParallelFull->GetNbOfRows(); 83 G4double detectorRadius = fNbOfLayers * fullLayerThickness; 84 G4double detectorOuterRadius = detectorInnerRadius + detectorRadius; 85 G4double rowThickness = detectorLength / fNbOfRows; 86 G4double full2Pi = 2. * CLHEP::pi * rad; 87 Print(); 88 89 // Insert cells to create a readout structure that contains both passive and active materials 90 // Mostly a copy from the detector construction 91 auto solidDetector = new G4Tubs("Detector", // name 92 detectorInnerRadius, // inner radius 93 detectorOuterRadius, // outer radius 94 detectorLength / 2., // half-width in Z 95 0, // start angle 96 full2Pi); // delta angle 97 auto logicDetector = new G4LogicalVolume(solidDetector, // solid 98 dummy, // material 99 "Detector"); // name 100 new G4PVPlacement(0, // no rotation 101 G4ThreeVector(0, 0, 0), // detector centre at (0,0,0) 102 logicDetector, // logical volume 103 "Detector", // name 104 parallelLogicalVolume, // mother volume 105 false, // not used 106 9999, // copy number 107 true); // check overlaps 108 109 //--------- Detector cylinder (division along z axis) --------- 110 auto solidRow = 111 new G4Tubs("Row", detectorInnerRadius, detectorOuterRadius, rowThickness / 2., 0, full2Pi); 112 113 auto logicRow = new G4LogicalVolume(solidRow, dummy, "Row"); 114 if (fNbOfRows > 1) 115 new G4PVReplica("Row", logicRow, logicDetector, kZAxis, fNbOfRows, rowThickness); 116 else 117 new G4PVPlacement(0, G4ThreeVector(), logicRow, "Row", logicDetector, false, 0); 118 119 //--------- Detector slices (division in azimuthal angle) --------- 120 G4double cellPhi = full2Pi / fNbOfSlices; 121 auto solidSlice = 122 new G4Tubs("Slice", detectorInnerRadius, detectorOuterRadius, rowThickness / 2, 0, cellPhi); 123 auto logicSlice = new G4LogicalVolume(solidSlice, dummy, "Slice"); 124 if (fNbOfSlices > 1) { 125 new G4PVReplica("Slice", logicSlice, logicRow, kPhi, fNbOfSlices, cellPhi, -cellPhi); 126 } 127 else { 128 new G4PVPlacement(0, G4ThreeVector(), logicSlice, "Slice", logicRow, false, 0); 129 } 130 131 //--------- Detector cells (division along radial axis) --------- 132 G4VisAttributes attribs; 133 attribs.SetColour(G4Colour(0, 1, 0, 0.1)); 134 attribs.SetForceSolid(true); 135 if (fNbOfLayers > 1) { 136 auto solidCell = new G4Tubs("Cell", detectorInnerRadius, detectorInnerRadius + fLayerThickness, 137 rowThickness / 2, 0, cellPhi); 138 fLogicalCell.push_back(new G4LogicalVolume(solidCell, dummy, "Cell_0")); 139 new G4PVReplica("Cell", fLogicalCell.back(), logicSlice, kRho, fNbOfLayers, fLayerThickness, 140 detectorInnerRadius); 141 } 142 else { 143 auto solidCell = new G4Tubs("Cell", detectorInnerRadius, detectorInnerRadius + fLayerThickness, 144 rowThickness / 2, 0, cellPhi); 145 fLogicalCell.push_back(new G4LogicalVolume(solidCell, dummy, "Cell")); 146 fLogicalCell.back()->SetVisAttributes(attribs); 147 new G4PVPlacement(0, G4ThreeVector(), fLogicalCell.back(), "Cell", logicSlice, false, 0); 148 } 149 Print(); 150 } 151 152 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 153 154 void Par04ParallelFastWorld::ConstructSD() 155 { 156 // -- sensitive detectors: 157 G4SDManager* SDman = G4SDManager::GetSDMpointer(); 158 Par04ParallelFastSensitiveDetector* caloSD = 159 new Par04ParallelFastSensitiveDetector("parallelFastSD", fNbOfLayers, fNbOfSlices); 160 SDman->AddNewDetector(caloSD); 161 for (const auto& logicalCell : fLogicalCell) 162 logicalCell->SetSensitiveDetector(caloSD); 163 } 164 165 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 166 167 void Par04ParallelFastWorld::Print() 168 { 169 G4cout << "\n------------------------------------------------------" 170 << "\n Readout geometry with physics layout is set in parallel geometry:\t" 171 << "\n Cylindrical detector is divided along radius (layers), phi (slices), and z (rows)." 172 << "\n Number of layers is determined by number of layers set in detector construction. " 173 << "\n- Number of layers: " << fNbOfLayers << "\n------- Number of slices: " << fNbOfSlices 174 << "\n- Number of rows: " << fNbOfRows; 175 G4cout << "\n Readout will collect energy from fast simulation.\n------- Thickness is " 176 << "a sum of all absorbers" 177 << " = " << G4BestUnit(fLayerThickness, "Length") 178 << "\n-----------------------------------------------------" << G4endl; 179 } 180