All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OpDetVisibilityData.h
Go to the documentation of this file.
1 /**
2  * @file larsim/PhotonPropagation/LibraryMappingTools/OpDetVisibilityData.h
3  * @brief Data container for use with photon visibility libraries.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date March 29, 2019
6  *
7  * This is a header-only library.
8  *
9  */
10 
11 #ifndef LARSIM_PHOTONPROPAGATION_LIBRARYMAPPINGTOOLS_OPDETVISIBILITYDATA_H
12 #define LARSIM_PHOTONPROPAGATION_LIBRARYMAPPINGTOOLS_OPDETVISIBILITYDATA_H
13 
14 // LArSoft libraries
16 
17 // C++ standard libraries
18 #include <iterator> // std::size()
19 #include <utility> // std::forward()
20 #include <type_traits> // std::enable_if_t<>
21 
22 
23 namespace phot {
24 
25  /**
26  * @brief Trait for determining the validity of library data in a container.
27  * @tparam Cont type of container being tested
28  * @tparam Enable dummy type for `std::enable_if_t` hooks
29  *
30  * This class is expected to be specialized to provide specific behavior for
31  * custom classes.
32  * The required interface consists of the single static method:
33  * * `static bool isValid(Cont const&)` returning whether `cont` is valid
34  *
35  *
36  * For example:
37  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
38  * template <typename T, std::size_t N>
39  * struct MyArray;
40  *
41  * template <typename T, std::size_t N>
42  * struct LibraryDataValidatorStruct<MyArray<T, N>, void> {
43  * static bool isValid(Cont const&) { return N > 0U; }
44  * };
45  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46  * or
47  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
48  * template <typename T>
49  * struct MyVector;
50  *
51  * template <typename T>
52  * struct LibraryDataValidatorStruct
53  * <T, std::enable_if_t<util::is_instance_of<MyVector, T>>>
54  * {
55  * static bool isValid(Cont const& cont) { return !cont.isInvalid(); }
56  * };
57  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
58  */
59  template <typename Cont, typename Enable = void>
61 
62 
63  /**
64  * @brief Returns the validity of content of library data in the container.
65  * @tparam Cont type of the container being tested
66  * @param cont a reference to the container being tested
67  * @return whether the content of library data in `cont` is valid.
68  *
69  * Customization of this behaviour should be through specialization of
70  * `phot::LibraryDataValidatorStruct`.
71  *
72  */
73  template <typename Cont>
74  bool isValidLibraryData(Cont&& cont);
75 
76 
77  /**
78  * @brief A container for photon visibility mapping data.
79  *
80  * This container is designed to replace the use of plain pointers to library
81  * data, adding an intermediate mapping layer.
82  *
83  * A proper mapping allows to use symmetries of the detector to reduce the
84  * redundant size of the library, at the cost of some run time.
85  *
86  * This container is used as a `util::MappedContainer` object, with the
87  * addition of being aware of whether the contained data is valid or not.
88  * The validity is estimated by considering the original data that is being
89  * mapped, that is the data from the library. If the data is invalid or empty,
90  * as it may be for a null pointer or an empty vector, the container data is
91  * also considered to be invalid.
92  *
93  *
94  * Implementation notes
95  * ---------------------
96  *
97  * In the current implementation, the concept of data being invalid is
98  * implemented by forcing the nominal size of the container to be zero.
99  *
100  *
101  * Known limitations
102  * ------------------
103  *
104  * Currently the mapping of the optical detectors is forced to be a static
105  * collection of detector IDs. If more flexibility is needed, the design of
106  * the container internals need to be updated to allow run time polymorphism.
107  *
108  * Given the type of validity detection described above, it takes extra steps
109  * to provide a default mapping for areas not covered by the library. While
110  * with plain `util::MappedContainer` that can be achieved by a empty data
111  * container and a mapping returning `InvalidIndex` for all optical detectors,
112  * here this would just yield to an invalid container. Instead, together with
113  * that mapping, some fake data needs to be supplied to
114  * `phot::OpDetVisibilityData`, which will be basically ignored and may be of
115  * any size larger than zero (or more precisely,
116  * `phot::isValidLibraryData()` must return `false`).
117  *
118  */
119  template <typename Cont, typename Mapping>
121  : public util::MappedContainer<Cont, Mapping>
122  {
124 
125  public:
126 
127  // import types from base class
128  using typename ContainerBase_t::DataContainer_t;
129  using typename ContainerBase_t::Mapping_t;
130  using typename ContainerBase_t::size_type;
131  using typename ContainerBase_t::value_type;
132 
133  private:
134 
135  /// Determines whether the current content should be considered valid.
136  static size_type effectiveSize
137  (DataContainer_t const& cont, size_type allegedSize);
138 
139  /// Determines whether the current content should be considered valid.
140  static size_type effectiveSize
141  (DataContainer_t const& cont, Mapping_t const& mapping);
142 
143  public:
144 
145 
146  // --- BEGIN Constructors --------------------------------------------------
147 
148  /// @name Validity information
149  /// @{
150  /// Default constructor: data will be invalid.
151  OpDetVisibilityData() = default;
152 
153  /**
154  * @brief Constructor: acquires data, mapping and a default value.
155  * @param cont container with the data to be mapped
156  * @param mapping the mapping to be used
157  * @param size the size of the container after mapping
158  * @param defValue value to be used as default
159  * @see `MappedContainer(DataContainer_t const&, Mapping_t const&, size_type, value_type)`
160  *
161  * This works as the equivalent `util::MappedContainer` constructor, except
162  * that if the data in `cont` is deemed invalid the size is overridden to
163  * zero.
164  */
166  DataContainer_t const& cont,
167  Mapping_t const& mapping,
168  size_type size,
169  value_type defValue
170  )
171  : ContainerBase_t(cont, mapping, effectiveSize(cont, size), defValue)
172  {}
173 
174  /**
175  * @brief Constructor: acquires data and mapping.
176  * @param cont container with the data to be mapped
177  * @param mapping the mapping to be used
178  * @param size the size of the container after mapping
179  * @see `MappedContainer(DataContainer_t const&, Mapping_t const&, size_type)`
180  *
181  * This works as the equivalent `util::MappedContainer` constructor, except
182  * that if the data in `cont` is deemed invalid the size is overridden to
183  * zero.
184  */
186  (DataContainer_t const& cont, Mapping_t const& mapping, size_type size)
187  : ContainerBase_t(cont, mapping, effectiveSize(cont, size))
188  {}
189 
190  /**
191  * @brief Constructor: acquires data and mapping.
192  * @param cont container with the data to be mapped
193  * @param mapping the mapping to be used
194  * @see `util::MappedContainer(DataContainer_t const&, Mapping_t const&, size_type)`
195  *
196  * The size of the container is declared to be the minimal one
197  * (see `minimal_size()`), unless data of the library `cont` is invalid,
198  * in which case the full container is invalid.
199  *
200  * The default value is assigned as in
201  * `util::MappedContainer(DataContainer_t const&, Mapping_t const&, size_type)`.
202  */
203  OpDetVisibilityData(DataContainer_t const& cont, Mapping_t const& mapping)
204  : ContainerBase_t(cont, mapping, effectiveSize(cont, mapping))
205  {}
206 
207 
208  // --- END Constructors ----------------------------------------------------
209 
210 
211  // --- BEGIN Validity information ------------------------------------------
212  /// @name Validity information
213  /// @{
214 
215  /// Returns whether the contained data is valid or not.
216  bool isValid() const { return !ContainerBase_t::empty(); }
217 
218  /// Returns whether the container has valid data.
219  operator bool() const { return isValid(); }
220 
221  /// Returns whether the container has no valid data.
222  bool operator!() const { return !isValid(); }
223 
224  /// @}
225  // --- END Validity information --------------------------------------------
226 
227 
228  }; // OpDetVisibilityData
229 
230 
231 } // namespace phot
232 
233 
234 //------------------------------------------------------------------------------
235 //--- template implementation
236 //------------------------------------------------------------------------------
237 
238 namespace phot {
239 
240  namespace details {
241 
242  //--------------------------------------------------------------------------
243  template <typename Cont>
244  auto generic_size(Cont&& cont)
245  { using std::size; return size(std::forward<Cont>(cont)); }
246 
247 
248  //--------------------------------------------------------------------------
249  // layered implementation of `LibraryDataValidatorStructStandardImpl`:
250 
251  // This is the last layer: if compiler points here,
252  // the type `Cont` is not being supported yet:
253  // - std::size() (or better, `generic_size()`)
254  template <typename Cont, typename = void>
256 
257  template <typename Cont>
259  <Cont, std::enable_if_t<util::always_true_v<decltype(
260  generic_size(std::declval<Cont>())
261  )>>
262  >
263  {
264  static bool isValid(Cont const& cont) { return generic_size(cont) > 0U; }
265  }; // struct LibraryDataValidatorStructStandardImpl_size
266 
267 
268  // - Cont::empty()
269  template <typename Cont, typename = void>
272  {};
273 
274  template <typename Cont>
276  <Cont, std::enable_if_t<util::always_true_v<decltype(
277  std::declval<Cont const>().empty()
278  )>>
279  >
280  {
281  static bool isValid(Cont const& cont) { return !cont.empty(); }
282  }; // struct LibraryDataValidatorStructStandardImpl_empty
283 
284 
285  // - Cont::is_valid()
286  template <typename Cont, typename = void>
289  {};
290 
291  template <typename Cont>
293  <Cont, std::enable_if_t<util::always_true_v<decltype(
294  std::declval<Cont const>().is_valid()
295  )>>
296  >
297  {
298  static bool isValid(Cont const& cont) { return cont.is_valid(); }
299  }; // struct LibraryDataValidatorStructStandardImpl_is_valid
300 
301 
302  // - Cont::isValid()
303  template <typename Cont, typename = void>
306  {};
307 
308  template <typename Cont>
310  <Cont, std::enable_if_t<util::always_true_v<decltype(
311  std::declval<Cont const>().isValid()
312  )>>
313  >
314  {
315  static bool isValid(Cont const& cont) { return cont.isValid(); }
316  }; // struct LibraryDataValidatorStructStandardImpl_isValid
317 
318 
319  // - std::unique_ptr<> (using `enable_if` to catch all qualifiers)
320  template <typename Cont, typename = void>
323  {};
324 
325  template <typename Cont>
327  <Cont, std::enable_if_t<util::is_unique_ptr_v<Cont>>>
328  {
329  static bool isValid(Cont const& cont) { return bool(cont); }
330  }; // struct LibraryDataValidatorStructStandardImpl_unique_ptr
331 
332 
333  // C pointer types:
334  template <typename T>
336 
337  // - T*
338  template <typename T>
340  { static bool isValid(T* ptr) { return bool(ptr); } };
341 
342  // - T[]
343  template <typename T>
346 
347  // - T[N]
348  template <typename T, std::size_t N>
350  { static bool isValid(T (&) [N]) { return N > 0U; } };
351 
352  // - entry point
353  template <typename Cont, typename = void>
356  {};
357 
358  template <typename Cont>
360  <Cont, std::enable_if_t<std::is_pointer_v<std::decay_t<Cont>>>>
362  <std::decay_t<Cont>>
363  {};
364 
365 
366  // - entry point
367  template <typename Cont>
370  {};
371 
372 
373  //--------------------------------------------------------------------------
374 
375  } // namespace details
376 
377 
378  //----------------------------------------------------------------------------
379  // we pick a standard implementation of our own, and let users add here
380  template <typename Cont, typename /* = void */>
383  <std::remove_reference_t<Cont>>
384  {};
385 
386 
387  //----------------------------------------------------------------------------
388  template <typename Cont>
389  bool isValidLibraryData(Cont&& cont) {
390  return
392  } // isValidLibraryData()
393 
394 
395  //----------------------------------------------------------------------------
396  template <typename Cont, typename Mapping>
398  (DataContainer_t const& cont, size_type allegedSize) -> size_type
399  { return isValidLibraryData(cont)? allegedSize: 0U; }
400 
401 
402  template <typename Cont, typename Mapping>
404  (DataContainer_t const& cont, Mapping_t const& mapping) -> size_type
405  {
406  return isValidLibraryData(cont)
407  ? ContainerBase_t::minimal_size(cont, mapping)
408  : 0U
409  ;
410  } // OpDetVisibilityData::effectiveSize(DataContainer_t, Mapping_t)
411 
412 
413  //----------------------------------------------------------------------------
414 
415 } // namespace phot
416 
417 
418 #endif // LARSIM_PHOTONPROPAGATION_LIBRARYMAPPINGTOOLS_OPDETVISIBILITYDATA_H
Provides MappedContainer class.
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
Definition: UtilFunc.cxx:42
auto generic_size(Cont &&cont)
A meta-container providing transparent mapping on top of another.
Mapping Mapping_t
Type of the mapping object.
OpDetVisibilityData(DataContainer_t const &cont, Mapping_t const &mapping)
Constructor: acquires data and mapping.
static constexpr bool
std::size_t size(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:561
OpDetVisibilityData(DataContainer_t const &cont, Mapping_t const &mapping, size_type size, value_type defValue)
Constructor: acquires data, mapping and a default value.
util::MappedContainer< Cont, Mapping > ContainerBase_t
static size_type effectiveSize(DataContainer_t const &cont, size_type allegedSize)
Determines whether the current content should be considered valid.
bool operator!() const
Returns whether the container has no valid data.
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:2191
Cont DataContainer_t
Type of the original container.
bool isValidLibraryData(Cont &&cont)
Returns the validity of content of library data in the container.
A container for photon visibility mapping data.
bool isValid() const
Returns whether the contained data is valid or not.
process_name largeant stream1 can override from command line with o or output physics producers generator N
bool empty() const
Returns whether the container has no elements.
Trait for determining the validity of library data in a container.