LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
DetectorHolder.cc
Go to the documentation of this file.
1 // For more comprehensive documentation, see DetectorHolderService.hh.
2 
3 // Authors: Tasha Arvanitis, Adam Lyon
4 // Date: July 2012
5 
6 // Includes
7 
10 
12 
13 // Save ourselves the trouble of typing 'std::' all the time
14 using std::endl;
15 using std::map;
16 using std::pair;
17 using std::string;
18 
19 // Category for this file
20 static std::string msgctg = "DetectorHolderService";
21 
22 // PUBLIC METHODS
23 
24 // Constructor doesn't do anything with either of its passed components.
26  : categoryMap_(), worldPV_(nullptr)
27 {}
28 
29 // Register a detector object with this service
30 void
32 {
33  mf::LogDebug(msgctg) << "Registering detector named " << db->myName();
35 }
36 
37 // Get the physical volume for the world/lab in the simulation
38 G4VPhysicalVolume*
40 {
41  // Check if we have a world yet.
42  if (0 == worldPV_) {
43  // We don't - let's construct all the physical volumes.
45 
46  // Check whether we have a world at this point. If not, we have a problem.
47  if (0 == worldPV_) {
48  throw cet::exception("DetectorHolderService") << "No world volume "
49  << "constructed!\n";
50  }
51  }
52  // If we reach this point, the world volume exists, so let's return it!
53  return worldPV_;
54 }
55 
56 // Set up all the detectors' LVs
57 void
59 {
60  // Let's loop over the detectors in the map
61  for (auto entry : categoryMap_) {
62  mf::LogDebug(msgctg) << "Constructing logical volumes for detector of "
63  << "category " << (entry.second)->category();
64 
65  (entry.second)->buildLVs();
66  }
67 }
68 
69 // Initialize all detectors
70 void
72 {
73  for (auto entry : categoryMap_) {
74  mf::LogDebug(msgctg) << "Initializing detector with category " << (entry.second)->category();
75 
76  (entry.second)->initialize();
77  }
78 }
79 
80 // Set up all the detectors' PVs
81 void
83 {
84  // Let's loop over the detectors in the map
85  for (auto entry : categoryMap_) {
86  mf::LogDebug(msgctg) << "Constructing physical volumes for detector of "
87  << "category " << (entry.second)->category();
88 
89  placeDetector(entry.second);
90  }
91 }
92 
93 // Get a specific detector, given a category string.
96 {
97 
98  auto categoryDB = categoryMap_.find(category);
99 
100  if (categoryDB != categoryMap_.end()) {
101  // We have a detector of that category
102  return categoryDB->second;
103  }
104  throw cet::exception("DetectorHolderService")
105  << "No detector found for category " << category << ".LO";
106 }
107 
108 // Get the parameter set for a detector given its category string
111 {
112  return getDetectorForCategory(category)->parameters();
113 }
114 
115 // Tell the detectors to tell Art what they produce
116 void
118 {
119  // Let's loop over the detectors in the map
120  for (auto entry : categoryMap_) {
121  mf::LogDebug(msgctg) << "Calling art produces for category " << (entry.second)->category();
122  (entry.second)->callArtProduces(collector);
123  }
124 }
125 
126 // Convert geant hits to art hits for all detectors
127 void
129 {
130  // Let's loop over the detectors in the map
131  for (auto entry : categoryMap_) {
132  mf::LogDebug(msgctg) << "Converting hits for category " << (entry.second)->category();
133  (entry.second)->fillEventWithArtHits(hc);
134  }
135 }
136 
137 // PRIVATE METHODS
138 
139 // Add a detector base object to our collection of registered detectors
140 void
142 {
143  if (categoryMap_.find(db->category()) != cend(categoryMap_)) {
144  // We already have one of these detectors
145  throw cet::exception("DetectorHolderService")
146  << "Duplicate detector found. "
147  << "There is already one detector with the category " << db->category() << ".\n";
148  }
149  categoryMap_.try_emplace(db->category(), db);
150  mf::LogDebug(msgctg) << "Registered detector with category: " << db->category();
151 }
152 
153 // Find a detector's mother logical volume and pass it to the detector to
154 // allow it to create its own physical volume.
155 void
157 {
158  // Check if we're dealing with the world volume first.
159  if (db->category() == "world") {
160  // The world's mother 'logical volume' is an empty vector.
161  worldPV_ = (db->placeToPVs(std::vector<G4LogicalVolume*>()))[0];
162  mf::LogDebug(msgctg) << "Just placed detector with category: " << db->category();
163  return;
164  }
165 
166  // Deal with non-world detectors
167  auto motherCategoryDB = categoryMap_.find(db->motherCategory());
168  if (motherCategoryDB == categoryMap_.end()) {
169  throw cet::exception("DetectorHolderService")
170  << "No mother volume found for detector with category " << db->category()
171  << ", which wanted a mother of category " << db->motherCategory()
172  << ". This probably means you are missing a "
173  << "detector class (derived from DetectorBase).\n";
174  }
175 
176  // We have a parent volume - pass the DB its mother volume and call place.
177  db->placeToPVs(motherCategoryDB->second->lvs());
178  mf::LogDebug(msgctg) << "Just placed detector with category: " << db->category();
179 }
G4VPhysicalVolume * worldPhysicalVolume()
DetectorHolderService(fhicl::ParameterSet const &)
decltype(auto) constexpr cend(T &&obj)
ADL-aware version of std::cend.
Definition: StdUtils.h:93
fhicl::ParameterSet const & parameters() const
fhicl::ParameterSet const getParametersForCategory(std::string category)
std::map< std::string, DetectorBase * > categoryMap_
static std::string msgctg
void placeDetector(DetectorBase *const db)
void addDBtoCategoryMap(DetectorBase *const db)
void registerDetector(DetectorBase *const db)
std::string const & myName() const
std::vector< G4VPhysicalVolume * > placeToPVs(std::vector< G4LogicalVolume * > motherLVs)
DetectorBase * getDetectorForCategory(std::string category) const
std::string const & motherCategory() const
std::string const & category() const
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
void callArtProduces(art::ProducesCollector &)
void fillEventWithArtHits(G4HCofThisEvent *hc)
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33