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 // 26 // 27 /// \file B4/B4d/src/DetectorConstruction.cc 27 /// \file B4/B4d/src/DetectorConstruction.cc 28 /// \brief Implementation of the B4d::Detector 28 /// \brief Implementation of the B4d::DetectorConstruction class 29 29 30 #include "DetectorConstruction.hh" 30 #include "DetectorConstruction.hh" 31 31 32 #include "G4AutoDelete.hh" << 33 #include "G4Box.hh" << 34 #include "G4Colour.hh" << 35 #include "G4GlobalMagFieldMessenger.hh" << 36 #include "G4LogicalVolume.hh" << 37 #include "G4Material.hh" 32 #include "G4Material.hh" 38 #include "G4MultiFunctionalDetector.hh" << 39 #include "G4NistManager.hh" 33 #include "G4NistManager.hh" 40 #include "G4PSEnergyDeposit.hh" << 34 41 #include "G4PSTrackLength.hh" << 35 #include "G4Box.hh" >> 36 #include "G4LogicalVolume.hh" 42 #include "G4PVPlacement.hh" 37 #include "G4PVPlacement.hh" 43 #include "G4PVReplica.hh" 38 #include "G4PVReplica.hh" 44 #include "G4PhysicalConstants.hh" << 39 #include "G4GlobalMagFieldMessenger.hh" 45 #include "G4SDChargedFilter.hh" << 40 #include "G4AutoDelete.hh" >> 41 46 #include "G4SDManager.hh" 42 #include "G4SDManager.hh" 47 #include "G4SystemOfUnits.hh" << 43 #include "G4SDChargedFilter.hh" >> 44 #include "G4MultiFunctionalDetector.hh" 48 #include "G4VPrimitiveScorer.hh" 45 #include "G4VPrimitiveScorer.hh" >> 46 #include "G4PSEnergyDeposit.hh" >> 47 #include "G4PSTrackLength.hh" >> 48 49 #include "G4VisAttributes.hh" 49 #include "G4VisAttributes.hh" >> 50 #include "G4Colour.hh" >> 51 >> 52 #include "G4PhysicalConstants.hh" >> 53 #include "G4SystemOfUnits.hh" 50 54 51 namespace B4d 55 namespace B4d 52 { 56 { 53 57 54 //....oooOO0OOooo........oooOO0OOooo........oo 58 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 55 59 56 G4ThreadLocal G4GlobalMagFieldMessenger* Detec << 60 G4ThreadLocal >> 61 G4GlobalMagFieldMessenger* DetectorConstruction::fMagFieldMessenger = nullptr; 57 62 58 //....oooOO0OOooo........oooOO0OOooo........oo 63 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 59 64 60 G4VPhysicalVolume* DetectorConstruction::Const 65 G4VPhysicalVolume* DetectorConstruction::Construct() 61 { 66 { 62 // Define materials 67 // Define materials 63 DefineMaterials(); 68 DefineMaterials(); 64 69 65 // Define volumes 70 // Define volumes 66 return DefineVolumes(); 71 return DefineVolumes(); 67 } 72 } 68 73 69 //....oooOO0OOooo........oooOO0OOooo........oo 74 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 70 75 71 void DetectorConstruction::DefineMaterials() 76 void DetectorConstruction::DefineMaterials() 72 { 77 { 73 // Lead material defined using NIST Manager 78 // Lead material defined using NIST Manager 74 auto nistManager = G4NistManager::Instance() 79 auto nistManager = G4NistManager::Instance(); 75 nistManager->FindOrBuildMaterial("G4_Pb"); 80 nistManager->FindOrBuildMaterial("G4_Pb"); 76 81 77 // Liquid argon material 82 // Liquid argon material 78 G4double a; // mass of a mole; 83 G4double a; // mass of a mole; 79 G4double z; // z=mean number of protons; 84 G4double z; // z=mean number of protons; 80 G4double density; 85 G4double density; 81 new G4Material("liquidArgon", z = 18., a = 3 << 86 new G4Material("liquidArgon", z=18., a= 39.95*g/mole, density= 1.390*g/cm3); 82 // The argon by NIST Manager is a gas with a << 87 // The argon by NIST Manager is a gas with a different density 83 88 84 // Vacuum 89 // Vacuum 85 new G4Material("Galactic", z = 1., a = 1.01 << 90 new G4Material("Galactic", z=1., a=1.01*g/mole,density= universe_mean_density, 86 kStateGas, 2.73 * kelvin, 3.e << 91 kStateGas, 2.73*kelvin, 3.e-18*pascal); 87 92 88 // Print materials 93 // Print materials 89 G4cout << *(G4Material::GetMaterialTable()) 94 G4cout << *(G4Material::GetMaterialTable()) << G4endl; 90 } 95 } 91 96 92 //....oooOO0OOooo........oooOO0OOooo........oo 97 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 93 98 94 G4VPhysicalVolume* DetectorConstruction::Defin 99 G4VPhysicalVolume* DetectorConstruction::DefineVolumes() 95 { 100 { 96 // Geometry parameters 101 // Geometry parameters 97 G4int nofLayers = 10; << 102 G4int nofLayers = 10; 98 G4double absoThickness = 10. * mm; << 103 G4double absoThickness = 10.*mm; 99 G4double gapThickness = 5. * mm; << 104 G4double gapThickness = 5.*mm; 100 G4double calorSizeXY = 10. * cm; << 105 G4double calorSizeXY = 10.*cm; 101 << 106 102 auto layerThickness = absoThickness + gapThi << 107 auto layerThickness = absoThickness + gapThickness; 103 auto calorThickness = nofLayers * layerThick << 108 auto calorThickness = nofLayers * layerThickness; 104 auto worldSizeXY = 1.2 * calorSizeXY; << 109 auto worldSizeXY = 1.2 * calorSizeXY; 105 auto worldSizeZ = 1.2 * calorThickness; << 110 auto worldSizeZ = 1.2 * calorThickness; 106 111 107 // Get materials 112 // Get materials 108 auto defaultMaterial = G4Material::GetMateri 113 auto defaultMaterial = G4Material::GetMaterial("Galactic"); 109 auto absorberMaterial = G4Material::GetMater 114 auto absorberMaterial = G4Material::GetMaterial("G4_Pb"); 110 auto gapMaterial = G4Material::GetMaterial(" 115 auto gapMaterial = G4Material::GetMaterial("liquidArgon"); 111 116 112 if (!defaultMaterial || !absorberMaterial || << 117 if ( ! defaultMaterial || ! absorberMaterial || ! gapMaterial ) { 113 G4ExceptionDescription msg; 118 G4ExceptionDescription msg; 114 msg << "Cannot retrieve materials already 119 msg << "Cannot retrieve materials already defined."; 115 G4Exception("DetectorConstruction::DefineV << 120 G4Exception("DetectorConstruction::DefineVolumes()", >> 121 "MyCode0001", FatalException, msg); 116 } 122 } 117 123 118 // 124 // 119 // World 125 // World 120 // 126 // 121 auto worldS = new G4Box("World", // its nam << 127 auto worldS 122 worldSizeXY / 2, wor << 128 = new G4Box("World", // its name 123 << 129 worldSizeXY/2, worldSizeXY/2, worldSizeZ/2); // its size 124 auto worldLV = new G4LogicalVolume(worldS, << 130 125 defaultMa << 131 auto worldLV 126 "World"); << 132 = new G4LogicalVolume( >> 133 worldS, // its solid >> 134 defaultMaterial, // its material >> 135 "World"); // its name 127 136 128 auto worldPV = new G4PVPlacement(nullptr, / 137 auto worldPV = new G4PVPlacement(nullptr, // no rotation 129 G4ThreeVect << 138 G4ThreeVector(), // at (0,0,0) 130 worldLV, / << 139 worldLV, // its logical volume 131 "World", / << 140 "World", // its name 132 nullptr, / << 141 nullptr, // its mother volume 133 false, // << 142 false, // no boolean operation 134 0, // copy << 143 0, // copy number 135 fCheckOverl << 144 fCheckOverlaps); // checking overlaps 136 145 137 // 146 // 138 // Calorimeter 147 // Calorimeter 139 // 148 // 140 auto calorimeterS = new G4Box("Calorimeter", << 149 auto calorimeterS 141 calorSizeXY / << 150 = new G4Box("Calorimeter", // its name 142 << 151 calorSizeXY/2, calorSizeXY/2, calorThickness/2); // its size 143 auto calorLV = new G4LogicalVolume(calorimet << 152 144 defaultMa << 153 auto calorLV 145 "Calorime << 154 = new G4LogicalVolume( >> 155 calorimeterS, // its solid >> 156 defaultMaterial, // its material >> 157 "Calorimeter"); // its name 146 158 147 new G4PVPlacement(nullptr, // no rotation 159 new G4PVPlacement(nullptr, // no rotation 148 G4ThreeVector(), // at (0 << 160 G4ThreeVector(), // at (0,0,0) 149 calorLV, // its logical v << 161 calorLV, // its logical volume 150 "Calorimeter", // its nam << 162 "Calorimeter", // its name 151 worldLV, // its mother v << 163 worldLV, // its mother volume 152 false, // no boolean oper << 164 false, // no boolean operation 153 0, // copy number << 165 0, // copy number 154 fCheckOverlaps); // check << 166 fCheckOverlaps); // checking overlaps 155 167 156 // 168 // 157 // Layer 169 // Layer 158 // 170 // 159 auto layerS = new G4Box("Layer", // its nam << 171 auto layerS 160 calorSizeXY / 2, cal << 172 = new G4Box("Layer", // its name 161 << 173 calorSizeXY/2, calorSizeXY/2, layerThickness/2); // its size 162 auto layerLV = new G4LogicalVolume(layerS, << 174 163 defaultMa << 175 auto layerLV 164 "Layer"); << 176 = new G4LogicalVolume( 165 << 177 layerS, // its solid 166 new G4PVReplica("Layer", // its name << 178 defaultMaterial, // its material 167 layerLV, // its logical vol << 179 "Layer"); // its name 168 calorLV, // its mother << 180 169 kZAxis, // axis of replicat << 181 new G4PVReplica( 170 nofLayers, // number of rep << 182 "Layer", // its name 171 layerThickness); // witdth << 183 layerLV, // its logical volume >> 184 calorLV, // its mother >> 185 kZAxis, // axis of replication >> 186 nofLayers, // number of replica >> 187 layerThickness); // witdth of replica 172 188 173 // 189 // 174 // Absorber 190 // Absorber 175 // 191 // 176 auto absorberS = new G4Box("Abso", // its n << 192 auto absorberS 177 calorSizeXY / 2, << 193 = new G4Box("Abso", // its name 178 << 194 calorSizeXY/2, calorSizeXY/2, absoThickness/2); // its size 179 auto absorberLV = new G4LogicalVolume(absorb << 195 180 absorb << 196 auto absorberLV 181 "AbsoL << 197 = new G4LogicalVolume( 182 << 198 absorberS, // its solid 183 new G4PVPlacement(nullptr, // no rotation << 199 absorberMaterial, // its material 184 G4ThreeVector(0., 0., -gap << 200 "AbsoLV"); // its name 185 absorberLV, // its logica << 201 186 "Abso", // its name << 202 new G4PVPlacement(nullptr, // no rotation 187 layerLV, // its mother v << 203 G4ThreeVector(0., 0., -gapThickness / 2), // its position 188 false, // no boolean oper << 204 absorberLV, // its logical volume 189 0, // copy number << 205 "Abso", // its name 190 fCheckOverlaps); // check << 206 layerLV, // its mother volume >> 207 false, // no boolean operation >> 208 0, // copy number >> 209 fCheckOverlaps); // checking overlaps 191 210 192 // 211 // 193 // Gap 212 // Gap 194 // 213 // 195 auto gapS = new G4Box("Gap", // its name << 214 auto gapS 196 calorSizeXY / 2, calor << 215 = new G4Box("Gap", // its name 197 << 216 calorSizeXY/2, calorSizeXY/2, gapThickness/2); // its size 198 auto gapLV = new G4LogicalVolume(gapS, // i << 217 199 gapMaterial << 218 auto gapLV 200 "GapLV"); << 219 = new G4LogicalVolume( 201 << 220 gapS, // its solid 202 new G4PVPlacement(nullptr, // no rotation << 221 gapMaterial, // its material 203 G4ThreeVector(0., 0., abso << 222 "GapLV"); // its name 204 gapLV, // its logical vol << 223 205 "Gap", // its name << 224 new G4PVPlacement(nullptr, // no rotation 206 layerLV, // its mother v << 225 G4ThreeVector(0., 0., absoThickness / 2), // its position 207 false, // no boolean oper << 226 gapLV, // its logical volume 208 0, // copy number << 227 "Gap", // its name 209 fCheckOverlaps); // check << 228 layerLV, // its mother volume >> 229 false, // no boolean operation >> 230 0, // copy number >> 231 fCheckOverlaps); // checking overlaps 210 232 211 // 233 // 212 // print parameters 234 // print parameters 213 // 235 // 214 G4cout << G4endl << "----------------------- << 236 G4cout 215 << "---> The calorimeter is " << nofL << 237 << G4endl 216 << "mm of " << absorberMaterial->GetN << 238 << "------------------------------------------------------------" << G4endl 217 << gapMaterial->GetName() << " ] " << << 239 << "---> The calorimeter is " << nofLayers << " layers of: [ " 218 << "--------------------------------- << 240 << absoThickness/mm << "mm of " << absorberMaterial->GetName() >> 241 << " + " >> 242 << gapThickness/mm << "mm of " << gapMaterial->GetName() << " ] " << G4endl >> 243 << "------------------------------------------------------------" << G4endl; 219 244 220 // 245 // 221 // Visualization attributes 246 // Visualization attributes 222 // 247 // 223 worldLV->SetVisAttributes(G4VisAttributes::G << 248 worldLV->SetVisAttributes (G4VisAttributes::GetInvisible()); 224 calorLV->SetVisAttributes(G4VisAttributes(G4 << 249 >> 250 auto simpleBoxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0)); >> 251 simpleBoxVisAtt->SetVisibility(true); >> 252 calorLV->SetVisAttributes(simpleBoxVisAtt); 225 253 226 // 254 // 227 // Always return the physical World 255 // Always return the physical World 228 // 256 // 229 return worldPV; 257 return worldPV; 230 } 258 } 231 259 232 //....oooOO0OOooo........oooOO0OOooo........oo 260 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 233 261 234 void DetectorConstruction::ConstructSDandField 262 void DetectorConstruction::ConstructSDandField() 235 { 263 { 236 G4SDManager::GetSDMpointer()->SetVerboseLeve 264 G4SDManager::GetSDMpointer()->SetVerboseLevel(1); 237 // 265 // 238 // Scorers 266 // Scorers 239 // 267 // 240 268 241 // declare Absorber as a MultiFunctionalDete 269 // declare Absorber as a MultiFunctionalDetector scorer 242 // 270 // 243 auto absDetector = new G4MultiFunctionalDete 271 auto absDetector = new G4MultiFunctionalDetector("Absorber"); 244 G4SDManager::GetSDMpointer()->AddNewDetector 272 G4SDManager::GetSDMpointer()->AddNewDetector(absDetector); 245 273 246 G4VPrimitiveScorer* primitive; 274 G4VPrimitiveScorer* primitive; 247 primitive = new G4PSEnergyDeposit("Edep"); 275 primitive = new G4PSEnergyDeposit("Edep"); 248 absDetector->RegisterPrimitive(primitive); 276 absDetector->RegisterPrimitive(primitive); 249 277 250 primitive = new G4PSTrackLength("TrackLength 278 primitive = new G4PSTrackLength("TrackLength"); 251 auto charged = new G4SDChargedFilter("charge 279 auto charged = new G4SDChargedFilter("chargedFilter"); 252 primitive->SetFilter(charged); << 280 primitive ->SetFilter(charged); 253 absDetector->RegisterPrimitive(primitive); 281 absDetector->RegisterPrimitive(primitive); 254 282 255 SetSensitiveDetector("AbsoLV", absDetector); << 283 SetSensitiveDetector("AbsoLV",absDetector); 256 284 257 // declare Gap as a MultiFunctionalDetector 285 // declare Gap as a MultiFunctionalDetector scorer 258 // 286 // 259 auto gapDetector = new G4MultiFunctionalDete 287 auto gapDetector = new G4MultiFunctionalDetector("Gap"); 260 G4SDManager::GetSDMpointer()->AddNewDetector 288 G4SDManager::GetSDMpointer()->AddNewDetector(gapDetector); 261 289 262 primitive = new G4PSEnergyDeposit("Edep"); 290 primitive = new G4PSEnergyDeposit("Edep"); 263 gapDetector->RegisterPrimitive(primitive); 291 gapDetector->RegisterPrimitive(primitive); 264 292 265 primitive = new G4PSTrackLength("TrackLength 293 primitive = new G4PSTrackLength("TrackLength"); 266 primitive->SetFilter(charged); << 294 primitive ->SetFilter(charged); 267 gapDetector->RegisterPrimitive(primitive); 295 gapDetector->RegisterPrimitive(primitive); 268 296 269 SetSensitiveDetector("GapLV", gapDetector); << 297 SetSensitiveDetector("GapLV",gapDetector); 270 298 271 // 299 // 272 // Magnetic field 300 // Magnetic field 273 // 301 // 274 // Create global magnetic field messenger. 302 // Create global magnetic field messenger. 275 // Uniform magnetic field is then created au 303 // Uniform magnetic field is then created automatically if 276 // the field value is not zero. 304 // the field value is not zero. 277 G4ThreeVector fieldValue; 305 G4ThreeVector fieldValue; 278 fMagFieldMessenger = new G4GlobalMagFieldMes 306 fMagFieldMessenger = new G4GlobalMagFieldMessenger(fieldValue); 279 fMagFieldMessenger->SetVerboseLevel(1); 307 fMagFieldMessenger->SetVerboseLevel(1); 280 308 281 // Register the field messenger for deleting 309 // Register the field messenger for deleting 282 G4AutoDelete::Register(fMagFieldMessenger); 310 G4AutoDelete::Register(fMagFieldMessenger); 283 } 311 } 284 312 285 //....oooOO0OOooo........oooOO0OOooo........oo 313 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 286 314 287 } // namespace B4d << 315 } 288 316