Loading...
Searching...
No Matches
DetectorConstruction.cc
Go to the documentation of this file.
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 B2/B2a/src/DetectorConstruction.cc
28/// \brief Implementation of the B2a::DetectorConstruction class
29
30#include "DetectorConstruction.hh"
31#include "DetectorMessenger.hh"
32#include "TrackerSD.hh"
33
34#include "G4Material.hh"
35#include "G4NistManager.hh"
36#include "G4SDManager.hh"
37
38#include "G4Box.hh"
39#include "G4Tubs.hh"
40#include "G4LogicalVolume.hh"
41#include "G4PVPlacement.hh"
42#include "G4GlobalMagFieldMessenger.hh"
43#include "G4AutoDelete.hh"
44
45#include "G4GeometryTolerance.hh"
46#include "G4GeometryManager.hh"
47
48#include "G4UserLimits.hh"
49
50#include "G4VisAttributes.hh"
51#include "G4Colour.hh"
52
53#include "G4SystemOfUnits.hh"
54
55using namespace B2;
56
57namespace B2a
58{
59
60//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
61
62G4ThreadLocal
64
72
73//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
74
81
82//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
83
85{
86 // Define materials
88
89 // Define volumes
90 return DefineVolumes();
91}
92
93//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
94
96{
97 // Material definition
98
99 G4NistManager* nistManager = G4NistManager::Instance();
100
101 // Air defined using NIST Manager
102 nistManager->FindOrBuildMaterial("G4_AIR");
103
104 // Lead defined using NIST Manager
105 fTargetMaterial = nistManager->FindOrBuildMaterial("G4_Pb");
106
107 // Xenon gas defined using NIST Manager
108 fChamberMaterial = nistManager->FindOrBuildMaterial("G4_Xe");
109
110 // Print materials
111 G4cout << *(G4Material::GetMaterialTable()) << G4endl;
112}
113
114//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
115
117{
118 G4Material* air = G4Material::GetMaterial("G4_AIR");
119
120 // Sizes of the principal geometrical components (solids)
121
122 G4double chamberSpacing = 80*cm; // from chamber center to center!
123
124 G4double chamberWidth = 20.0*cm; // width of the chambers
125 G4double targetLength = 5.0*cm; // full length of Target
126
127 G4double trackerLength = (fNbOfChambers+1)*chamberSpacing;
128
129 G4double worldLength = 1.2 * (2*targetLength + trackerLength);
130
131 G4double targetRadius = 0.5*targetLength; // Radius of Target
132 targetLength = 0.5*targetLength; // Half length of the Target
133 G4double trackerSize = 0.5*trackerLength; // Half length of the Tracker
134
135 // Definitions of Solids, Logical Volumes, Physical Volumes
136
137 // World
138
139 G4GeometryManager::GetInstance()->SetWorldMaximumExtent(worldLength);
140
141 G4cout << "Computed tolerance = "
142 << G4GeometryTolerance::GetInstance()->GetSurfaceTolerance()/mm
143 << " mm" << G4endl;
144
145 auto worldS = new G4Box("world", // its name
146 worldLength / 2, worldLength / 2, worldLength / 2); // its size
147 auto worldLV = new G4LogicalVolume(worldS, // its solid
148 air, // its material
149 "World"); // its name
150
151 // Must place the World Physical volume unrotated at (0,0,0).
152 //
153 auto worldPV = new G4PVPlacement(nullptr, // no rotation
154 G4ThreeVector(), // at (0,0,0)
155 worldLV, // its logical volume
156 "World", // its name
157 nullptr, // its mother volume
158 false, // no boolean operations
159 0, // copy number
160 fCheckOverlaps); // checking overlaps
161
162 // Target
163
164 G4ThreeVector positionTarget = G4ThreeVector(0,0,-(targetLength+trackerSize));
165
166 auto targetS = new G4Tubs("target", 0., targetRadius, targetLength, 0. * deg, 360. * deg);
167 fLogicTarget = new G4LogicalVolume(targetS, fTargetMaterial, "Target", nullptr, nullptr, nullptr);
168 new G4PVPlacement(nullptr, // no rotation
169 positionTarget, // at (x,y,z)
170 fLogicTarget, // its logical volume
171 "Target", // its name
172 worldLV, // its mother volume
173 false, // no boolean operations
174 0, // copy number
175 fCheckOverlaps); // checking overlaps
176
177 G4cout << "Target is " << 2*targetLength/cm << " cm of "
178 << fTargetMaterial->GetName() << G4endl;
179
180 // Tracker
181
182 G4ThreeVector positionTracker = G4ThreeVector(0,0,0);
183
184 auto trackerS = new G4Tubs("tracker", 0, trackerSize, trackerSize, 0. * deg, 360. * deg);
185 auto trackerLV = new G4LogicalVolume(trackerS, air, "Tracker", nullptr, nullptr, nullptr);
186 new G4PVPlacement(nullptr, // no rotation
187 positionTracker, // at (x,y,z)
188 trackerLV, // its logical volume
189 "Tracker", // its name
190 worldLV, // its mother volume
191 false, // no boolean operations
192 0, // copy number
193 fCheckOverlaps); // checking overlaps
194
195 // Visualization attributes
196
197 G4VisAttributes boxVisAtt(G4Colour::White());
198 G4VisAttributes chamberVisAtt(G4Colour::Yellow());
199
200 worldLV ->SetVisAttributes(boxVisAtt);
201 fLogicTarget ->SetVisAttributes(boxVisAtt);
202 trackerLV ->SetVisAttributes(boxVisAtt);
203
204 // Tracker segments
205
206 G4cout << "There are " << fNbOfChambers << " chambers in the tracker region. "
207 << G4endl
208 << "The chambers are " << chamberWidth/cm << " cm of "
209 << fChamberMaterial->GetName() << G4endl
210 << "The distance between chamber is " << chamberSpacing/cm << " cm"
211 << G4endl;
212
213 G4double firstPosition = -trackerSize + chamberSpacing;
214 G4double firstLength = trackerLength/10;
215 G4double lastLength = trackerLength;
216
217 G4double halfWidth = 0.5*chamberWidth;
218 G4double rmaxFirst = 0.5 * firstLength;
219
220 G4double rmaxIncr = 0.0;
221 if( fNbOfChambers > 0 ){
222 rmaxIncr = 0.5 * (lastLength-firstLength)/(fNbOfChambers-1);
223 if (chamberSpacing < chamberWidth) {
224 G4Exception("DetectorConstruction::DefineVolumes()",
225 "InvalidSetup", FatalException,
226 "Width>Spacing");
227 }
228 }
229
230 for (G4int copyNo=0; copyNo<fNbOfChambers; copyNo++) {
231
232 G4double Zposition = firstPosition + copyNo * chamberSpacing;
233 G4double rmax = rmaxFirst + copyNo * rmaxIncr;
234
235 auto chamberS = new G4Tubs("Chamber_solid", 0, rmax, halfWidth, 0. * deg, 360. * deg);
236
237 fLogicChamber[copyNo] =
238 new G4LogicalVolume(chamberS, fChamberMaterial, "Chamber_LV", nullptr, nullptr, nullptr);
239
240 fLogicChamber[copyNo]->SetVisAttributes(chamberVisAtt);
241
242 new G4PVPlacement(nullptr, // no rotation
243 G4ThreeVector(0, 0, Zposition), // at (x,y,z)
244 fLogicChamber[copyNo], // its logical volume
245 "Chamber_PV", // its name
246 trackerLV, // its mother volume
247 false, // no boolean operations
248 copyNo, // copy number
249 fCheckOverlaps); // checking overlaps
250 }
251
252 // Example of User Limits
253 //
254 // Below is an example of how to set tracking constraints in a given
255 // logical volume
256 //
257 // Sets a max step length in the tracker region, with G4StepLimiter
258
259 G4double maxStep = 0.5*chamberWidth;
260 fStepLimit = new G4UserLimits(maxStep);
261 trackerLV->SetUserLimits(fStepLimit);
262
263 /// Set additional contraints on the track, with G4UserSpecialCuts
264 ///
265 /// G4double maxLength = 2*trackerLength, maxTime = 0.1*ns, minEkin = 10*MeV;
266 /// trackerLV->SetUserLimits(new G4UserLimits(maxStep,
267 /// maxLength,
268 /// maxTime,
269 /// minEkin));
270
271 // Always return the physical world
272
273 return worldPV;
274}
275
276//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
277
279{
280 // Sensitive detectors
281
282 G4String trackerChamberSDname = "/TrackerChamberSD";
283 auto aTrackerSD = new TrackerSD(trackerChamberSDname, "TrackerHitsCollection");
284 G4SDManager::GetSDMpointer()->AddNewDetector(aTrackerSD);
285 // Setting aTrackerSD to all logical volumes with the same name
286 // of "Chamber_LV".
287 SetSensitiveDetector("Chamber_LV", aTrackerSD, true);
288
289 // Create global magnetic field messenger.
290 // Uniform magnetic field is then created automatically if
291 // the field value is not zero.
292 G4ThreeVector fieldValue = G4ThreeVector();
294 fMagFieldMessenger->SetVerboseLevel(1);
295
296 // Register the field messenger for deleting
297 G4AutoDelete::Register(fMagFieldMessenger);
298}
299
300//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
301
303{
304 G4NistManager* nistManager = G4NistManager::Instance();
305
306 G4Material* pttoMaterial =
307 nistManager->FindOrBuildMaterial(materialName);
308
309 if (fTargetMaterial != pttoMaterial) {
310 if ( pttoMaterial ) {
311 fTargetMaterial = pttoMaterial;
312 if (fLogicTarget) fLogicTarget->SetMaterial(fTargetMaterial);
313 G4cout
314 << G4endl
315 << "----> The target is made of " << materialName << G4endl;
316 } else {
317 G4cout
318 << G4endl
319 << "--> WARNING from SetTargetMaterial : "
320 << materialName << " not found" << G4endl;
321 }
322 }
323}
324
325//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
326
328{
329 G4NistManager* nistManager = G4NistManager::Instance();
330
331 G4Material* pttoMaterial =
332 nistManager->FindOrBuildMaterial(materialName);
333
334 if (fChamberMaterial != pttoMaterial) {
335 if ( pttoMaterial ) {
336 fChamberMaterial = pttoMaterial;
337 for (G4int copyNo=0; copyNo<fNbOfChambers; copyNo++) {
338 if (fLogicChamber[copyNo]) fLogicChamber[copyNo]->
339 SetMaterial(fChamberMaterial);
340 }
341 G4cout
342 << G4endl
343 << "----> The chambers are made of " << materialName << G4endl;
344 } else {
345 G4cout
346 << G4endl
347 << "--> WARNING from SetChamberMaterial : "
348 << materialName << " not found" << G4endl;
349 }
350 }
351}
352
353//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
354
356{
357 if ((fStepLimit)&&(maxStep>0.)) fStepLimit->SetMaxAllowedStep(maxStep);
358}
359
360//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
361
363{
364 fCheckOverlaps = checkOverlaps;
365}
366
367//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
368
369}
Definition of the B2::TrackerSD class.
Tracker sensitive detector class.
G4VPhysicalVolume * Construct() override
static G4ThreadLocal G4GlobalMagFieldMessenger * fMagFieldMessenger
G4VPhysicalVolume * DefineVolumes()
Messenger class that defines commands for DetectorConstruction.

Applications | User Support | Publications | Collaboration