ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
B2aDetectorConstruction.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file B2aDetectorConstruction.cc
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 //
29 
31 #include "B2aDetectorMessenger.hh"
32 #include "B2TrackerSD.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"
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 
55 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
56 
59 
62  fNbOfChambers(0),
63  fLogicTarget(NULL), fLogicChamber(NULL),
64  fTargetMaterial(NULL), fChamberMaterial(NULL),
65  fStepLimit(NULL),
66  fCheckOverlaps(true)
67 {
68  fMessenger = new B2aDetectorMessenger(this);
69 
70  fNbOfChambers = 5;
72 }
73 
74 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
75 
77 {
78  delete [] fLogicChamber;
79  delete fStepLimit;
80  delete fMessenger;
81 }
82 
83 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
84 
86 {
87  // Define materials
89 
90  // Define volumes
91  return DefineVolumes();
92 }
93 
94 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
95 
97 {
98  // Material definition
99 
100  G4NistManager* nistManager = G4NistManager::Instance();
101 
102  // Air defined using NIST Manager
103  nistManager->FindOrBuildMaterial("G4_AIR");
104 
105  // Lead defined using NIST Manager
106  fTargetMaterial = nistManager->FindOrBuildMaterial("G4_Pb");
107 
108  // Xenon gas defined using NIST Manager
109  fChamberMaterial = nistManager->FindOrBuildMaterial("G4_Xe");
110 
111  // Print materials
113 }
114 
115 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
116 
118 {
119  G4Material* air = G4Material::GetMaterial("G4_AIR");
120 
121  // Sizes of the principal geometrical components (solids)
122 
123  G4double chamberSpacing = 80*cm; // from chamber center to center!
124 
125  G4double chamberWidth = 20.0*cm; // width of the chambers
126  G4double targetLength = 5.0*cm; // full length of Target
127 
128  G4double trackerLength = (fNbOfChambers+1)*chamberSpacing;
129 
130  G4double worldLength = 1.2 * (2*targetLength + trackerLength);
131 
132  G4double targetRadius = 0.5*targetLength; // Radius of Target
133  targetLength = 0.5*targetLength; // Half length of the Target
134  G4double trackerSize = 0.5*trackerLength; // Half length of the Tracker
135 
136  // Definitions of Solids, Logical Volumes, Physical Volumes
137 
138  // World
139 
141 
142  G4cout << "Computed tolerance = "
144  << " mm" << G4endl;
145 
146  G4Box* worldS
147  = new G4Box("world", //its name
148  worldLength/2,worldLength/2,worldLength/2); //its size
149  G4LogicalVolume* worldLV
150  = new G4LogicalVolume(
151  worldS, //its solid
152  air, //its material
153  "World"); //its name
154 
155  // Must place the World Physical volume unrotated at (0,0,0).
156  //
157  G4VPhysicalVolume* worldPV
158  = new G4PVPlacement(
159  0, // no rotation
160  G4ThreeVector(), // at (0,0,0)
161  worldLV, // its logical volume
162  "World", // its name
163  0, // its mother volume
164  false, // no boolean operations
165  0, // copy number
166  fCheckOverlaps); // checking overlaps
167 
168  // Target
169 
170  G4ThreeVector positionTarget = G4ThreeVector(0,0,-(targetLength+trackerSize));
171 
172  G4Tubs* targetS
173  = new G4Tubs("target",0.,targetRadius,targetLength,0.*deg,360.*deg);
175  = new G4LogicalVolume(targetS, fTargetMaterial,"Target",0,0,0);
176  new G4PVPlacement(0, // no rotation
177  positionTarget, // at (x,y,z)
178  fLogicTarget, // its logical volume
179  "Target", // its name
180  worldLV, // its mother volume
181  false, // no boolean operations
182  0, // copy number
183  fCheckOverlaps); // checking overlaps
184 
185  G4cout << "Target is " << 2*targetLength/cm << " cm of "
186  << fTargetMaterial->GetName() << G4endl;
187 
188  // Tracker
189 
190  G4ThreeVector positionTracker = G4ThreeVector(0,0,0);
191 
192  G4Tubs* trackerS
193  = new G4Tubs("tracker",0,trackerSize,trackerSize, 0.*deg, 360.*deg);
194  G4LogicalVolume* trackerLV
195  = new G4LogicalVolume(trackerS, air, "Tracker",0,0,0);
196  new G4PVPlacement(0, // no rotation
197  positionTracker, // at (x,y,z)
198  trackerLV, // its logical volume
199  "Tracker", // its name
200  worldLV, // its mother volume
201  false, // no boolean operations
202  0, // copy number
203  fCheckOverlaps); // checking overlaps
204 
205  // Visualization attributes
206 
207  G4VisAttributes* boxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
208  G4VisAttributes* chamberVisAtt = new G4VisAttributes(G4Colour(1.0,1.0,0.0));
209 
210  worldLV ->SetVisAttributes(boxVisAtt);
211  fLogicTarget ->SetVisAttributes(boxVisAtt);
212  trackerLV ->SetVisAttributes(boxVisAtt);
213 
214  // Tracker segments
215 
216  G4cout << "There are " << fNbOfChambers << " chambers in the tracker region. "
217  << G4endl
218  << "The chambers are " << chamberWidth/cm << " cm of "
219  << fChamberMaterial->GetName() << G4endl
220  << "The distance between chamber is " << chamberSpacing/cm << " cm"
221  << G4endl;
222 
223  G4double firstPosition = -trackerSize + chamberSpacing;
224  G4double firstLength = trackerLength/10;
225  G4double lastLength = trackerLength;
226 
227  G4double halfWidth = 0.5*chamberWidth;
228  G4double rmaxFirst = 0.5 * firstLength;
229 
230  G4double rmaxIncr = 0.0;
231  if( fNbOfChambers > 0 ){
232  rmaxIncr = 0.5 * (lastLength-firstLength)/(fNbOfChambers-1);
233  if (chamberSpacing < chamberWidth) {
234  G4Exception("B2aDetectorConstruction::DefineVolumes()",
235  "InvalidSetup", FatalException,
236  "Width>Spacing");
237  }
238  }
239 
240  for (G4int copyNo=0; copyNo<fNbOfChambers; copyNo++) {
241 
242  G4double Zposition = firstPosition + copyNo * chamberSpacing;
243  G4double rmax = rmaxFirst + copyNo * rmaxIncr;
244 
245  G4Tubs* chamberS
246  = new G4Tubs("Chamber_solid", 0, rmax, halfWidth, 0.*deg, 360.*deg);
247 
248  fLogicChamber[copyNo] =
249  new G4LogicalVolume(chamberS,fChamberMaterial,"Chamber_LV",0,0,0);
250 
251  fLogicChamber[copyNo]->SetVisAttributes(chamberVisAtt);
252 
253  new G4PVPlacement(0, // no rotation
254  G4ThreeVector(0,0,Zposition), // at (x,y,z)
255  fLogicChamber[copyNo], // its logical volume
256  "Chamber_PV", // its name
257  trackerLV, // its mother volume
258  false, // no boolean operations
259  copyNo, // copy number
260  fCheckOverlaps); // checking overlaps
261 
262  }
263 
264  // Example of User Limits
265  //
266  // Below is an example of how to set tracking constraints in a given
267  // logical volume
268  //
269  // Sets a max step length in the tracker region, with G4StepLimiter
270 
271  G4double maxStep = 0.5*chamberWidth;
272  fStepLimit = new G4UserLimits(maxStep);
273  trackerLV->SetUserLimits(fStepLimit);
274 
282 
283  // Always return the physical world
284 
285  return worldPV;
286 }
287 
288 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
289 
291 {
292  // Sensitive detectors
293 
294  G4String trackerChamberSDname = "B2/TrackerChamberSD";
295  B2TrackerSD* aTrackerSD = new B2TrackerSD(trackerChamberSDname,
296  "TrackerHitsCollection");
298  // Setting aTrackerSD to all logical volumes with the same name
299  // of "Chamber_LV".
300  SetSensitiveDetector("Chamber_LV", aTrackerSD, true);
301 
302  // Create global magnetic field messenger.
303  // Uniform magnetic field is then created automatically if
304  // the field value is not zero.
305  G4ThreeVector fieldValue = G4ThreeVector();
308 
309  // Register the field messenger for deleting
311 }
312 
313 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
314 
316 {
317  G4NistManager* nistManager = G4NistManager::Instance();
318 
319  G4Material* pttoMaterial =
320  nistManager->FindOrBuildMaterial(materialName);
321 
322  if (fTargetMaterial != pttoMaterial) {
323  if ( pttoMaterial ) {
324  fTargetMaterial = pttoMaterial;
326  G4cout
327  << G4endl
328  << "----> The target is made of " << materialName << G4endl;
329  } else {
330  G4cout
331  << G4endl
332  << "--> WARNING from SetTargetMaterial : "
333  << materialName << " not found" << G4endl;
334  }
335  }
336 }
337 
338 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
339 
341 {
342  G4NistManager* nistManager = G4NistManager::Instance();
343 
344  G4Material* pttoMaterial =
345  nistManager->FindOrBuildMaterial(materialName);
346 
347  if (fChamberMaterial != pttoMaterial) {
348  if ( pttoMaterial ) {
349  fChamberMaterial = pttoMaterial;
350  for (G4int copyNo=0; copyNo<fNbOfChambers; copyNo++) {
351  if (fLogicChamber[copyNo]) fLogicChamber[copyNo]->
353  }
354  G4cout
355  << G4endl
356  << "----> The chambers are made of " << materialName << G4endl;
357  } else {
358  G4cout
359  << G4endl
360  << "--> WARNING from SetChamberMaterial : "
361  << materialName << " not found" << G4endl;
362  }
363  }
364 }
365 
366 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
367 
369 {
370  if ((fStepLimit)&&(maxStep>0.)) fStepLimit->SetMaxAllowedStep(maxStep);
371 }
372 
373 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
374 
376 {
377  fCheckOverlaps = checkOverlaps;
378 }