Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 #include "Par03DetectorConstruction.hh" 26 #include "Par03DetectorConstruction.hh" 27 << 28 #include "Par03DetectorMessenger.hh" 27 #include "Par03DetectorMessenger.hh" 29 #include "Par03EMShowerModel.hh" << 30 #include "Par03SensitiveDetector.hh" 28 #include "Par03SensitiveDetector.hh" >> 29 #include "Par03EMShowerModel.hh" 31 30 >> 31 #include "G4NistManager.hh" >> 32 #include "G4Material.hh" 32 #include "G4Box.hh" 33 #include "G4Box.hh" >> 34 #include "G4Tubs.hh" 33 #include "G4LogicalVolume.hh" 35 #include "G4LogicalVolume.hh" 34 #include "G4Material.hh" << 35 #include "G4NistManager.hh" << 36 #include "G4PVPlacement.hh" 36 #include "G4PVPlacement.hh" 37 #include "G4PVReplica.hh" 37 #include "G4PVReplica.hh" 38 #include "G4Region.hh" << 38 #include "G4VisAttributes.hh" 39 #include "G4RegionStore.hh" << 40 #include "G4RunManager.hh" 39 #include "G4RunManager.hh" >> 40 41 #include "G4SDManager.hh" 41 #include "G4SDManager.hh" 42 #include "G4Tubs.hh" << 42 43 #include "G4UnitsTable.hh" 43 #include "G4UnitsTable.hh" 44 #include "G4VisAttributes.hh" << 44 >> 45 #include "G4Region.hh" >> 46 #include "G4RegionStore.hh" 45 47 46 //....oooOO0OOooo........oooOO0OOooo........oo 48 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 47 49 48 Par03DetectorConstruction::Par03DetectorConstr << 50 Par03DetectorConstruction::Par03DetectorConstruction() >> 51 : G4VUserDetectorConstruction() 49 { 52 { 50 fDetectorMessenger = new Par03DetectorMessen 53 fDetectorMessenger = new Par03DetectorMessenger(this); 51 54 52 G4NistManager* nistManager = G4NistManager:: 55 G4NistManager* nistManager = G4NistManager::Instance(); 53 fDetectorMaterial = nistManager->FindOrBuild << 56 fDetectorMaterial = nistManager->FindOrBuildMaterial("G4_Fe"); 54 } 57 } 55 58 56 //....oooOO0OOooo........oooOO0OOooo........oo 59 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 57 60 58 Par03DetectorConstruction::~Par03DetectorConst 61 Par03DetectorConstruction::~Par03DetectorConstruction() = default; 59 62 60 //....oooOO0OOooo........oooOO0OOooo........oo 63 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 61 64 62 G4VPhysicalVolume* Par03DetectorConstruction:: 65 G4VPhysicalVolume* Par03DetectorConstruction::Construct() 63 { 66 { 64 //--------- Material definition --------- 67 //--------- Material definition --------- 65 G4NistManager* nistManager = G4NistManager:: 68 G4NistManager* nistManager = G4NistManager::Instance(); 66 G4Material* air = nistManager->FindOrBuildMa << 69 G4Material* air = nistManager->FindOrBuildMaterial("G4_AIR"); 67 70 68 //--------- Derived dimensions --------- 71 //--------- Derived dimensions --------- 69 G4double full2Pi = 2. * CLHEP::pi * rad; << 72 G4double full2Pi = 2. * CLHEP::pi * rad; 70 G4double layerThickness = fDetectorLength / 73 G4double layerThickness = fDetectorLength / fNbOfLayers; 71 G4double cellPhi = full2Pi / fNbOfPhiCells; << 74 G4double cellPhi = full2Pi / fNbOfPhiCells; 72 G4double cellDR = fDetectorRadius / fNbOfRho << 75 G4double cellDR = fDetectorRadius / fNbOfRhoCells; 73 76 74 //--------- World --------- 77 //--------- World --------- 75 auto fSolidWorld = new G4Box("World", // na << 78 auto fSolidWorld = new G4Box("World", // name 76 fWorldSize / 2. << 79 fWorldSize / 2., // half-width in X 77 fWorldSize / 2. << 80 fWorldSize / 2., // half-width in Y 78 fWorldSize / 2. << 81 fWorldSize / 2.); // half-width in Z 79 auto fLogicWorld = new G4LogicalVolume(fSoli << 82 auto fLogicWorld = new G4LogicalVolume(fSolidWorld, // solid 80 air, << 83 air, // material 81 "Worl << 84 "World"); // name 82 auto fPhysicWorld = new G4PVPlacement(0, // << 85 auto fPhysicWorld = new G4PVPlacement(0, // no rotation 83 G4Thre 86 G4ThreeVector(), // at (0,0,0) 84 fLogic << 87 fLogicWorld, // logical volume 85 "World << 88 "World", // name 86 0, // << 89 0, // mother volume 87 false, << 90 false, // not used 88 999, << 91 999, // copy number 89 true); << 92 true); // copy number 90 93 91 //--------- Detector envelope --------- 94 //--------- Detector envelope --------- 92 auto fSolidDetector = new G4Tubs("Detector", << 95 auto fSolidDetector = new G4Tubs("Detector", // name 93 0, // inne << 96 0, // inner radius 94 fDetectorRa << 97 fDetectorRadius, // outer radius 95 fDetectorLe << 98 fDetectorLength / 2., // half-width in Z 96 0, // star << 99 0, // start angle 97 full2Pi); << 100 full2Pi); // delta angle 98 auto fLogicDetector = new G4LogicalVolume(fS 101 auto fLogicDetector = new G4LogicalVolume(fSolidDetector, // solid 99 fD 102 fDetectorMaterial, // material 100 "D << 103 "Detector"); // name 101 new G4PVPlacement(0, // no rotation << 104 new G4PVPlacement( 102 G4ThreeVector(0, 0, << 105 0, // no rotation 103 fDetectorLen << 106 G4ThreeVector(0, 0, 104 fLogicDetector, // logica << 107 fDetectorLength / 2), // detector face starts at (0,0,0) 105 "Detector", // name << 108 fLogicDetector, // logical volume 106 fLogicWorld, // mother vo << 109 "Detector", // name 107 false, // not used << 110 fLogicWorld, // mother volume 108 99, // copy number << 111 false, // not used 109 true); // check overlaps << 112 99, // copy number >> 113 true); // check overlaps 110 114 111 // Region for fast simulation 115 // Region for fast simulation 112 auto detectorRegion = new G4Region("Detector 116 auto detectorRegion = new G4Region("DetectorRegion"); 113 detectorRegion->AddRootLogicalVolume(fLogicD 117 detectorRegion->AddRootLogicalVolume(fLogicDetector); 114 118 115 //--------- Readout geometry --------- 119 //--------- Readout geometry --------- 116 // Layers (along z) 120 // Layers (along z) 117 auto fSolidLayer = new G4Tubs("Layer", // n << 121 auto fSolidLayer = new G4Tubs("Layer", // name 118 0, // inner r << 122 0, // inner radius 119 fDetectorRadiu << 123 fDetectorRadius, // outer radius 120 layerThickness << 124 layerThickness / 2., // half-width in Z 121 0, // start a << 125 0, // start angle 122 full2Pi); // << 126 full2Pi); // delta angle 123 auto fLogicLayer = new G4LogicalVolume(fSoli 127 auto fLogicLayer = new G4LogicalVolume(fSolidLayer, // solid 124 air, << 128 air, // material 125 "Laye << 129 "Layer"); // name 126 if (fNbOfLayers > 1) << 130 if(fNbOfLayers > 1) 127 new G4PVReplica("Layer", // name << 131 new G4PVReplica("Layer", // name 128 fLogicLayer, // logical v << 132 fLogicLayer, // logical volume 129 fLogicDetector, // mother << 133 fLogicDetector, // mother volume 130 kZAxis, // axis of replic << 134 kZAxis, // axis of replication 131 fNbOfLayers, // number of << 135 fNbOfLayers, // number of replicas 132 layerThickness); // width 136 layerThickness); // width of single replica 133 else 137 else 134 new G4PVPlacement(0, // no rotation << 138 new G4PVPlacement(0, // no rotation 135 G4ThreeVector(), // pla 139 G4ThreeVector(), // place at centre of mother volume 136 fLogicLayer, // logical << 140 fLogicLayer, // logical volume 137 "Layer", // name << 141 "Layer", // name 138 fLogicDetector, // moth << 142 fLogicDetector, // mother volume 139 false, // not used << 143 false, // not used 140 0, // copy number << 144 0, // copy number 141 true); // check overlap << 145 true); // check overlaps 142 146 143 // Layer segment (division in phi) 147 // Layer segment (division in phi) 144 auto fSolidRow = new G4Tubs("Row", // name << 148 auto fSolidRow = new G4Tubs("Row", // name 145 0, // inner rad << 149 0, // inner radius 146 fDetectorRadius, << 150 fDetectorRadius, // outer radius 147 layerThickness / 151 layerThickness / 2., // half-width in Z 148 0, // start ang << 152 0, // start angle 149 cellPhi); // de << 153 cellPhi); // delta angle 150 154 151 auto fLogicRow = new G4LogicalVolume(fSolidR << 155 auto fLogicRow = new G4LogicalVolume(fSolidRow, // solid 152 air, / << 156 air, // material 153 "Segmen 157 "Segment"); // name 154 if (fNbOfPhiCells > 1) << 158 if(fNbOfPhiCells > 1) 155 new G4PVReplica("Segment", // name << 159 new G4PVReplica("Segment", // name 156 fLogicRow, // logical vol << 160 fLogicRow, // logical volume 157 fLogicLayer, // mother vo << 161 fLogicLayer, // mother volume 158 kPhi, // axis of replicat << 162 kPhi, // axis of replication 159 fNbOfPhiCells, // number 163 fNbOfPhiCells, // number of replicas 160 cellPhi); // width of sin << 164 cellPhi); // width of single replica 161 else 165 else 162 new G4PVPlacement(0, // no rotation << 166 new G4PVPlacement(0, // no rotation 163 G4ThreeVector(), // pla 167 G4ThreeVector(), // place at centre of mother volume 164 fLogicRow, // logical v << 168 fLogicRow, // logical volume 165 "Row", // name << 169 "Row", // name 166 fLogicLayer, // mother << 170 fLogicLayer, // mother volume 167 false, // not used << 171 false, // not used 168 0, // copy number << 172 0, // copy number 169 true); // check overlap << 173 true); // check overlaps 170 174 171 // Final cells (segment slices in radius) 175 // Final cells (segment slices in radius) 172 // No volume can be placed inside a radial r 176 // No volume can be placed inside a radial replication 173 auto fSolidCell = new G4Tubs("Cell", // nam << 177 auto fSolidCell = new G4Tubs("Cell", // name 174 0, // inner ra << 178 0, // inner radius 175 cellDR, // out << 179 cellDR, // outer radius 176 layerThickness 180 layerThickness / 2., // half-width in Z 177 0, // start an << 181 0, // start angle 178 cellPhi); // d << 182 cellPhi); // delta angle 179 183 180 fLogicCell = new G4LogicalVolume(fSolidCell, << 184 fLogicCell = new G4LogicalVolume(fSolidCell, // solid 181 fDetectorMa 185 fDetectorMaterial, // material 182 "Cell"); / << 186 "Cell"); // name 183 if (fNbOfRhoCells > 1) << 187 if(fNbOfRhoCells > 1) 184 new G4PVReplica("Cell", // name << 188 new G4PVReplica("Cell", // name 185 fLogicCell, // logical vo << 189 fLogicCell, // logical volume 186 fLogicRow, // mother volu << 190 fLogicRow, // mother volume 187 kRho, // axis of replicat << 191 kRho, // axis of replication 188 fNbOfRhoCells, // number 192 fNbOfRhoCells, // number of replicas 189 cellDR); // width of sing << 193 cellDR); // width of single replica 190 else 194 else 191 new G4PVPlacement(0, // no rotation << 195 new G4PVPlacement(0, // no rotation 192 G4ThreeVector(), // pla 196 G4ThreeVector(), // place at centre of mother volume 193 fLogicCell, // logical << 197 fLogicCell, // logical volume 194 "Cell", // name << 198 "Cell", // name 195 fLogicRow, // mother vo << 199 fLogicRow, // mother volume 196 false, // not used << 200 false, // not used 197 0, // copy number << 201 0, // copy number 198 true); // check overlap << 202 true); // check overlaps 199 203 200 //--------- Visualisation settings --------- 204 //--------- Visualisation settings --------- 201 fLogicWorld->SetVisAttributes(G4VisAttribute 205 fLogicWorld->SetVisAttributes(G4VisAttributes::GetInvisible()); 202 fLogicLayer->SetVisAttributes(G4VisAttribute 206 fLogicLayer->SetVisAttributes(G4VisAttributes::GetInvisible()); 203 fLogicRow->SetVisAttributes(G4VisAttributes: 207 fLogicRow->SetVisAttributes(G4VisAttributes::GetInvisible()); 204 G4VisAttributes attribs; 208 G4VisAttributes attribs; 205 attribs.SetColour(G4Colour(0, 0, 1, 0.3)); 209 attribs.SetColour(G4Colour(0, 0, 1, 0.3)); 206 attribs.SetForceSolid(true); 210 attribs.SetForceSolid(true); 207 fLogicCell->SetVisAttributes(attribs); 211 fLogicCell->SetVisAttributes(attribs); 208 212 209 Print(); 213 Print(); 210 return fPhysicWorld; 214 return fPhysicWorld; 211 } 215 } 212 216 213 //....oooOO0OOooo........oooOO0OOooo........oo 217 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 214 218 215 void Par03DetectorConstruction::ConstructSDand 219 void Par03DetectorConstruction::ConstructSDandField() 216 { 220 { 217 Par03SensitiveDetector* caloSD = << 221 Par03SensitiveDetector* caloSD = new Par03SensitiveDetector( 218 new Par03SensitiveDetector("sensitiveDetec << 222 "sensitiveDetector", fNbOfLayers, fNbOfPhiCells, fNbOfRhoCells); 219 G4SDManager::GetSDMpointer()->AddNewDetector 223 G4SDManager::GetSDMpointer()->AddNewDetector(caloSD); 220 SetSensitiveDetector(fLogicCell, caloSD); 224 SetSensitiveDetector(fLogicCell, caloSD); 221 225 222 auto detectorRegion = G4RegionStore::GetInst << 226 auto detectorRegion = >> 227 G4RegionStore::GetInstance()->GetRegion("DetectorRegion"); 223 new Par03EMShowerModel("model", detectorRegi 228 new Par03EMShowerModel("model", detectorRegion); 224 } 229 } 225 230 226 //....oooOO0OOooo........oooOO0OOooo........oo 231 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 227 232 228 void Par03DetectorConstruction::Print() const 233 void Par03DetectorConstruction::Print() const 229 { 234 { 230 G4cout << "\n------------------------------- 235 G4cout << "\n------------------------------------------------------" 231 << "\n--- Detector material:\t" << fD 236 << "\n--- Detector material:\t" << fDetectorMaterial->GetName() 232 << "\n--- Detector length:\t" << G4Be 237 << "\n--- Detector length:\t" << G4BestUnit(fDetectorLength, "Length") 233 << "\n--- Detector radius:\t" << G4Be 238 << "\n--- Detector radius:\t" << G4BestUnit(fDetectorRadius, "Length") 234 << "\n--- Number of layers:\t" << fNb << 239 << "\n--- Number of layers:\t" << fNbOfLayers 235 << fNbOfRhoCells << "\n--- Number of << 240 << "\n--- Number of R-cells:\t" << fNbOfRhoCells >> 241 << "\n--- Number of phi-cells:\t" << fNbOfPhiCells << G4endl; 236 G4cout << "--------------------------------- 242 G4cout << "-----------------------------------------------------" << G4endl; 237 } 243 } 238 244 239 //....oooOO0OOooo........oooOO0OOooo........oo 245 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 240 246 241 void Par03DetectorConstruction::SetMaterial(co 247 void Par03DetectorConstruction::SetMaterial(const G4String& aName) 242 { 248 { 243 // search material by its name 249 // search material by its name 244 G4Material* material = G4NistManager::Instan 250 G4Material* material = G4NistManager::Instance()->FindOrBuildMaterial(aName); 245 if (material) << 251 if(material) 246 fDetectorMaterial = material; 252 fDetectorMaterial = material; 247 else 253 else 248 G4Exception("Par03DetectorConstruction::Se << 254 G4Exception("Par03DetectorConstruction::SetMaterial()", "InvalidSetup", 249 ("Unknown material name: " + a << 255 FatalException, ("Unknown material name: " + aName).c_str()); 250 G4RunManager::GetRunManager()->PhysicsHasBee 256 G4RunManager::GetRunManager()->PhysicsHasBeenModified(); 251 } 257 } 252 258 253 //....oooOO0OOooo........oooOO0OOooo........oo 259 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 254 260 255 void Par03DetectorConstruction::SetRadius(G4do 261 void Par03DetectorConstruction::SetRadius(G4double aRadius) 256 { 262 { 257 // check if fits within world volume 263 // check if fits within world volume 258 if (aRadius >= fWorldSize / 2.) << 264 if(aRadius >= fWorldSize / 2.) 259 G4Exception("Par03DetectorConstruction::Se << 265 G4Exception("Par03DetectorConstruction::SetRadius()", "InvalidSetup", 260 ("Detector radius cannot be la << 266 FatalException, 261 + G4String(G4BestUnit(fWorldS << 267 ("Detector radius cannot be larger than the world size (" + >> 268 G4String(G4BestUnit(fWorldSize / 2., "Length")) + ")") 262 .c_str()); 269 .c_str()); 263 fDetectorRadius = aRadius; 270 fDetectorRadius = aRadius; 264 } 271 } 265 //....oooOO0OOooo........oooOO0OOooo........oo 272 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 266 273 267 void Par03DetectorConstruction::SetLength(G4do 274 void Par03DetectorConstruction::SetLength(G4double aLength) 268 { 275 { 269 // check if fits within world volume 276 // check if fits within world volume 270 if (aLength >= fWorldSize / 2.) << 277 if(aLength >= fWorldSize / 2.) 271 G4Exception("Par03DetectorConstruction::Se << 278 G4Exception("Par03DetectorConstruction::SetLength()", "InvalidSetup", 272 ("Detector length cannot be la << 279 FatalException, 273 + G4String(G4BestUnit(fWorldS << 280 ("Detector length cannot be larger than the world size (" + >> 281 G4String(G4BestUnit(fWorldSize / 2., "Length")) + ")") 274 .c_str()); 282 .c_str()); 275 fDetectorLength = aLength; 283 fDetectorLength = aLength; 276 } 284 }