Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/extended/parameterisations/Par03/src/Par03DetectorConstruction.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 #include "Par03DetectorConstruction.hh"
 27 
 28 #include "Par03DetectorMessenger.hh"
 29 #include "Par03EMShowerModel.hh"
 30 #include "Par03SensitiveDetector.hh"
 31 
 32 #include "G4Box.hh"
 33 #include "G4LogicalVolume.hh"
 34 #include "G4Material.hh"
 35 #include "G4NistManager.hh"
 36 #include "G4PVPlacement.hh"
 37 #include "G4PVReplica.hh"
 38 #include "G4Region.hh"
 39 #include "G4RegionStore.hh"
 40 #include "G4RunManager.hh"
 41 #include "G4SDManager.hh"
 42 #include "G4Tubs.hh"
 43 #include "G4UnitsTable.hh"
 44 #include "G4VisAttributes.hh"
 45 
 46 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 47 
 48 Par03DetectorConstruction::Par03DetectorConstruction() : G4VUserDetectorConstruction()
 49 {
 50   fDetectorMessenger = new Par03DetectorMessenger(this);
 51 
 52   G4NistManager* nistManager = G4NistManager::Instance();
 53   fDetectorMaterial = nistManager->FindOrBuildMaterial("G4_Fe");
 54 }
 55 
 56 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 57 
 58 Par03DetectorConstruction::~Par03DetectorConstruction() = default;
 59 
 60 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 61 
 62 G4VPhysicalVolume* Par03DetectorConstruction::Construct()
 63 {
 64   //--------- Material definition ---------
 65   G4NistManager* nistManager = G4NistManager::Instance();
 66   G4Material* air = nistManager->FindOrBuildMaterial("G4_AIR");
 67 
 68   //--------- Derived dimensions ---------
 69   G4double full2Pi = 2. * CLHEP::pi * rad;
 70   G4double layerThickness = fDetectorLength / fNbOfLayers;
 71   G4double cellPhi = full2Pi / fNbOfPhiCells;
 72   G4double cellDR = fDetectorRadius / fNbOfRhoCells;
 73 
 74   //--------- World ---------
 75   auto fSolidWorld = new G4Box("World",  // name
 76                                fWorldSize / 2.,  // half-width in X
 77                                fWorldSize / 2.,  // half-width in Y
 78                                fWorldSize / 2.);  // half-width in Z
 79   auto fLogicWorld = new G4LogicalVolume(fSolidWorld,  // solid
 80                                          air,  // material
 81                                          "World");  // name
 82   auto fPhysicWorld = new G4PVPlacement(0,  // no rotation
 83                                         G4ThreeVector(),  // at (0,0,0)
 84                                         fLogicWorld,  // logical volume
 85                                         "World",  // name
 86                                         0,  // mother volume
 87                                         false,  // not used
 88                                         999,  // copy number
 89                                         true);  // copy number
 90 
 91   //--------- Detector envelope ---------
 92   auto fSolidDetector = new G4Tubs("Detector",  // name
 93                                    0,  // inner radius
 94                                    fDetectorRadius,  // outer radius
 95                                    fDetectorLength / 2.,  // half-width in Z
 96                                    0,  // start angle
 97                                    full2Pi);  // delta angle
 98   auto fLogicDetector = new G4LogicalVolume(fSolidDetector,  // solid
 99                                             fDetectorMaterial,  // material
100                                             "Detector");  // name
101   new G4PVPlacement(0,  // no rotation
102                     G4ThreeVector(0, 0,
103                                   fDetectorLength / 2),  // detector face starts at (0,0,0)
104                     fLogicDetector,  // logical volume
105                     "Detector",  // name
106                     fLogicWorld,  // mother volume
107                     false,  // not used
108                     99,  // copy number
109                     true);  // check overlaps
110 
111   // Region for fast simulation
112   auto detectorRegion = new G4Region("DetectorRegion");
113   detectorRegion->AddRootLogicalVolume(fLogicDetector);
114 
115   //--------- Readout geometry ---------
116   // Layers (along z)
117   auto fSolidLayer = new G4Tubs("Layer",  // name
118                                 0,  // inner radius
119                                 fDetectorRadius,  // outer radius
120                                 layerThickness / 2.,  // half-width in Z
121                                 0,  // start angle
122                                 full2Pi);  // delta angle
123   auto fLogicLayer = new G4LogicalVolume(fSolidLayer,  // solid
124                                          air,  // material
125                                          "Layer");  // name
126   if (fNbOfLayers > 1)
127     new G4PVReplica("Layer",  // name
128                     fLogicLayer,  // logical volume
129                     fLogicDetector,  // mother volume
130                     kZAxis,  // axis of replication
131                     fNbOfLayers,  // number of replicas
132                     layerThickness);  // width of single replica
133   else
134     new G4PVPlacement(0,  // no rotation
135                       G4ThreeVector(),  // place at centre of mother volume
136                       fLogicLayer,  // logical volume
137                       "Layer",  // name
138                       fLogicDetector,  // mother volume
139                       false,  // not used
140                       0,  // copy number
141                       true);  // check overlaps
142 
143   // Layer segment (division in phi)
144   auto fSolidRow = new G4Tubs("Row",  // name
145                               0,  // inner radius
146                               fDetectorRadius,  // outer radius
147                               layerThickness / 2.,  // half-width in Z
148                               0,  // start angle
149                               cellPhi);  // delta angle
150 
151   auto fLogicRow = new G4LogicalVolume(fSolidRow,  // solid
152                                        air,  // material
153                                        "Segment");  // name
154   if (fNbOfPhiCells > 1)
155     new G4PVReplica("Segment",  // name
156                     fLogicRow,  // logical volume
157                     fLogicLayer,  // mother volume
158                     kPhi,  // axis of replication
159                     fNbOfPhiCells,  // number of replicas
160                     cellPhi);  // width of single replica
161   else
162     new G4PVPlacement(0,  // no rotation
163                       G4ThreeVector(),  // place at centre of mother volume
164                       fLogicRow,  // logical volume
165                       "Row",  // name
166                       fLogicLayer,  // mother volume
167                       false,  // not used
168                       0,  // copy number
169                       true);  // check overlaps
170 
171   // Final cells (segment slices in radius)
172   // No volume can be placed inside a radial replication
173   auto fSolidCell = new G4Tubs("Cell",  // name
174                                0,  // inner radius
175                                cellDR,  // outer radius
176                                layerThickness / 2.,  // half-width in Z
177                                0,  // start angle
178                                cellPhi);  // delta angle
179 
180   fLogicCell = new G4LogicalVolume(fSolidCell,  // solid
181                                    fDetectorMaterial,  // material
182                                    "Cell");  // name
183   if (fNbOfRhoCells > 1)
184     new G4PVReplica("Cell",  // name
185                     fLogicCell,  // logical volume
186                     fLogicRow,  // mother volume
187                     kRho,  // axis of replication
188                     fNbOfRhoCells,  // number of replicas
189                     cellDR);  // width of single replica
190   else
191     new G4PVPlacement(0,  // no rotation
192                       G4ThreeVector(),  // place at centre of mother volume
193                       fLogicCell,  // logical volume
194                       "Cell",  // name
195                       fLogicRow,  // mother volume
196                       false,  // not used
197                       0,  // copy number
198                       true);  // check overlaps
199 
200   //--------- Visualisation settings ---------
201   fLogicWorld->SetVisAttributes(G4VisAttributes::GetInvisible());
202   fLogicLayer->SetVisAttributes(G4VisAttributes::GetInvisible());
203   fLogicRow->SetVisAttributes(G4VisAttributes::GetInvisible());
204   G4VisAttributes attribs;
205   attribs.SetColour(G4Colour(0, 0, 1, 0.3));
206   attribs.SetForceSolid(true);
207   fLogicCell->SetVisAttributes(attribs);
208 
209   Print();
210   return fPhysicWorld;
211 }
212 
213 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
214 
215 void Par03DetectorConstruction::ConstructSDandField()
216 {
217   Par03SensitiveDetector* caloSD =
218     new Par03SensitiveDetector("sensitiveDetector", fNbOfLayers, fNbOfPhiCells, fNbOfRhoCells);
219   G4SDManager::GetSDMpointer()->AddNewDetector(caloSD);
220   SetSensitiveDetector(fLogicCell, caloSD);
221 
222   auto detectorRegion = G4RegionStore::GetInstance()->GetRegion("DetectorRegion");
223   new Par03EMShowerModel("model", detectorRegion);
224 }
225 
226 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
227 
228 void Par03DetectorConstruction::Print() const
229 {
230   G4cout << "\n------------------------------------------------------"
231          << "\n--- Detector material:\t" << fDetectorMaterial->GetName()
232          << "\n--- Detector length:\t" << G4BestUnit(fDetectorLength, "Length")
233          << "\n--- Detector radius:\t" << G4BestUnit(fDetectorRadius, "Length")
234          << "\n--- Number of layers:\t" << fNbOfLayers << "\n--- Number of R-cells:\t"
235          << fNbOfRhoCells << "\n--- Number of phi-cells:\t" << fNbOfPhiCells << G4endl;
236   G4cout << "-----------------------------------------------------" << G4endl;
237 }
238 
239 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
240 
241 void Par03DetectorConstruction::SetMaterial(const G4String& aName)
242 {
243   // search material by its name
244   G4Material* material = G4NistManager::Instance()->FindOrBuildMaterial(aName);
245   if (material)
246     fDetectorMaterial = material;
247   else
248     G4Exception("Par03DetectorConstruction::SetMaterial()", "InvalidSetup", FatalException,
249                 ("Unknown material name: " + aName).c_str());
250   G4RunManager::GetRunManager()->PhysicsHasBeenModified();
251 }
252 
253 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
254 
255 void Par03DetectorConstruction::SetRadius(G4double aRadius)
256 {
257   // check if fits within world volume
258   if (aRadius >= fWorldSize / 2.)
259     G4Exception("Par03DetectorConstruction::SetRadius()", "InvalidSetup", FatalException,
260                 ("Detector radius cannot be larger than the world size ("
261                  + G4String(G4BestUnit(fWorldSize / 2., "Length")) + ")")
262                   .c_str());
263   fDetectorRadius = aRadius;
264 }
265 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
266 
267 void Par03DetectorConstruction::SetLength(G4double aLength)
268 {
269   // check if fits within world volume
270   if (aLength >= fWorldSize / 2.)
271     G4Exception("Par03DetectorConstruction::SetLength()", "InvalidSetup", FatalException,
272                 ("Detector length cannot be larger than the world size ("
273                  + G4String(G4BestUnit(fWorldSize / 2., "Length")) + ")")
274                   .c_str());
275   fDetectorLength = aLength;
276 }