LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
GeometryConfigurationWriter_service.cc
Go to the documentation of this file.
1 
8 // LArSoft libraries
12 
13 // framework libraries
19 #include "cetlib/HorizontalRule.h"
20 #include "fhiclcpp/types/Atom.h"
22 
23 // C/C++ standard libraries
24 #include <memory> // std::make_unique()
25 #include <utility> // std::move()
26 
27 // -----------------------------------------------------------------------------
28 namespace geo {
29  class GeometryConfigurationWriter;
30 }
97 public:
99  struct Config {
100  fhicl::Atom<bool> SkipConfigurationCheck{fhicl::Name("SkipConfigurationCheck"), false};
101  };
103 
105 
106 private:
108  void postReadRun(art::Run& run) override;
109 
111  using InfoPtr_t = std::unique_ptr<sumdata::GeometryConfigurationInfo>;
112 
114  InfoPtr_t previousInfo(art::Run const& run) const;
115 
118 
123  art::RunID const& id) const;
124 
126  InfoPtr_t readGeometryInformation(art::Run const& run) const;
127 
130  InfoPtr_t makeInfoFromRunData(art::Run const& run) const;
131 
133  sumdata::RunData const* readRunData(art::Run const& run) const;
134 
136 
137 }; // geo::GeometryConfigurationWriter
138 
139 // -----------------------------------------------------------------------------
140 // --- implementation
141 // -----------------------------------------------------------------------------
142 
143 namespace {
144  // ---------------------------------------------------------------------------
145  auto makeInfoPtr(sumdata::GeometryConfigurationInfo info)
146  {
147  return std::make_unique<sumdata::GeometryConfigurationInfo>(std::move(info));
148  }
149 
150  // ---------------------------------------------------------------------------
151  // Converts the legacy `data` into geometry configuration information.
152  auto convertRunDataToGeometryInformation(sumdata::RunData const& data)
153  {
155 
156  // we use the simplest version 1 data format (legacy format)
158  confInfo.detectorName = data.DetName();
159 
160  MF_LOG_DEBUG("GeometryConfigurationInfo")
161  << "Built geometry configuration information from run data:\n"
162  << confInfo;
163 
164  return makeInfoPtr(std::move(confInfo));
165  }
166 
167  //......................................................................
168  // Returns if `A` and `B` are compatible geometry service configurations.
169  bool compareConfigurationInfo(sumdata::GeometryConfigurationInfo const& A,
171  {
178  if (!A.isDataValid()) {
179  mf::LogWarning("GeometryConfiguration") << "invalid version for configuration A:\n" << A;
180  return false;
181  }
182  if (!B.isDataValid()) {
183  mf::LogWarning("GeometryConfiguration") << "invalid version for configuration B:\n" << B;
184  return false;
185  }
186 
187  // currently used only in debug mode (assert())
188  [[maybe_unused]] auto const commonVersion = std::min(A.dataVersion, B.dataVersion);
189 
190  assert(commonVersion >= 1);
191 
192  if (A.detectorName != B.detectorName) { // case sensitive so far
193  mf::LogWarning("GeometryConfiguration")
194  << "detector name mismatch: '" << A.detectorName << "' vs. '" << B.detectorName << "'";
195  return false;
196  }
197 
198  return true;
199  }
200 
201 }
202 
203 // -----------------------------------------------------------------------------
205  : fFatalConfCheck{not p().SkipConfigurationCheck()}
206 {
207  produces<sumdata::GeometryConfigurationInfo, art::InRun>();
208 }
209 
210 // -----------------------------------------------------------------------------
212 {
213  auto previousConfInfo = previousInfo(run);
214  auto currentConfInfo = extractInfoFromGeometry();
215  if (previousConfInfo && currentConfInfo) {
216  verifyConsistentConfigs(*previousConfInfo, *currentConfInfo, run.id());
217  }
218 
219  InfoPtr_t confInfo = previousConfInfo ? std::move(previousConfInfo) : std::move(currentConfInfo);
220  run.put(std::move(confInfo), art::fullRun());
221 }
222 
223 // -----------------------------------------------------------------------------
225 {
234  return info ? std::move(info) : makeInfoFromRunData(run);
235 }
236 
237 // -----------------------------------------------------------------------------
239 {
240 
242  art::ServiceHandle<geo::Geometry>()->configurationInfo();
243 
244  MF_LOG_DEBUG("GeometryConfigurationWriter")
245  << "Geometry configuration information from service:\n"
246  << confInfo;
247 
248  return makeInfoPtr(std::move(confInfo));
249 }
250 
251 // -----------------------------------------------------------------------------
255  art::RunID const& id) const
256 {
257  auto consistentInfo = compareConfigurationInfo(A, B);
258  if (consistentInfo) { return; }
259 
260  if (fFatalConfCheck) {
261  cet::HorizontalRule rule{50};
262  throw cet::exception("GeometryConfiguration")
263  << "Geometry used for run " << id << " is incompatible with the one configured in the job!"
264  << "\n=== job configuration " << rule('=') << "\n"
265  << B << "\n=== run configuration " << rule('=') << "\n"
266  << A << "\n======================" << rule('=') << "\n";
267  }
268  mf::LogWarning("GeometryConfiguration")
269  << "Geometry used for " << id << " is incompatible with the one configured in the job.";
270 }
271 
272 // -----------------------------------------------------------------------------
274  -> InfoPtr_t
275 {
276  if (auto h = run.getHandle<sumdata::GeometryConfigurationInfo>(
277  art::InputTag{"GeometryConfigurationWriter"})) {
278  return makeInfoPtr(*h);
279  }
280  return nullptr;
281 }
282 
283 // -----------------------------------------------------------------------------
285 {
286  sumdata::RunData const* runData = readRunData(run);
287  return runData ? convertRunDataToGeometryInformation(*runData) : InfoPtr_t{};
288 }
289 
290 // -----------------------------------------------------------------------------
292 {
293  auto allRunData = run.getMany<sumdata::RunData>();
294  return allRunData.empty() ? nullptr : allRunData.front().product();
295 }
296 
RunID id() const
Definition: Run.cc:21
constexpr auto fullRun()
Writes geometry configuration information into art runs.
std::string const & DetName() const
Definition: RunData.h:35
DataVersion_t dataVersion
Version of the data in this object (0 is invalid version).
void verifyConsistentConfigs(sumdata::GeometryConfigurationInfo const &A, sumdata::GeometryConfigurationInfo const &B, art::RunID const &id) const
PutHandle< PROD > put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: Run.h:121
InfoPtr_t makeInfoFromRunData(art::Run const &run) const
Definition: Run.h:37
InfoPtr_t readGeometryInformation(art::Run const &run) const
Reads geometry information from the run (returns null pointer if none).
bool isDataValid() const noexcept
Protocol: whether the data content is valid.
#define DEFINE_ART_PRODUCING_SERVICE(klass)
std::unique_ptr< sumdata::GeometryConfigurationInfo > InfoPtr_t
Alias for the pointer to the data product object to be put into the run.
static InfoPtr_t extractInfoFromGeometry()
Creates configuration information based on the current Geometry service.
Description of the current configuration of detector geometry.
unsigned int DataVersion_t
Type used for the version of data.
InfoPtr_t previousInfo(art::Run const &run) const
Loads the geometry information from the run (either directly or legacy).
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
#define MF_LOG_DEBUG(id)
sumdata::RunData const * readRunData(art::Run const &run) const
Returns a pointer to the sumdata::RunData in run (nullptr if none).
ROOT libraries.
void postReadRun(art::Run &run) override
Writes the information from the service configuration into the run.
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
Description of the current configuration of detector geometry.
std::vector< Handle< PROD > > getMany(SelectorBase const &selector=MatchAllSelector{}) const