LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
DetectorConstruction.cxx
Go to the documentation of this file.
1 
11 #include "cetlib_except/exception.h"
12 
16 
17 #include "Geant4/G4VPhysicalVolume.hh"
18 #include "Geant4/G4GDMLParser.hh"
19 #include "Geant4/G4LogicalVolumeStore.hh"
20 #include "Geant4/G4Material.hh"
21 #include "Geant4/G4UniformMagField.hh"
22 #include "Geant4/G4FieldManager.hh"
23 
24 namespace g4b{
25 
26  // Allocate static variables.
27  G4VPhysicalVolume* DetectorConstruction::fWorld = nullptr;
28  G4FieldManager* DetectorConstruction::fFieldMgr = nullptr;
29 
30  //---------------------------------------------------
31  // Constructor
32  DetectorConstruction::DetectorConstruction(std::string const& gdmlFile,
33  bool const& overlapCheck,
34  bool const& validateSchema)
35  {
36  if ( gdmlFile.empty() ) {
37  throw cet::exception("DetectorConstruction") << "Supplied GDML filename is empty\n"
38  << __FILE__ << ":" << __LINE__ << "\n";
39  }
40  // Get the path to the GDML file from the Geometry interface.
41  const G4String GDMLfile = static_cast<const G4String>( gdmlFile );
42 
43  // Use Geant4's GDML parser to convert the geometry to Geant4 format.
44  G4GDMLParser parser;
45  parser.SetOverlapCheck(overlapCheck);
46  parser.Read(GDMLfile,validateSchema);
47 
48  // Fetch the world physical volume from the parser. This contains
49  // the entire detector, not just the outline of the experimental
50  // hall.
51  fWorld = parser.GetWorldVolume();
52 
53  }
54 
55  //---------------------------------------------------
56  // Destructor.
58  {
59  }
60 
61  //---------------------------------------------------
62  G4VPhysicalVolume* DetectorConstruction::Construct()
63  {
64  // Setup the magnetic field situation
66  auto const * pProvider = bField->provider(); //get the provider
67 
68  // loop over the possible fields
69  for(auto fd : pProvider->Fields()){
70  switch (fd.fMode) {
71  case mag::kNoBFieldMode:
72  /* NOP */
73  break;
75  // Attach this to the magnetized volume only, so get that volume
76  G4LogicalVolume *bvol = G4LogicalVolumeStore::GetInstance()->GetVolume(fd.fVolume);
77 
78  // Define the basic field, using p we should get the uniform field
79  G4UniformMagField* magField = new G4UniformMagField( fd.fField * CLHEP::tesla );
80  fFieldMgr = new G4FieldManager();
81  fFieldMgr->SetDetectorField(magField);
82  fFieldMgr->CreateChordFinder(magField);
83 
84  MF_LOG_INFO("DetectorConstruction")
85  << "Setting uniform magnetic field to be "
86  << magField->GetConstantFieldValue().x() << " "
87  << magField->GetConstantFieldValue().y() << " "
88  << magField->GetConstantFieldValue().z() << " "
89  << " in " << bvol->GetName();
90 
91  // Reset the chord finding accuracy
92  // fFieldMgr->GetChordFinder()->SetDeltaChord(1.0 * cm);
93 
94  // the boolean tells the field manager to use local volume
95  bvol->SetFieldManager(fFieldMgr, true);
96 
97  break;
98  } // case mag::kConstantBFieldMode
99  case mag::kFieldRZMapMode: {
100 
101  // Attach this to the magnetized volume only, so get that volume
102  G4LogicalVolume *bvol = G4LogicalVolumeStore::GetInstance()->GetVolume(fd.fVolume);
103 
105  fFieldMgr = new G4FieldManager();
106  fFieldMgr->SetDetectorField(magField);
107  fFieldMgr->CreateChordFinder(magField);
108 
109  MF_LOG_INFO("DetectorConstruction")
110  << "Setting magnetic field in kFieldRZMapMode to be"
111  << " in " << bvol->GetName();
112 
113  // the boolean tells the field manager to use local volume
114  bvol->SetFieldManager(fFieldMgr, true);
115 
116  break;
117  } // case mag::kFieldRZMapMode
118  case mag::kFieldXYZMapMode: {
119 
120  // Attach this to the magnetized volume only, so get that volume
121  G4LogicalVolume *bvol = G4LogicalVolumeStore::GetInstance()->GetVolume(fd.fVolume);
122 
124  fFieldMgr = new G4FieldManager();
125  fFieldMgr->SetDetectorField(magField);
126  fFieldMgr->CreateChordFinder(magField);
127 
128  MF_LOG_INFO("DetectorConstruction")
129  << "Setting magnetic field in kFieldXYZMapMode to be"
130  << " in " << bvol->GetName();
131 
132  // the boolean tells the field manager to use local volume
133  bvol->SetFieldManager(fFieldMgr, true);
134 
135  break;
136  } // case mag::kFieldXYZMapMode
137  default: // Complain if the user asks for something not handled
138  MF_LOG_ERROR("DetectorConstruction")
139  << "Unknown or illegal Magneticfield "
140  << "mode specified: "
141  << fd.fMode
142  << ". Note that AutomaticBFieldMode is reserved.";
143  break;
144  } // end switch cases
145 
146  } // end loop over fields
147 
148  return fWorld;
149  }
150 
151 }// namespace
Build Geant4 geometry from GDML.
#define MF_LOG_ERROR(category)
DetectorConstruction(std::string const &gdmlFile, bool const &overlapCheck=false, bool const &validateSchema=true)
Standard constructor and destructor.
virtual const mag::MagneticField * provider() const =0
CommandLineParser * parser(0)
basic interface to Geant4 for ART-based software
#define MF_LOG_INFO(category)
static G4FieldManager * fFieldMgr
pointer to the field manager
static G4VPhysicalVolume * fWorld
pointer to the world volume
G4VPhysicalVolume * Construct()
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33