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 /// \file Par01/src/Par01DetectorConstruction.cc 27 /// \brief Implementation of the Par01DetectorConstruction class 28 // 29 // 30 // 31 #include "Par01DetectorConstruction.hh" 32 33 #include "Par01CalorimeterSD.hh" 34 #include "Par01EMShowerModel.hh" 35 #include "Par01PiModel.hh" 36 37 #include "G4Box.hh" 38 #include "G4Colour.hh" 39 #include "G4Element.hh" 40 #include "G4ElementTable.hh" 41 #include "G4LogicalVolume.hh" 42 #include "G4Material.hh" 43 #include "G4MaterialTable.hh" 44 #include "G4NistManager.hh" 45 #include "G4PVPlacement.hh" 46 #include "G4ProductionCuts.hh" 47 #include "G4RegionStore.hh" 48 #include "G4SDManager.hh" 49 #include "G4SystemOfUnits.hh" 50 #include "G4ThreeVector.hh" 51 #include "G4Tubs.hh" 52 #include "G4VisAttributes.hh" 53 54 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 55 56 Par01DetectorConstruction::Par01DetectorConstruction() 57 { 58 ; 59 } 60 61 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 62 63 Par01DetectorConstruction::~Par01DetectorConstruction() 64 { 65 ; 66 } 67 68 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 69 70 G4VPhysicalVolume* Par01DetectorConstruction::Construct() 71 { 72 G4cout << "\nPar01DetectorConstruction....\n" << G4endl; 73 74 //--------- Material definition --------- 75 // Get nist material manager 76 G4NistManager* nistManager = G4NistManager::Instance(); 77 78 // Build materials 79 G4Material* air = nistManager->FindOrBuildMaterial("G4_AIR"); 80 G4Material* csi = nistManager->FindOrBuildMaterial("G4_CESIUM_IODIDE"); 81 G4Material* helium = nistManager->FindOrBuildMaterial("G4_He"); 82 G4Material* iron = nistManager->FindOrBuildMaterial("G4_Fe"); 83 84 //--------- G4VSolid, G4LogicalVolume, G4VPhysicalVolume --------- 85 86 //-------------- 87 // World: 88 //-------------- 89 G4Box* WorldBox = new G4Box("WorldBox", 400 * cm, 400 * cm, 400 * cm); 90 G4LogicalVolume* WorldLog = new G4LogicalVolume(WorldBox, air, "WorldLogical", 0, 0, 0); 91 G4PVPlacement* WorldPhys = 92 new G4PVPlacement(0, G4ThreeVector(), "WorldPhysical", WorldLog, 0, false, 0); 93 // Size of detectors: 94 G4double detectSize = 125 * cm; 95 96 //----------------------------- 97 // "Drift Chamber": 98 // Not used in parameterisation. 99 //----------------------------- 100 // -- Logical volume: 101 G4Box* driftChamberBox = new G4Box("DriftChamberSolid", detectSize, detectSize, 40 * cm); 102 G4LogicalVolume* driftChamberLog = 103 new G4LogicalVolume(driftChamberBox, helium, "DriftChamberLogical", 0, 0, 0); 104 // -- Placement: 105 // G4PVPlacement *driftChamberPhys = 106 new G4PVPlacement(0, G4ThreeVector(0., 0., 50 * cm), "DriftChamberPhysical", driftChamberLog, 107 WorldPhys, false, 0); 108 109 //-------------------------- 110 // "Calorimeter": used in 111 // parameterisation below 112 //-------------------------- 113 // -- Logical volume: 114 G4Box* calorimeterBox = new G4Box("CalorimeterSolid", detectSize, detectSize, 20 * cm); 115 G4LogicalVolume* calorimeterLog = 116 new G4LogicalVolume(calorimeterBox, air, "CalorimeterLogical", 0, 0, 0); 117 // -- Placement: 118 G4PVPlacement* calorimeterPhys = new G4PVPlacement( 119 0, G4ThreeVector(0., 0., 120 * cm), "CalorimeterPhysical", calorimeterLog, WorldPhys, false, 0); 120 121 //-------------------------------------- 122 // The calorimeter is filled with 123 // crystals: 124 //-------------------------------------- 125 // -- Logical volume: 126 G4double CrystalX = 2.5 * cm; 127 G4double CrystalY = CrystalX; 128 G4double CrystalZ = 20 * cm; 129 G4Box* CrystalSolid = new G4Box("CrystalSolid", CrystalX, CrystalY, CrystalZ); 130 fCrystalLog = new G4LogicalVolume(CrystalSolid, csi, "CrystalLogical", 0, 0, 0); 131 132 G4String tName1("Crystal"); // Allow all target physicals to share 133 // same name (delayed copy) 134 135 // -- and placements inside the calorimeter: 136 G4int copyNo = 0; 137 G4double xTlate, yTlate; 138 fnX = 48; 139 fnY = 48; 140 for (G4int j = 0; j < fnY; j++) { 141 yTlate = -detectSize + 3 * CrystalY + j * 2 * CrystalY; 142 for (G4int i = 0; i < fnX; i++) { 143 xTlate = -detectSize + 3 * CrystalX + i * 2 * CrystalX; 144 new G4PVPlacement(0, G4ThreeVector(xTlate, yTlate, 0 * cm), tName1, fCrystalLog, 145 calorimeterPhys, false, copyNo++); 146 } 147 } 148 149 //-------------------------- 150 // "Hadron Calorimeter": used 151 // in parameterisation with 152 // a parallel geometry 153 //-------------------------- 154 // -- Logical volume: 155 G4Box* hadCaloBox = new G4Box("HadCaloSolid", detectSize, detectSize, 50 * cm); 156 G4LogicalVolume* hadCaloLog = new G4LogicalVolume(hadCaloBox, air, "HadCaloLogical", 0, 0, 0); 157 // -- Placement: 158 G4PVPlacement* hadCaloPhys = new G4PVPlacement( 159 0, G4ThreeVector(0., 0., 200 * cm), "HadCaloPhysical", hadCaloLog, WorldPhys, false, 0); 160 161 //-------------------------------------- 162 // The calorimeter is filled with 163 // towers: 164 //-------------------------------------- 165 // -- Logical volume: 166 G4double TowerX = 5 * cm; 167 G4double TowerY = TowerX; 168 G4double TowerZ = 45 * cm; 169 G4Box* TowerSolid = new G4Box("TowerSolid", TowerX, TowerY, TowerZ); 170 fTowerLog = new G4LogicalVolume(TowerSolid, iron, "TowerLogical", 0, 0, 0); 171 172 G4String tName2("Tower"); 173 174 // -- and placements inside the calorimeter: 175 copyNo = 0; 176 fnXhad = 23; 177 fnYhad = 23; 178 for (G4int jj = 0; jj < fnYhad; jj++) { 179 yTlate = -detectSize + 3 * TowerY + jj * 2 * TowerY; 180 for (G4int i = 0; i < fnXhad; i++) { 181 xTlate = -detectSize + 3 * TowerX + i * 2 * TowerX; 182 new G4PVPlacement(0, G4ThreeVector(xTlate, yTlate, 0 * cm), tName2, fTowerLog, hadCaloPhys, 183 false, copyNo++); 184 } 185 } 186 187 // -- Makes the calorimeterLog volume becoming a G4Region: 188 G4Region* caloRegion = new G4Region("EM_calo_region"); 189 caloRegion->AddRootLogicalVolume(calorimeterLog); 190 std::vector<double> cuts; 191 cuts.push_back(1.0 * mm); 192 cuts.push_back(1.0 * mm); 193 cuts.push_back(1.0 * mm); 194 cuts.push_back(1.0 * mm); 195 caloRegion->SetProductionCuts(new G4ProductionCuts()); 196 caloRegion->GetProductionCuts()->SetProductionCuts(cuts); 197 198 // Makes had. calo a region to: 199 G4Region* hadRegion = new G4Region("HAD_calo_region"); 200 hadRegion->AddRootLogicalVolume(hadCaloLog); 201 cuts.clear(); 202 cuts.push_back(1.0 * cm); 203 cuts.push_back(1.0 * cm); 204 cuts.push_back(1.0 * cm); 205 cuts.push_back(1.0 * cm); 206 hadRegion->SetProductionCuts(new G4ProductionCuts()); 207 hadRegion->GetProductionCuts()->SetProductionCuts(cuts); 208 209 //--------- Visualization attributes ------------------------------- 210 WorldLog->SetVisAttributes(G4VisAttributes::GetInvisible()); 211 212 auto driftchamberTubeVisAtt = new G4VisAttributes(G4Colour(0.0, 1.0, 0.0)); 213 driftchamberTubeVisAtt->SetForceWireframe(true); 214 driftChamberLog->SetVisAttributes(driftchamberTubeVisAtt); 215 216 auto calorimeterBoxVisAtt = new G4VisAttributes(G4Colour(0.0, 0.0, 1.0)); 217 calorimeterBoxVisAtt->SetForceWireframe(true); 218 calorimeterLog->SetVisAttributes(calorimeterBoxVisAtt); 219 220 auto crystalVisAtt = new G4VisAttributes(G4Colour(1.0, 0.0, 0.0)); 221 crystalVisAtt->SetForceWireframe(true); 222 fCrystalLog->SetVisAttributes(crystalVisAtt); 223 224 auto hadCaloBoxVisAtt = new G4VisAttributes(G4Colour(1.0, 0.0, 1.0)); 225 hadCaloBoxVisAtt->SetForceWireframe(true); 226 hadCaloLog->SetVisAttributes(hadCaloBoxVisAtt); 227 228 auto towerVisAtt = new G4VisAttributes(G4Colour(0.5, 0.0, 1.0)); 229 towerVisAtt->SetForceWireframe(true); 230 fTowerLog->SetVisAttributes(towerVisAtt); 231 232 //------------------------------------------------------------------ 233 234 //----------------------- 235 // Returns the pointer to 236 // the physical world: 237 //----------------------- 238 return WorldPhys; 239 } 240 241 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 242 243 void Par01DetectorConstruction::ConstructSDandField() 244 { 245 //--------- Sensitive detector ------------------------------------- 246 G4SDManager* SDman = G4SDManager::GetSDMpointer(); 247 G4String calorimeterSDname = "Par01/Calorimeter"; 248 Par01CalorimeterSD* CalorimeterSD = 249 new Par01CalorimeterSD(calorimeterSDname, fnX * fnY, "CalCollection"); 250 SDman->AddNewDetector(CalorimeterSD); 251 fCrystalLog->SetSensitiveDetector(CalorimeterSD); 252 253 G4String hadCalorimeterSDname = "Par01/HadronCalorimeter"; 254 Par01CalorimeterSD* HadCalorimeterSD = 255 new Par01CalorimeterSD(hadCalorimeterSDname, fnXhad * fnYhad, "HadCollection"); 256 SDman->AddNewDetector(HadCalorimeterSD); 257 fTowerLog->SetSensitiveDetector(HadCalorimeterSD); 258 259 // --------------- fast simulation ---------------------------- 260 G4RegionStore* regionStore = G4RegionStore::GetInstance(); 261 262 G4Region* caloRegion = regionStore->GetRegion("EM_calo_region"); 263 // builds a model and sets it to the envelope of the calorimeter: 264 new Par01EMShowerModel("emShowerModel", caloRegion); 265 } 266