All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GeometryConfigurationWriter_service.cc
Go to the documentation of this file.
1 /**
2  * @file larcore/Geometry/GeometryConfigurationWriter_service.cc
3  * @brief Service writing geometry configuration information into _art_ runs.
4  * @date October 7, 2020
5  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
6  *
7  * Producing services have no header.
8  */
9 
10 // LArSoft libraries
14 
15 // framework libraries
16 #include "art/Framework/Core/ProducingService.h"
17 #include "art/Framework/Principal/Handle.h"
18 #include "art/Framework/Principal/Run.h"
19 #include "art/Framework/Services/Registry/ServiceHandle.h"
20 #include "canvas/Utilities/InputTag.h"
21 #include "messagefacility/MessageLogger/MessageLogger.h"
22 
23 // C/C++ standard libraries
24 #include <memory> // std::make_unique()
25 #include <utility> // std::move()
26 
27 // -----------------------------------------------------------------------------
28 namespace geo { class GeometryConfigurationWriter; }
29 /**
30  * @brief Writes geometry configuration information into _art_ runs.
31  *
32  * This service is part of the mandatory version check of `geo::Geometry`
33  * service.
34  * It does not require any special configuration, but it must be listed
35  * in the configuration in order for `Geometry` to work:
36  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37  * services: {
38  *
39  * GeometryConfigurationWriter: {}
40  *
41  * Geometry: @local::experiment_geometry
42  *
43  * # ...
44  *
45  * }
46  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47  *
48  * The configuration check is described in the documentation of `geo::Geometry`
49  * service.
50  *
51  *
52  * Produced data products
53  * -----------------------
54  *
55  * The service guarantees that configuration information of type
56  * `sumdata::GeometryConfigurationInfo` is present into the run, accessible with
57  * an input tag `GeometryConfigurationWriter`:
58  *
59  * * if such information is already available in the run, no further information
60  * is added
61  * * legacy: if there is no such information, but there is a `sumdata::RunData`
62  * data product, a reduced version of the configuration information is created
63  * from the information in that data product (the first one, if multiple are
64  * present)
65  * * finally, if no information is present neither in the full
66  * `sumdata::GeometryConfigurationInfo` form nor in the legacy
67  * `sumdata::RunData` form, information is put together based on the current
68  * configuration of the `Geometry` service.
69  *
70  *
71  * Service dependencies
72  * ---------------------
73  *
74  * * `Geometry` service
75  * (for obtaining the current configuration to put into the event)
76  *
77  */
78 class geo::GeometryConfigurationWriter: public art::ProducingService {
79 
80  public:
81 
82  /// Service configuration.
83  struct Config {
84  // no configuration parameters at this time
85  };
86 
87  using Parameters = art::ServiceTable<Config>;
88 
89  /// Constructor: gets its configuration and does nothing with it.
91 
92 
93  private:
94 
95  /// Writes the information from the service configuration into the `run`.
96  virtual void postReadRun(art::Run& run) override;
97 
98 
99  private:
100 
101  /// Alias for the pointer to the data product object to be put into the run.
102  using InfoPtr_t = std::unique_ptr<sumdata::GeometryConfigurationInfo>;
103 
104 
105  /// Loads the geometry information from the `run` (either directly or legacy).
106  InfoPtr_t loadInfo(art::Run& run) const;
107 
108  /// Creates configuration information based on the current `Geometry` service.
110 
111  /// Reads geometry information from the run (returns null pointer if none).
112  InfoPtr_t readGeometryInformation(art::Run& run) const;
113 
114  /// Upgrades legacy `sumdata::RunData` in `run` to geometry information
115  /// (returns null pointer if no legacy information is present).
116  InfoPtr_t makeInfoFromRunData(art::Run& run) const;
117 
118  /// Returns a pointer to the `sumdata::RunData` in `run` (nullptr if none).
119  sumdata::RunData const* readRunData(art::Run& run) const;
120 
121  /// Converts the legacy `data` into geometry configuration information.
123  (sumdata::RunData const& data);
124 
125  /// Alias to `std::make_unique<sumdata::GeometryConfigurationInfo>`.
127  { return std::make_unique<sumdata::GeometryConfigurationInfo>(info); }
128 
129 
130 }; // geo::GeometryConfigurationWriter
131 
132 
133 // -----------------------------------------------------------------------------
134 // --- implementation
135 // -----------------------------------------------------------------------------
137 {
138  produces<sumdata::GeometryConfigurationInfo, art::InRun>();
139 }
140 
141 
142 // -----------------------------------------------------------------------------
144 
146 
147  if (!confInfo) confInfo = extractInfoFromGeometry();
148 
149  run.put(std::move(confInfo), art::fullRun());
150 
151 } // geo::GeometryConfigurationWriter::postReadRun()
152 
153 
154 // -----------------------------------------------------------------------------
156  -> InfoPtr_t
157 {
158 
159  /*
160  * Read geometry configuration information from the run:
161  *
162  * 1. first attempt to directly read information from past runs of this
163  * service
164  * 2. if none is found, attempt reading legacy information and upgrade it
165  * 3. if no legacy information is found either, return a null pointer
166  *
167  */
168  InfoPtr_t info = readGeometryInformation(run);
169 
170  return info? std::move(info): makeInfoFromRunData(run);
171 
172 } // geo::GeometryConfigurationWriter::loadInfo()
173 
174 
175 // -----------------------------------------------------------------------------
177 
179  = art::ServiceHandle<geo::Geometry>()->configurationInfo();
180 
181  MF_LOG_DEBUG("GeometryConfigurationWriter")
182  << "Geometry configuration information from service:\n" << confInfo;
183 
184  return makeInfoPtr(std::move(confInfo));
185 
186 } // geo::GeometryConfigurationWriter::extractInfoFromGeometry()
187 
188 
189 // -----------------------------------------------------------------------------
191  (art::Run& run) const -> InfoPtr_t
192 {
193 
194  art::Handle<sumdata::GeometryConfigurationInfo> infoHandle;
195  return
196  run.getByLabel(art::InputTag{"GeometryConfigurationWriter"}, infoHandle)
197  ? makeInfoPtr(*infoHandle): InfoPtr_t{};
198 
199 } // geo::GeometryConfigurationWriter::hasGeometryInformation()
200 
201 
202 // -----------------------------------------------------------------------------
204  -> InfoPtr_t
205 {
206 
207  sumdata::RunData const* runData = readRunData(run);
208 
209  return runData? convertRunDataToGeometryInformation(*runData): InfoPtr_t{};
210 
211 } // geo::GeometryConfigurationWriter::makeInfoFromRunData()
212 
213 
214 // -----------------------------------------------------------------------------
216  (art::Run& run) const
217 {
218  //std::vector<art::Handle<sumdata::RunData>> allRunData;
219  //run.getManyByType(allRunData);
220  auto allRunData = run.getMany<sumdata::RunData>();
221  return allRunData.empty()? nullptr: allRunData.front().product();
222 } // geo::GeometryConfigurationWriter::readRunData()
223 
224 
225 // -----------------------------------------------------------------------------
227  (sumdata::RunData const& data) -> InfoPtr_t
228 {
229 
231 
232  // we use the simplest version 1 data format (legacy format)
234  confInfo.detectorName = data.DetName();
235 
236  MF_LOG_DEBUG("GeometryConfigurationInfo")
237  << "Built geometry configuration information from run data:\n" << confInfo;
238 
239  return makeInfoPtr(std::move(confInfo));
240 
241 } // geo::GeometryConfigurationWriter::convertRunDataToGeometryInformation()
242 
243 
244 // -----------------------------------------------------------------------------
245 DEFINE_ART_PRODUCING_SERVICE(geo::GeometryConfigurationWriter)
246 
247 
248 // -----------------------------------------------------------------------------
Writes geometry configuration information into art runs.
std::string const & DetName() const
Definition: RunData.h:39
DataVersion_t dataVersion
Version of the data in this object (0 is invalid version).
GeometryConfigurationWriter(Parameters const &)
Constructor: gets its configuration and does nothing with it.
static InfoPtr_t makeInfoPtr(sumdata::GeometryConfigurationInfo const &info)
Alias to std::make_unique&lt;sumdata::GeometryConfigurationInfo&gt;.
static InfoPtr_t convertRunDataToGeometryInformation(sumdata::RunData const &data)
Converts the legacy data into geometry configuration information.
std::unique_ptr< sumdata::GeometryConfigurationInfo > InfoPtr_t
Alias for the pointer to the data product object to be put into the run.
InfoPtr_t readGeometryInformation(art::Run &run) const
Reads geometry information from the run (returns null pointer if none).
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.
sumdata::RunData const * readRunData(art::Run &run) const
Returns a pointer to the sumdata::RunData in run (nullptr if none).
virtual void postReadRun(art::Run &run) override
Writes the information from the service configuration into the run.
art framework interface to geometry description
Description of the current configuration of detector geometry.
InfoPtr_t loadInfo(art::Run &run) const
Loads the geometry information from the run (either directly or legacy).