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 B2/B2b/src/DetectorConstruction.cc << 27 /// \file DetectorConstruction.cc 28 /// \brief Implementation of the B2b::Detector 28 /// \brief Implementation of the B2b::DetectorConstruction class 29 29 30 #include "DetectorConstruction.hh" 30 #include "DetectorConstruction.hh" 31 << 32 #include "ChamberParameterisation.hh" << 33 #include "DetectorMessenger.hh" 31 #include "DetectorMessenger.hh" >> 32 #include "ChamberParameterisation.hh" 34 #include "TrackerSD.hh" 33 #include "TrackerSD.hh" 35 34 36 #include "G4AutoDelete.hh" << 37 #include "G4Box.hh" << 38 #include "G4Colour.hh" << 39 #include "G4GeometryManager.hh" << 40 #include "G4GeometryTolerance.hh" << 41 #include "G4GlobalMagFieldMessenger.hh" << 42 #include "G4LogicalVolume.hh" << 43 #include "G4Material.hh" 35 #include "G4Material.hh" 44 #include "G4NistManager.hh" 36 #include "G4NistManager.hh" 45 #include "G4PVParameterised.hh" << 46 #include "G4PVPlacement.hh" << 47 #include "G4SDManager.hh" 37 #include "G4SDManager.hh" 48 #include "G4SystemOfUnits.hh" << 38 49 #include "G4ThreeVector.hh" << 39 #include "G4Box.hh" 50 #include "G4Tubs.hh" 40 #include "G4Tubs.hh" >> 41 #include "G4LogicalVolume.hh" >> 42 #include "G4PVPlacement.hh" >> 43 #include "G4PVParameterised.hh" >> 44 #include "G4GlobalMagFieldMessenger.hh" >> 45 #include "G4AutoDelete.hh" >> 46 >> 47 #include "G4GeometryTolerance.hh" >> 48 #include "G4GeometryManager.hh" >> 49 51 #include "G4UserLimits.hh" 50 #include "G4UserLimits.hh" >> 51 52 #include "G4VisAttributes.hh" 52 #include "G4VisAttributes.hh" >> 53 #include "G4Colour.hh" >> 54 >> 55 #include "G4SystemOfUnits.hh" 53 56 54 using namespace B2; 57 using namespace B2; 55 58 56 namespace B2b 59 namespace B2b 57 { 60 { 58 61 59 //....oooOO0OOooo........oooOO0OOooo........oo 62 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 60 63 61 G4ThreadLocal G4GlobalMagFieldMessenger* Detec << 64 G4ThreadLocal >> 65 G4GlobalMagFieldMessenger* DetectorConstruction::fMagFieldMessenger = nullptr; 62 66 63 DetectorConstruction::DetectorConstruction() 67 DetectorConstruction::DetectorConstruction() 64 { 68 { 65 fMessenger = new DetectorMessenger(this); 69 fMessenger = new DetectorMessenger(this); 66 } 70 } 67 71 68 //....oooOO0OOooo........oooOO0OOooo........oo 72 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 69 73 70 DetectorConstruction::~DetectorConstruction() 74 DetectorConstruction::~DetectorConstruction() 71 { 75 { 72 delete fStepLimit; 76 delete fStepLimit; 73 delete fMessenger; 77 delete fMessenger; 74 } 78 } 75 79 76 //....oooOO0OOooo........oooOO0OOooo........oo 80 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 77 81 78 G4VPhysicalVolume* DetectorConstruction::Const 82 G4VPhysicalVolume* DetectorConstruction::Construct() 79 { 83 { 80 // Define materials 84 // Define materials 81 DefineMaterials(); 85 DefineMaterials(); 82 86 83 // Define volumes 87 // Define volumes 84 return DefineVolumes(); 88 return DefineVolumes(); 85 } 89 } 86 90 87 //....oooOO0OOooo........oooOO0OOooo........oo 91 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 88 92 89 void DetectorConstruction::DefineMaterials() 93 void DetectorConstruction::DefineMaterials() 90 { 94 { 91 // Material definition 95 // Material definition 92 96 93 G4NistManager* nistManager = G4NistManager:: 97 G4NistManager* nistManager = G4NistManager::Instance(); 94 98 95 // Air defined using NIST Manager 99 // Air defined using NIST Manager 96 nistManager->FindOrBuildMaterial("G4_AIR"); 100 nistManager->FindOrBuildMaterial("G4_AIR"); 97 101 98 // Lead defined using NIST Manager 102 // Lead defined using NIST Manager 99 fTargetMaterial = nistManager->FindOrBuildMa << 103 fTargetMaterial = nistManager->FindOrBuildMaterial("G4_Pb"); 100 104 101 // Xenon gas defined using NIST Manager 105 // Xenon gas defined using NIST Manager 102 fChamberMaterial = nistManager->FindOrBuildM 106 fChamberMaterial = nistManager->FindOrBuildMaterial("G4_Xe"); 103 107 104 // Print materials 108 // Print materials 105 G4cout << *(G4Material::GetMaterialTable()) 109 G4cout << *(G4Material::GetMaterialTable()) << G4endl; 106 } 110 } 107 111 108 //....oooOO0OOooo........oooOO0OOooo........oo 112 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 109 113 110 G4VPhysicalVolume* DetectorConstruction::Defin 114 G4VPhysicalVolume* DetectorConstruction::DefineVolumes() 111 { 115 { 112 G4Material* air = G4Material::GetMaterial("G << 116 G4Material* air = G4Material::GetMaterial("G4_AIR"); 113 117 114 // Sizes of the principal geometrical compon 118 // Sizes of the principal geometrical components (solids) 115 119 116 G4int NbOfChambers = 5; 120 G4int NbOfChambers = 5; 117 G4double chamberSpacing = 80 * cm; // from << 121 G4double chamberSpacing = 80*cm; // from chamber center to center! 118 122 119 G4double chamberWidth = 20.0 * cm; // width << 123 G4double chamberWidth = 20.0*cm; // width of the chambers 120 G4double targetLength = 5.0 * cm; // full l << 124 G4double targetLength = 5.0*cm; // full length of Target 121 125 122 G4double trackerLength = (NbOfChambers + 1) << 126 G4double trackerLength = (NbOfChambers+1)*chamberSpacing; 123 127 124 G4double worldLength = 1.2 * (2 * targetLeng << 128 G4double worldLength = 1.2 * (2*targetLength + trackerLength); 125 129 126 G4double targetRadius = 0.5 * targetLength; << 130 G4double targetRadius = 0.5*targetLength; // Radius of Target 127 targetLength = 0.5 * targetLength; // Half << 131 targetLength = 0.5*targetLength; // Half length of the Target 128 G4double trackerSize = 0.5 * trackerLength; << 132 G4double trackerSize = 0.5*trackerLength; // Half length of the Tracker 129 133 130 // Definitions of Solids, Logical Volumes, P 134 // Definitions of Solids, Logical Volumes, Physical Volumes 131 135 132 // World 136 // World 133 137 134 G4GeometryManager::GetInstance()->SetWorldMa 138 G4GeometryManager::GetInstance()->SetWorldMaximumExtent(worldLength); 135 139 136 G4cout << "Computed tolerance = " 140 G4cout << "Computed tolerance = " 137 << G4GeometryTolerance::GetInstance() << 141 << G4GeometryTolerance::GetInstance()->GetSurfaceTolerance()/mm >> 142 << " mm" << G4endl; 138 143 139 auto worldS = new G4Box("world", // its nam << 144 G4Box* worldS 140 worldLength / 2, wor << 145 = new G4Box("world", //its name 141 auto worldLV = new G4LogicalVolume(worldS, << 146 worldLength/2,worldLength/2,worldLength/2); //its size 142 air, // << 147 G4LogicalVolume* worldLV 143 "World"); << 148 = new G4LogicalVolume( >> 149 worldS, //its solid >> 150 air, //its material >> 151 "World"); //its name 144 152 145 // Must place the World Physical volume unr 153 // Must place the World Physical volume unrotated at (0,0,0). 146 // 154 // 147 auto worldPV = new G4PVPlacement(nullptr, / << 155 G4VPhysicalVolume* worldPV 148 G4ThreeVect << 156 = new G4PVPlacement( 149 worldLV, / << 157 0, // no rotation 150 "World", / << 158 G4ThreeVector(), // at (0,0,0) 151 nullptr, / << 159 worldLV, // its logical volume 152 false, // << 160 "World", // its name 153 0, // copy << 161 0, // its mother volume 154 fCheckOverl << 162 false, // no boolean operations >> 163 0, // copy number >> 164 fCheckOverlaps); // checking overlaps 155 165 156 // Target 166 // Target 157 167 158 G4ThreeVector positionTarget = G4ThreeVector << 168 G4ThreeVector positionTarget = G4ThreeVector(0,0,-(targetLength+trackerSize)); 159 169 160 auto targetS = new G4Tubs("target", 0., targ << 170 G4Tubs* targetS 161 fLogicTarget = new G4LogicalVolume(targetS, << 171 = new G4Tubs("target",0.,targetRadius,targetLength,0.*deg,360.*deg); 162 new G4PVPlacement(nullptr, // no rotation << 172 fLogicTarget 163 positionTarget, // at (x, << 173 = new G4LogicalVolume(targetS, fTargetMaterial,"Target",0,0,0); 164 fLogicTarget, // its logi << 174 new G4PVPlacement(0, // no rotation 165 "Target", // its name << 175 positionTarget, // at (x,y,z) 166 worldLV, // its mother vo << 176 fLogicTarget, // its logical volume 167 false, // no boolean oper << 177 "Target", // its name 168 0, // copy number << 178 worldLV, // its mother volume 169 fCheckOverlaps); // check << 179 false, // no boolean operations >> 180 0, // copy number >> 181 fCheckOverlaps); // checking overlaps 170 182 171 G4cout << "Target is " << 2 * targetLength / << 183 G4cout << "Target is " << 2*targetLength/cm << " cm of " 172 << G4endl; << 184 << fTargetMaterial->GetName() << G4endl; 173 185 174 // Tracker 186 // Tracker 175 187 176 G4ThreeVector positionTracker = G4ThreeVecto << 188 G4ThreeVector positionTracker = G4ThreeVector(0,0,0); 177 189 178 auto trackerS = new G4Tubs("tracker", 0, tra << 190 G4Tubs* trackerS 179 auto trackerLV = new G4LogicalVolume(tracker << 191 = new G4Tubs("tracker",0,trackerSize,trackerSize, 0.*deg, 360.*deg); 180 new G4PVPlacement(nullptr, // no rotation << 192 G4LogicalVolume* trackerLV 181 positionTracker, // at (x << 193 = new G4LogicalVolume(trackerS, air, "Tracker",0,0,0); 182 trackerLV, // its logical << 194 new G4PVPlacement(0, // no rotation 183 "Tracker", // its name << 195 positionTracker, // at (x,y,z) 184 worldLV, // its mother v << 196 trackerLV, // its logical volume 185 false, // no boolean oper << 197 "Tracker", // its name 186 0, // copy number << 198 worldLV, // its mother volume 187 fCheckOverlaps); // check << 199 false, // no boolean operations >> 200 0, // copy number >> 201 fCheckOverlaps); // checking overlaps 188 202 189 // Tracker segments 203 // Tracker segments 190 204 191 // An example of Parameterised volumes 205 // An example of Parameterised volumes 192 // Dummy values for G4Tubs -- modified by pa 206 // Dummy values for G4Tubs -- modified by parameterised volume 193 207 194 auto chamberS = new G4Tubs("tracker", 0, 100 << 208 G4Tubs* chamberS 195 fLogicChamber = << 209 = new G4Tubs("tracker",0, 100*cm, 100*cm, 0.*deg, 360.*deg); 196 new G4LogicalVolume(chamberS, fChamberMate << 210 fLogicChamber >> 211 = new G4LogicalVolume(chamberS,fChamberMaterial,"Chamber",0,0,0); 197 212 198 G4double firstPosition = -trackerSize + cham 213 G4double firstPosition = -trackerSize + chamberSpacing; 199 G4double firstLength = trackerLength / 10; << 214 G4double firstLength = trackerLength/10; 200 G4double lastLength = trackerLength; << 215 G4double lastLength = trackerLength; 201 216 202 G4VPVParameterisation* chamberParam = 217 G4VPVParameterisation* chamberParam = 203 new ChamberParameterisation(NbOfChambers, << 218 new ChamberParameterisation( 204 firstPosition, << 219 NbOfChambers, // NoChambers 205 chamberSpacing << 220 firstPosition, // Z of center of first 206 chamberWidth, << 221 chamberSpacing, // Z spacing of centers 207 firstLength, << 222 chamberWidth, // chamber width 208 lastLength); << 223 firstLength, // initial length >> 224 lastLength); // final length 209 225 210 // dummy value : kZAxis -- modified by param 226 // dummy value : kZAxis -- modified by parameterised volume 211 227 212 new G4PVParameterised("Chamber", // their n << 228 new G4PVParameterised("Chamber", // their name 213 fLogicChamber, // the << 229 fLogicChamber, // their logical volume 214 trackerLV, // Mother << 230 trackerLV, // Mother logical volume 215 kZAxis, // Are placed << 231 kZAxis, // Are placed along this axis 216 NbOfChambers, // Numb << 232 NbOfChambers, // Number of chambers 217 chamberParam, // The << 233 chamberParam, // The parametrisation 218 fCheckOverlaps); // c << 234 fCheckOverlaps); // checking overlaps 219 << 235 220 G4cout << "There are " << NbOfChambers << " << 236 G4cout << "There are " << NbOfChambers << " chambers in the tracker region. " 221 << "The chambers are " << chamberWidt << 237 << G4endl 222 << G4endl << "The distance between ch << 238 << "The chambers are " << chamberWidth/cm << " cm of " >> 239 << fChamberMaterial->GetName() << G4endl >> 240 << "The distance between chamber is " << chamberSpacing/cm << " cm" >> 241 << G4endl; 223 242 224 // Visualization attributes 243 // Visualization attributes 225 244 226 G4VisAttributes boxVisAtt(G4Colour::White()) << 245 G4VisAttributes* boxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0)); >> 246 worldLV ->SetVisAttributes(boxVisAtt); >> 247 fLogicTarget ->SetVisAttributes(boxVisAtt); >> 248 trackerLV ->SetVisAttributes(boxVisAtt); 227 249 228 worldLV->SetVisAttributes(boxVisAtt); << 250 G4VisAttributes* chamberVisAtt = new G4VisAttributes(G4Colour(1.0,1.0,0.0)); 229 fLogicTarget->SetVisAttributes(boxVisAtt); << 230 trackerLV->SetVisAttributes(boxVisAtt); << 231 << 232 G4VisAttributes chamberVisAtt(G4Colour::Yell << 233 fLogicChamber->SetVisAttributes(chamberVisAt 251 fLogicChamber->SetVisAttributes(chamberVisAtt); 234 252 235 // Example of User Limits 253 // Example of User Limits 236 // 254 // 237 // Below is an example of how to set trackin 255 // Below is an example of how to set tracking constraints in a given 238 // logical volume 256 // logical volume 239 // 257 // 240 // Sets a max step length in the tracker reg 258 // Sets a max step length in the tracker region, with G4StepLimiter 241 259 242 G4double maxStep = 0.5 * chamberWidth; << 260 G4double maxStep = 0.5*chamberWidth; 243 fStepLimit = new G4UserLimits(maxStep); 261 fStepLimit = new G4UserLimits(maxStep); 244 trackerLV->SetUserLimits(fStepLimit); 262 trackerLV->SetUserLimits(fStepLimit); 245 263 246 /// Set additional contraints on the track, 264 /// Set additional contraints on the track, with G4UserSpecialCuts 247 /// 265 /// 248 /// G4double maxLength = 2*trackerLength, ma 266 /// G4double maxLength = 2*trackerLength, maxTime = 0.1*ns, minEkin = 10*MeV; 249 /// trackerLV->SetUserLimits(new G4UserLimit 267 /// trackerLV->SetUserLimits(new G4UserLimits(maxStep, 250 /// 268 /// maxLength, 251 /// 269 /// maxTime, 252 /// 270 /// minEkin)); 253 271 254 // Always return the physical world 272 // Always return the physical world 255 273 256 return worldPV; 274 return worldPV; 257 } 275 } 258 276 259 //....oooOO0OOooo........oooOO0OOooo........oo 277 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 260 278 261 void DetectorConstruction::ConstructSDandField 279 void DetectorConstruction::ConstructSDandField() 262 { 280 { 263 // Sensitive detectors 281 // Sensitive detectors 264 282 265 G4String trackerChamberSDname = "B2/TrackerC 283 G4String trackerChamberSDname = "B2/TrackerChamberSD"; 266 auto trackerSD = new TrackerSD(trackerChambe << 284 TrackerSD* aTrackerSD = new TrackerSD(trackerChamberSDname, 267 G4SDManager::GetSDMpointer()->AddNewDetector << 285 "TrackerHitsCollection"); 268 SetSensitiveDetector(fLogicChamber, trackerS << 286 G4SDManager::GetSDMpointer()->AddNewDetector(aTrackerSD); >> 287 SetSensitiveDetector( fLogicChamber, aTrackerSD ); 269 288 270 // Create global magnetic field messenger. 289 // Create global magnetic field messenger. 271 // Uniform magnetic field is then created au 290 // Uniform magnetic field is then created automatically if 272 // the field value is not zero. 291 // the field value is not zero. 273 G4ThreeVector fieldValue = G4ThreeVector(); 292 G4ThreeVector fieldValue = G4ThreeVector(); 274 fMagFieldMessenger = new G4GlobalMagFieldMes 293 fMagFieldMessenger = new G4GlobalMagFieldMessenger(fieldValue); 275 fMagFieldMessenger->SetVerboseLevel(1); 294 fMagFieldMessenger->SetVerboseLevel(1); 276 295 277 // Register the field messenger for deleting 296 // Register the field messenger for deleting 278 G4AutoDelete::Register(fMagFieldMessenger); 297 G4AutoDelete::Register(fMagFieldMessenger); 279 } 298 } 280 299 281 //....oooOO0OOooo........oooOO0OOooo........oo 300 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 282 301 283 void DetectorConstruction::SetTargetMaterial(G 302 void DetectorConstruction::SetTargetMaterial(G4String materialName) 284 { 303 { 285 G4NistManager* nistManager = G4NistManager:: 304 G4NistManager* nistManager = G4NistManager::Instance(); 286 305 287 G4Material* pttoMaterial = nistManager->Find << 306 G4Material* pttoMaterial = >> 307 nistManager->FindOrBuildMaterial(materialName); 288 308 289 if (fTargetMaterial != pttoMaterial) { 309 if (fTargetMaterial != pttoMaterial) { 290 if (pttoMaterial) { << 310 if ( pttoMaterial ) { 291 fTargetMaterial = pttoMaterial; << 311 fTargetMaterial = pttoMaterial; 292 if (fLogicTarget) fLogicTarget->SetMater << 312 if (fLogicTarget) fLogicTarget->SetMaterial(fTargetMaterial); 293 G4cout << G4endl << "----> The target is << 313 G4cout 294 } << 314 << G4endl 295 else { << 315 << "----> The target is made of " << materialName << G4endl; 296 G4cout << G4endl << "--> WARNING from S << 316 } else { 297 << G4endl; << 317 G4cout 298 } << 318 << G4endl >> 319 << "--> WARNING from SetTargetMaterial : " >> 320 << materialName << " not found" << G4endl; >> 321 } 299 } 322 } 300 } 323 } 301 324 302 //....oooOO0OOooo........oooOO0OOooo........oo 325 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 303 326 304 void DetectorConstruction::SetChamberMaterial( 327 void DetectorConstruction::SetChamberMaterial(G4String materialName) 305 { 328 { 306 G4NistManager* nistManager = G4NistManager:: 329 G4NistManager* nistManager = G4NistManager::Instance(); 307 330 308 G4Material* pttoMaterial = nistManager->Find << 331 G4Material* pttoMaterial = >> 332 nistManager->FindOrBuildMaterial(materialName); 309 333 310 if (fChamberMaterial != pttoMaterial) { 334 if (fChamberMaterial != pttoMaterial) { 311 if (pttoMaterial) { << 335 if ( pttoMaterial ) { 312 fChamberMaterial = pttoMaterial; << 336 fChamberMaterial = pttoMaterial; 313 if (fLogicChamber) fLogicChamber->SetMat << 337 if (fLogicChamber) fLogicChamber->SetMaterial(fChamberMaterial); 314 G4cout << G4endl << "----> The chambers << 338 G4cout 315 } << 339 << G4endl 316 else { << 340 << "----> The chambers are made of " << materialName << G4endl; 317 G4cout << G4endl << "--> WARNING from S << 341 } else { 318 << G4endl; << 342 G4cout 319 } << 343 << G4endl >> 344 << "--> WARNING from SetChamberMaterial : " >> 345 << materialName << " not found" << G4endl; >> 346 } 320 } 347 } 321 } 348 } 322 349 323 //....oooOO0OOooo........oooOO0OOooo........oo 350 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 324 351 325 void DetectorConstruction::SetMaxStep(G4double 352 void DetectorConstruction::SetMaxStep(G4double maxStep) 326 { 353 { 327 if ((fStepLimit) && (maxStep > 0.)) fStepLim << 354 if ((fStepLimit)&&(maxStep>0.)) fStepLimit->SetMaxAllowedStep(maxStep); 328 } 355 } 329 356 330 //....oooOO0OOooo........oooOO0OOooo........oo 357 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 331 358 332 } // namespace B2b << 359 } 333 360