All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ICARUSPhotonMappingTransformations.h
Go to the documentation of this file.
1 /**
2  * @file icaruscode/PMT/LibraryMappingTools/ICARUSPhotonMappingTransformations.h
3  * @brief Photon library mapping for ICARUS geometry.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date April 3, 2019
6  * @see `icaruscode/PMT/LibraryMappingTools/ICARUSPhotonMappingTransformations_tool.cc`
7  *
8  */
9 
10 #ifndef ICARUSCODE_LIGHT_LIBRARYMAPPINGTOOLS_ICARUSPHOTONMAPPINGTRANSFORMATIONS_H
11 #define ICARUSCODE_LIGHT_LIBRARYMAPPINGTOOLS_ICARUSPHOTONMAPPINGTRANSFORMATIONS_H
12 
13 // LArSoft libraries
16 #include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom()
18 #include "larcoreobj/SimpleTypesAndConstants/geo_vectors.h" // geo::Vector_t
19 
20 // framework libraries
21 #include "art/Utilities/ToolConfigTable.h"
22 #include "fhiclcpp/types/OptionalSequence.h"
23 #include "fhiclcpp/types/Atom.h"
24 
25 // C/C++ standard libraries
26 #include <vector>
27 
28 
29 namespace phot {
30 
31  /**
32  * @brief Photon library mapping for ICARUS geometry.
33  *
34  * This is an implementation of `phot::IPhotonMappingTransformation` interface
35  * to exploit ICARUS detector symmetries.
36  *
37  * The current implementation only exploits the fact that the two cryostats
38  * are identical, and ignores the symmetry respect to the cathode within each
39  * of the cryostats.
40  *
41  * The required library is expected to cover the first 180 PMT channels (the
42  * ones pertaining the first cryostat, `C:0`), and the full volume of the TPC.
43  *
44  * When requested a point in the first cryostat (`C:0`), the point is used
45  * directly in the visibility library to get visibility on PMT channels 0 to
46  * 179 (the lower half). The mapping then maps the remaining PMT channels
47  * (180 to 359) to be invalid and with default value of `0`.
48  *
49  * When requested a point in the other cryostat (`C:1`), the point is
50  * translated into the first one to get visibility of PMT channels 0 to 179
51  * (the lower half). The mapping then translates those channels into the range
52  * 180 to 359, and maps the remaining PMT channels (0 to 179) to be invalid
53  * and with default value of `0`.
54  *
55  * Note that the content of the library for channels 180 to 359 is always
56  * ignored, and it may well be absent.
57  */
60  {
61 
62  public:
63  struct Config {
64 
65  using Name = fhicl::Name;
66  using Comment = fhicl::Comment;
67 
68  fhicl::OptionalSequence<OpDetID_t> CryostatChannelRemap {
69  Name("CryostatChannelRemap"),
70  Comment("internal library mapping (new library ID for each old one)")
71  };
72 
73  // no configuration required
74  fhicl::Atom<bool> DumpMapping{
75  Name("DumpMapping"),
76  Comment("dump the mapping into console"),
77  false // default
78  };
79 
80  }; // struct Config
81 
82  using Parameters = art::ToolConfigTable<Config>;
83 
84 
85  /// Constructor.
87 
88  /// Constructor: ignores the configuration.
91  {}
92 
93 
94  // --- BEGIN Geometry mapping interface ------------------------------------
95  /// @name Geometry mapping interface
96  /// @{
97 
98  /**
99  * @brief Returns the representation within the library of a detector
100  * location.
101  * @param location position in world coordinates [cm]
102  * @return a vector expressing `location` in the library space
103  *
104  * The returned vector is shifted as it were on the first cryostat.
105  *
106  * No exception is ever thrown.
107  */
109  (geo::Point_t const& location) const override;
110 
111  /// @}
112  // --- END Geometry mapping interface --------------------------------------
113 
114 
115  // --- BEGIN Optical detector mapping interface ----------------------------
116  /// @name Optical detector mapping interface
117  /// @{
118 
119  /**
120  * @brief Returns the library index for the specified optical detector.
121  * @param location where the scintillation source is in world frame [cm]
122  * @param opDetID optical detector identifier
123  * (as used, e.g., in `geo::GeometryCore::OpDetGeoFromOpDet()`)
124  * @return index corresponding to `opDetID`, or `InvalidLibraryIndex`
125  * @throw std::out_of_range if input optical detector ID can't be handled TODO not implemented this way (yet?)
126  * @see `opDetFromLibrary()`
127  *
128  * The mapping reduces the optical detector ID to the corresponding one in
129  * the first cryostat.
130  */
132  (geo::Point_t const& location, OpDetID_t opDetID) const override
133  { return opDetsToLibraryIndicesImpl(location)[opDetID]; }
134 
135  /**
136  * @brief Returns the optical detector ID for the specified library index.
137  * @param location where the scintillation source is in world frame [cm]
138  * @param libIndex library index to be mapped
139  * @return optical detector corresponding to `libIndex` (as used, e.g., in
140  * `geo::GeometryCore::OpDetGeoFromOpDet()`), or `InvalidOpDetID`
141  * @throw std::out_of_range if input library index can't be handled TODO not implemented this way (yet?)
142  * @see `opDetToLibraryIndex()`, `libraryIndicesToOpDets()`
143  */
145  (geo::Point_t const& location, LibraryIndex_t libIndex) const override
146  { return libraryIndicesToOpDetsImpl(location)[libIndex]; }
147 
148 
149  /**
150  * @brief Returns a map of library indices as function of optical detectors.
151  * @param location where the scintillation source is in world frame [cm]
152  * @return library indices for all optical detectors
153  * @see `opDetToLibraryIndex()`, `opDetsToLibraryIndices()`
154  */
156  (geo::Point_t const& location) const override
157  { return opDetsToLibraryIndicesImpl(location); }
158 
159  /**
160  * @brief Expected number of mappings of optical detector into library
161  * index.
162  * @return the expected size of the mapping of optical detectors
163  * @see `opDetsToLibraryIndices()`
164  *
165  * This is effectively the number of available optical detectors, as well
166  * as the size of the mapping as returned by `opDetsToLibraryIndices()`.
167  */
168  virtual std::size_t opDetMappingSize() const override
169  { return opDetsToLibraryIndicesImpl(geo::origin()).size(); }
170 
171 
172  /**
173  * @brief Returns a map of identifiers of optical detectors for each library
174  * index, for the library appropriate around `location`
175  * @param location where the scintillation source is in world frame [cm]
176  * @return optical detector identifiers for all library indices
177  * @see `opDetsToLibraryIndices()`, `libraryIndexToOpDet()`
178  *
179  * We use this mapping when we have information from the visibility library
180  * appropriate for a source at the specified `location`: this information
181  * is addressed via a "library index" with the reduced range (i.e. 0 to 179)
182  * and we need to know which are the optical detector channels that
183  * visibility covers.
184  *
185  * For ICARUS, this mapping is expected to be straightforward:
186  * * [ 0, 179 ] => [ 0, 179 ] if `location` is in the first cryostat (C:0)
187  * * [ 0, 179 ] => [ 180, 359 ] if `location` is in the other one (C:1)
188  *
189  * The specified `location` is used to provide context in a similar
190  * fashion as `detectorToLibrary()` does. It can be used to choose the
191  * correct mapping among the available ones.
192  *
193  * The returned value is a mapping object (see `LibraryIndexToOpDetMap`
194  * documentation for the interface). If a library index does not map to any
195  * optical detector in the library at `location` (which is unusual!),
196  * the optical detector ID corresponding to it is `InvalidOpDetID`.
197  */
199  (geo::Point_t const& location) const override
200  { return libraryIndicesToOpDetsImpl(location); }
201 
202  /**
203  * @brief Expected size of the mapping from library to optical detectors.
204  * @param location where the scintillation source is in world frame [cm]
205  * @return the expected size of the mapping from library indices to
206  * optical detectors
207  * @see `libraryIndicesToOpDets()`
208  *
209  * This is effectively the size of the mapping returned by
210  * `libraryIndicesToOpDets()`. It represents how many library indices are
211  * provided by the library for the specified `location`, that is `180`.
212  */
213  virtual std::size_t libraryMappingSize
214  (geo::Point_t const& location) const override
215  { return libraryIndicesToOpDets(location).size();}
216 
217 
218  /// @}
219  // --- END Optical detector identifier mapping interface -------------------
220 
221 
222  protected:
223  //
224  // configuration parameters
225  //
226  bool fDumpMapping = false; ///< Whether to dump mapping on initialization.
227 
228  //
229  // tool setup
230  //
231 
232  /// Detector geometry service provider. Not really used.
233  geo::GeometryCore const* fGeom = nullptr;
234 
235 
236  //
237  // for geometry transformation
238  //
239  std::vector<geo::Vector_t> fTranslations; ///< Translation of the point.
240  geo::Length_t fSwitchPoint; ///< Switch coordinate on x axis [cm]
241 
242  //
243  // for optical channel transformation
244  //
245  unsigned int fNOpDetChannels; /// Total number of optical detector channels.
246  /// Amount of channel number shifting indexed by cryostat. Not really used.
247  std::vector<int> fChannelShifts;
248  /// Library to detector channel mappings, indexed by cryostat number.
249  std::vector<LibraryIndexToOpDetMap> fLibraryIndexToOpDetMaps;
250  /// A library-to-detector mapping for invalid points.
252  /// Detector channel to library mappings, indexed by cryostat number.
253  std::vector<OpDetToLibraryIndexMap> fOpDetToLibraryIndexMaps;
254  /// A detector-to-library mapping for invalid points.
256 
257  //
258  // mapping helper functions
259  //
260 
261  /// Returns which cryostat better contain `point`. Never invalid so far.
263  { return geo::CryostatID{ (point.X() > fSwitchPoint)? 1U: 0U }; }
264 
265  //
266  // implementation methods (non-virtual)
267  //
269  (geo::Point_t const& location) const;
270 
272  (geo::Point_t const& location) const;
273 
274 
275  void prepareGeometryMapping();
276  void prepareLibraryMappings(LibraryIndexToOpDetMap const& libraryIndices);
277 
278  /// Extracts the necessary information for mapping from the geometry.
279  void prepareMappings(LibraryIndexToOpDetMap const& libraryIndices);
280 
281  /// Writes the current mapping information into the console. Debug stuff.
282  void dumpMapping() const;
283 
284  /**
285  * @brief Inverts a given mapping.
286  * @tparam OutputIndex the output index of the mapping to invert
287  * @tparam IndexIndex the input index of the mapping to invert
288  * @tparam Container container used for the mapping (be it `std::vector`)
289  * @param directMap the mapping (input index to output index) to be inverted
290  * @param size the total number of output indices (some may be not mapped)
291  * @param invalidIndex input index to associate to unmapped output indices
292  * @return a mapping (output index to input index) reversing `directMap`
293  *
294  * The resulting, "inverse" mapping has exactly `size` entries.
295  * If the input mapping maps out beyond that, those indices are not mapped
296  * back.
297  */
298  template<
299  typename OutputIndex, typename InputIndex,
300  template <typename...> typename Container
301  >
302  static Container<InputIndex> invertMapping(
303  Container<OutputIndex> const& directMap,
304  std::size_t size,
305  InputIndex invalidIndex
306  );
307 
308  }; // class ICARUSPhotonMappingTransformations
309 
310 
311 } // namespace phot
312 
313 
314 //------------------------------------------------------------------------------
315 //--- template implementation
316 //------------------------------------------------------------------------------
317 /**
318  * @brief Inverts a given mapping.
319  * @tparam OutputIndex the output index of the mapping to invert
320  * @tparam IndexIndex the input index of the mapping to invert
321  * @tparam Container type of container used for the mapping (be it `std::vector`)
322  * @param directMap the mapping (input index to output index) to be inverted
323  * @param size the total number of output indices (some may be not mapped)
324  * @param invalidIndex the input index to associate to unmapped output indices
325  * @return a mapping (output index to input index) reversing `directMap`
326  *
327  * The resulting, "inverse" mapping has exactly `size` entries.
328  * If the input mapping maps out beyond that, those indices are not mapped back.
329  */
330 template
331  <typename OutputIndex, typename InputIndex, template <typename...> typename Container>
333  Container<OutputIndex> const& directMap,
334  std::size_t size,
335  InputIndex invalidIndex
336 ) -> Container<InputIndex> {
337 
338  OutputIndex const endOutputIndex = size;
339 
340  Container<InputIndex> inverseMap(size, invalidIndex);
341  for (std::size_t i = 0U; i < directMap.size(); ++i) {
342  OutputIndex o = directMap[i];
343  if (o < endOutputIndex) inverseMap[o] = i;
344  }
345  return inverseMap;
346 }
347 
348 
349 //------------------------------------------------------------------------------
350 
351 
352 #endif // ICARUSCODE_LIGHT_LIBRARYMAPPINGTOOLS_ICARUSPHOTONMAPPINGTRANSFORMATIONS_H
Interface for transformation of photon visibility maps.
virtual geo::Point_t detectorToLibrary(geo::Point_t const &location) const override
Returns the representation within the library of a detector location.
Utilities related to art service access.
std::vector< LibraryIndexToOpDetMap > fLibraryIndexToOpDetMaps
Library to detector channel mappings, indexed by cryostat number.
LibraryIndexToOpDetMap fInvalidLibraryIndexToOpDetMap
A library-to-detector mapping for invalid points.
double Length_t
Type used for coordinates and distances. They are measured in centimeters.
Definition: geo_vectors.h:137
ICARUSPhotonMappingTransformations(Parameters const &config)
Constructor: ignores the configuration.
std::vector< geo::Vector_t > fTranslations
Translation of the point.
std::vector< int > fChannelShifts
Amount of channel number shifting indexed by cryostat. Not really used.
OpDetID_t LibraryIndex_t
Type describing a library index. FIXME former LibraryOpDetID_t.
void dumpMapping() const
Writes the current mapping information into the console. Debug stuff.
std::size_t size(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:561
virtual LibraryIndexToOpDetMap const & libraryIndicesToOpDets(geo::Point_t const &location) const override
Returns a map of identifiers of optical detectors for each library index, for the library appropriate...
bool fDumpMapping
Whether to dump mapping on initialization.
Collection of functions to transform photon mapping data.
OpDetToLibraryIndexMap fInvalidOpDetToLibraryIndexMap
A detector-to-library mapping for invalid points.
Access the description of detector geometry.
virtual std::size_t libraryMappingSize(geo::Point_t const &location) const override
Expected size of the mapping from library to optical detectors.
Definitions of geometry vector data types.
Photon library mapping for ICARUS geometry.
std::vector< OpDetToLibraryIndexMap > fOpDetToLibraryIndexMaps
Detector channel to library mappings, indexed by cryostat number.
geo::Length_t fSwitchPoint
Switch coordinate on x axis [cm].
BEGIN_PROLOG vertical distance to the surface Name
virtual LibraryIndex_t opDetToLibraryIndex(geo::Point_t const &location, OpDetID_t opDetID) const override
Returns the library index for the specified optical detector.
phot::IPhotonMappingTransformations::OpDetID_t OpDetID_t
Type of (global) optical detector ID.
std::vector< OpDetID_t > LibraryIndexToOpDetMap
Type describing the mapping of optical detectors into library indices.
Description of geometry of one entire detector.
void prepareLibraryMappings(LibraryIndexToOpDetMap const &libraryIndices)
geo::GeometryCore const * fGeom
Detector geometry service provider. Not really used.
int OpDetID_t
Type describing a optical detector ID.
virtual std::size_t opDetMappingSize() const override
Expected number of mappings of optical detector into library index.
virtual OpDetToLibraryIndexMap const & opDetsToLibraryIndices(geo::Point_t const &location) const override
Returns a map of library indices as function of optical detectors.
LibraryIndexToOpDetMap const & libraryIndicesToOpDetsImpl(geo::Point_t const &location) const
virtual OpDetID_t libraryIndexToOpDet(geo::Point_t const &location, LibraryIndex_t libIndex) const override
Returns the optical detector ID for the specified library index.
geo::CryostatID whichCryostat(geo::Point_t const &point) const
Returns which cryostat better contain point. Never invalid so far.
ICARUSPhotonMappingTransformations(Config const &config)
Constructor.
void prepareMappings(LibraryIndexToOpDetMap const &libraryIndices)
Extracts the necessary information for mapping from the geometry.
static Container< InputIndex > invertMapping(Container< OutputIndex > const &directMap, std::size_t size, InputIndex invalidIndex)
Inverts a given mapping.
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:184
OpDetToLibraryIndexMap const & opDetsToLibraryIndicesImpl(geo::Point_t const &location) const
art framework interface to geometry description
constexpr Point origin()
Returns a origin position with a point of the specified type.
Definition: geo_vectors.h:227
The data type to uniquely identify a cryostat.
Definition: geo_types.h:190
std::vector< LibraryIndex_t > OpDetToLibraryIndexMap
Type describing the mapping of library indices into optical detectors.