Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-17 08:06:16

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 //
0027 /// \file field/field04/src/F04DetectorConstruction.cc
0028 /// \brief Implementation of the F04DetectorConstruction class
0029 //
0030 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0031 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0032 
0033 #include "F04DetectorConstruction.hh"
0034 
0035 #include "F04DetectorMessenger.hh"
0036 #include "F04FocusSolenoid.hh"
0037 #include "F04GlobalField.hh"
0038 #include "F04Materials.hh"
0039 #include "F04SimpleSolenoid.hh"
0040 
0041 #include "G4AutoDelete.hh"
0042 #include "G4GeometryManager.hh"
0043 #include "G4LogicalVolume.hh"
0044 #include "G4LogicalVolumeStore.hh"
0045 #include "G4Material.hh"
0046 #include "G4NistManager.hh"
0047 #include "G4PVPlacement.hh"
0048 #include "G4PhysicalConstants.hh"
0049 #include "G4PhysicalVolumeStore.hh"
0050 #include "G4RotationMatrix.hh"
0051 #include "G4RunManager.hh"
0052 #include "G4SolidStore.hh"
0053 #include "G4StateManager.hh"
0054 #include "G4SystemOfUnits.hh"
0055 #include "G4Tubs.hh"
0056 #include "globals.hh"
0057 
0058 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0059 
0060 F04DetectorConstruction::F04DetectorConstruction()
0061 {
0062   SetTargetAngle(170);
0063   SetCaptureMgntB1(2.5 * tesla);
0064   SetCaptureMgntB2(5.0 * tesla);
0065   SetTransferMgntB(5.0 * tesla);
0066 
0067   fDegraderPos = -fTransferMgntLength / 2. + fDegraderThickness / 2.;
0068 
0069   fDetectorMessenger = new F04DetectorMessenger(this);
0070 }
0071 
0072 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0073 
0074 F04DetectorConstruction::~F04DetectorConstruction()
0075 {
0076   delete fDetectorMessenger;
0077 }
0078 
0079 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0080 
0081 G4VPhysicalVolume* F04DetectorConstruction::Construct()
0082 {
0083   if (fPhysiWorld) {
0084     G4GeometryManager::GetInstance()->OpenGeometry();
0085     G4PhysicalVolumeStore::GetInstance()->Clean();
0086     G4LogicalVolumeStore::GetInstance()->Clean();
0087     G4SolidStore::GetInstance()->Clean();
0088   }
0089 
0090   fMaterials = F04Materials::GetInstance();
0091 
0092   DefineMaterials();
0093 
0094   return ConstructDetector();
0095 }
0096 
0097 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0098 
0099 void F04DetectorConstruction::DefineMaterials()
0100 {
0101   // define materials for the experiment
0102 
0103   fVacuum = fMaterials->GetMaterial("G4_Galactic");
0104 
0105   fWorldMaterial = fMaterials->GetMaterial("G4_AIR");
0106   fDegraderMaterial = fMaterials->GetMaterial("G4_Pb");
0107   fTargetMaterial = fMaterials->GetMaterial("G4_W");
0108 }
0109 
0110 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0111 
0112 G4VPhysicalVolume* F04DetectorConstruction::ConstructDetector()
0113 {
0114   fSolidWorld = new G4Tubs("World", 0., GetWorldSizeR(), GetWorldSizeZ() / 2., 0., twopi);
0115 
0116   fLogicWorld = new G4LogicalVolume(fSolidWorld, GetWorldMaterial(), "World");
0117 
0118   fPhysiWorld =
0119     new G4PVPlacement(nullptr, G4ThreeVector(), "World", fLogicWorld, nullptr, false, 0);
0120 
0121   // Capture Magnet
0122 
0123   fSolidCaptureMgnt =
0124     new G4Tubs("CaptureMgnt", 0., GetCaptureMgntRadius(), GetCaptureMgntLength() / 2., 0., twopi);
0125 
0126   fLogicCaptureMgnt = new G4LogicalVolume(fSolidCaptureMgnt, fVacuum, "CaptureMgnt");
0127 
0128   fCaptureMgntCenter = G4ThreeVector();
0129 
0130   fPhysiCaptureMgnt = new G4PVPlacement(nullptr, fCaptureMgntCenter, "CaptureMgnt",
0131                                         fLogicCaptureMgnt, fPhysiWorld, false, 0);
0132 
0133   // Transfer Magnet
0134 
0135   fSolidTransferMgnt = new G4Tubs("TransferMgnt", 0., GetTransferMgntRadius(),
0136                                   GetTransferMgntLength() / 2., 0., twopi);
0137 
0138   fLogicTransferMgnt = new G4LogicalVolume(fSolidTransferMgnt, fVacuum, "TransferMgnt");
0139 
0140   G4double z = GetCaptureMgntLength() / 2. + GetTransferMgntLength() / 2. + GetTransferMgntPos();
0141   G4double x = GetTransferMgntPos() / 2.;
0142 
0143   fTransferMgntCenter = G4ThreeVector(x, 0., z);
0144 
0145   auto g4rot = new G4RotationMatrix();
0146   *g4rot = StringToRotationMatrix("Y30,X10");
0147   *g4rot = g4rot->inverse();
0148   if (*g4rot == G4RotationMatrix()) g4rot = nullptr;
0149 
0150   fPhysiTransferMgnt = new G4PVPlacement(g4rot, fTransferMgntCenter, "TransferMgnt",
0151                                          fLogicTransferMgnt, fPhysiWorld, false, 0);
0152 
0153   // Test Plane
0154 
0155   auto solidTestPlane = new G4Tubs("TestPlane", 0., GetTransferMgntRadius(), 1. * mm, 0., twopi);
0156 
0157   auto logicTestPlane = new G4LogicalVolume(solidTestPlane, fVacuum, "TestPlane");
0158 
0159   z = GetTransferMgntLength() / 2. - 1. * mm;
0160 
0161   G4ThreeVector testPlaneCenter = G4ThreeVector(0., 0., z);
0162 
0163   new G4PVPlacement(nullptr, testPlaneCenter, "TestPlane", logicTestPlane, fPhysiTransferMgnt,
0164                     false, 0);
0165 
0166   // Target
0167 
0168   if (GetTargetThickness() > 0.) {
0169     fSolidTarget =
0170       new G4Tubs("Target", 0., GetTargetRadius(), GetTargetThickness() / 2., 0., twopi);
0171 
0172     fLogicTarget = new G4LogicalVolume(fSolidTarget, GetTargetMaterial(), "Target");
0173 
0174     G4int i = GetTargetAngle();
0175 
0176     G4String angle = std::to_string(i);
0177     G4StrUtil::strip(angle);
0178     angle = "Y" + angle;
0179 
0180     g4rot = new G4RotationMatrix();
0181     *g4rot = StringToRotationMatrix(angle);
0182     *g4rot = g4rot->inverse();
0183     if (*g4rot == G4RotationMatrix()) g4rot = nullptr;
0184 
0185     G4ThreeVector targetCenter(0., 0., GetTargetPos());
0186 
0187     fPhysiTarget =
0188       new G4PVPlacement(g4rot, targetCenter, "Target", fLogicTarget, fPhysiCaptureMgnt, false, 0);
0189   }
0190 
0191   // Degrader
0192 
0193   if (GetDegraderThickness() > 0.) {
0194     fSolidDegrader =
0195       new G4Tubs("Degrader", 0., GetDegraderRadius(), GetDegraderThickness() / 2., 0., twopi);
0196 
0197     fLogicDegrader = new G4LogicalVolume(fSolidDegrader, GetDegraderMaterial(), "Degrader");
0198 
0199     G4ThreeVector degraderCenter = G4ThreeVector(0., 0., GetDegraderPos());
0200 
0201     fPhysiDegrader = new G4PVPlacement(nullptr, degraderCenter, "Degrader", fLogicDegrader,
0202                                        fPhysiTransferMgnt, false, 0);
0203   }
0204 
0205   return fPhysiWorld;
0206 }
0207 
0208 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0209 
0210 void F04DetectorConstruction::SetWorldMaterial(const G4String materialChoice)
0211 {
0212   G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
0213 
0214   if (pttoMaterial != fWorldMaterial) {
0215     if (pttoMaterial) {
0216       fWorldMaterial = pttoMaterial;
0217       G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0218     }
0219     else {
0220       G4cout << "\n--> WARNING from SetWorldMaterial : " << materialChoice << " not found"
0221              << G4endl;
0222     }
0223   }
0224 }
0225 
0226 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0227 
0228 void F04DetectorConstruction::SetTargetMaterial(const G4String materialChoice)
0229 {
0230   G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
0231 
0232   if (pttoMaterial != fTargetMaterial) {
0233     if (pttoMaterial) {
0234       fTargetMaterial = pttoMaterial;
0235       G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0236     }
0237     else {
0238       G4cout << "\n-->  WARNING from SetTargetMaterial : " << materialChoice << " not found"
0239              << G4endl;
0240     }
0241   }
0242 }
0243 
0244 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0245 
0246 void F04DetectorConstruction::SetDegraderMaterial(const G4String materialChoice)
0247 
0248 {
0249   G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
0250 
0251   if (pttoMaterial != fDegraderMaterial) {
0252     if (pttoMaterial) {
0253       fDegraderMaterial = pttoMaterial;
0254       G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0255     }
0256     else {
0257       G4cout << "\n--> WARNING from SetDegraderMaterial : " << materialChoice << " not found"
0258              << G4endl;
0259     }
0260   }
0261 }
0262 
0263 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0264 
0265 void F04DetectorConstruction::SetWorldSizeZ(G4double val)
0266 {
0267   fWorldSizeZ = val;
0268   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0269     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0270 }
0271 
0272 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0273 
0274 void F04DetectorConstruction::SetWorldSizeR(G4double val)
0275 {
0276   fWorldSizeR = val;
0277   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0278     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0279 }
0280 
0281 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0282 
0283 void F04DetectorConstruction::SetCaptureMgntRadius(G4double val)
0284 {
0285   fCaptureMgntRadius = val;
0286   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0287     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0288 }
0289 
0290 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0291 
0292 void F04DetectorConstruction::SetCaptureMgntLength(G4double val)
0293 {
0294   fCaptureMgntLength = val;
0295   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0296     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0297 }
0298 
0299 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0300 
0301 void F04DetectorConstruction::SetCaptureMgntB1(G4double val)
0302 {
0303   fCaptureMgntB1 = val;
0304   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0305     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0306 }
0307 
0308 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0309 
0310 void F04DetectorConstruction::SetCaptureMgntB2(G4double val)
0311 {
0312   fCaptureMgntB2 = val;
0313   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0314     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0315 }
0316 
0317 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0318 
0319 void F04DetectorConstruction::SetTransferMgntRadius(G4double val)
0320 {
0321   fTransferMgntRadius = val;
0322   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0323     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0324 }
0325 
0326 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0327 
0328 void F04DetectorConstruction::SetTransferMgntLength(G4double val)
0329 {
0330   fTransferMgntLength = val;
0331   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0332     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0333 }
0334 
0335 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0336 
0337 void F04DetectorConstruction::SetTransferMgntB(G4double val)
0338 {
0339   fTransferMgntB = val;
0340   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0341     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0342 }
0343 
0344 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0345 
0346 void F04DetectorConstruction::SetTransferMgntPos(G4double val)
0347 {
0348   fTransferMgntPos = val;
0349   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0350     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0351 }
0352 
0353 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0354 
0355 void F04DetectorConstruction::SetTargetRadius(G4double val)
0356 {
0357   fTargetRadius = val;
0358   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0359     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0360 }
0361 
0362 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0363 
0364 void F04DetectorConstruction::SetTargetThickness(G4double val)
0365 {
0366   fTargetThickness = val;
0367   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0368     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0369 }
0370 
0371 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0372 
0373 void F04DetectorConstruction::SetTargetPos(G4double val)
0374 {
0375   fTargetPos = val;
0376   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0377     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0378 }
0379 
0380 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0381 
0382 void F04DetectorConstruction::SetTargetAngle(G4int val)
0383 {
0384   fTargetAngle = val;
0385   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0386     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0387 }
0388 
0389 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0390 
0391 void F04DetectorConstruction::SetDegraderRadius(G4double val)
0392 {
0393   fDegraderRadius = val;
0394   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0395     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0396 }
0397 
0398 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0399 
0400 void F04DetectorConstruction::SetDegraderThickness(G4double val)
0401 {
0402   fDegraderThickness = val;
0403   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0404     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0405 }
0406 
0407 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0408 
0409 void F04DetectorConstruction::SetDegraderPos(G4double val)
0410 {
0411   fDegraderPos = val;
0412   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0413     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0414 }
0415 
0416 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0417 
0418 void F04DetectorConstruction::ConstructSDandField()
0419 {
0420   if (!fFieldSetUp.Get()) {
0421     F04GlobalField* field = F04GlobalField::GetObject(this);
0422     G4AutoDelete::Register(field);  // Kernel will delete the F04GlobalField
0423     fFieldSetUp.Put(field);
0424   }
0425 }
0426 
0427 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0428 
0429 G4RotationMatrix F04DetectorConstruction::StringToRotationMatrix(G4String rotation)
0430 {
0431   // We apply successive rotations OF THE OBJECT around the FIXED
0432   // axes of the parent's local coordinates; rotations are applied
0433   // left-to-right (rotation="r1,r2,r3" => r1 then r2 then r3).
0434 
0435   G4RotationMatrix rot;
0436 
0437   unsigned int place = 0;
0438 
0439   while (place < rotation.size()) {
0440     G4double angle;
0441     char* p(nullptr);
0442     G4String current = rotation.substr(place + 1);
0443     angle = strtod(current.c_str(), &p) * deg;
0444 
0445     if (!p || (*p != ',' && *p != '\0')) {
0446       G4cerr << "Invalid rotation specification: " << rotation.c_str() << G4endl;
0447 
0448       return rot;
0449     }
0450 
0451     G4RotationMatrix thisRotation;
0452 
0453     switch (rotation.substr(place, 1).c_str()[0]) {
0454       case 'X':
0455       case 'x':
0456         thisRotation = G4RotationMatrix(CLHEP::HepRotationX(angle));
0457         break;
0458       case 'Y':
0459       case 'y':
0460         thisRotation = G4RotationMatrix(CLHEP::HepRotationY(angle));
0461         break;
0462       case 'Z':
0463       case 'z':
0464         thisRotation = G4RotationMatrix(CLHEP::HepRotationZ(angle));
0465         break;
0466       default:
0467         G4cerr << " Invalid rotation specification: " << rotation << G4endl;
0468         return rot;
0469     }
0470 
0471     rot = thisRotation * rot;
0472     place = rotation.find(',', place);
0473     if (place > rotation.size()) break;
0474     ++place;
0475   }
0476 
0477   return rot;
0478 }