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