SiPMArray.cc
Go to the documentation of this file.
1 #include <mdet/SiPMArray.h>
2 
3 #include <mdet/SiPM.h>
4 #include <mdet/MHierarchyInfo.h>
5 //
6 #include <utl/ErrorLogger.h>
7 #include <utl/RandomEngine.h>
8 //
9 #include <fwk/RandomEngineRegistry.h>
10 //
11 #include <CLHEP/Random/RandFlat.h>
12 //
13 #include <cmath>
14 #include <algorithm>
15 #include <numeric>
16 #include <sstream>
17 //
18 #include <boost/algorithm/minmax_element.hpp>
19 #include <boost/lambda/lambda.hpp>
20 
21 namespace { // unnamed namespace with local helper stuff.
34  struct SiPMEq
35  {
36  SiPMEq(const mdet::SiPM& p) : fSiPM(p)
37  { }
42  bool operator()(const mdet::SiPM* const o) const {
43  /*
44  * Same object (equal addresses).
45  * Here we're relying on the fact that there
46  * isn't a subverted overload for operator&
47  * among SiPMs and then that we're calling the
48  * built-in one which gives the object-address.
49  *
50  * Boost's utility AddressOf could have been used
51  * but it seems that using them would have been too
52  * fancy more than a real concern: don't overload
53  * operator&, please (at least for a mdet::SiPM).
54  */
55  if (o == &fSiPM)
56  return true;
57  // Id has to be equal
58  return o->GetId() == fSiPM.GetId() &&
59  // and then also within the hierarchy.
60  o->GetIdsMap() == fSiPM.GetIdsMap();
61  }
62  const mdet::SiPM& fSiPM;
63  };
64 
65 }
66 
67 namespace mdet {
68 
69  const char* const
71 
72  const char* const
74 
75 
76  SiPMArray::SiPMGroup::SizeType
78  const
79  {
80  SiPMGroup::SizeType tot = fSiPMs.GetNumberOfComponents();
81  // Work with square SiPMArrays.
82  // To the able to work with rectangular one another datum is needed in the config,
83  // for instance the number of rows.
84  SiPMGroup::SizeType root = static_cast<SiPMGroup::SizeType>(std::sqrt(double(tot)));
85  if (tot != root*root) {
86  std::ostringstream ss;
87  ss << "The total number of SiPMs is not a perfect square number in ";
88  AddIdMessage(ss);
89  ss << ".";
90  ERROR(ss);
91  }
92  return root;
93  }
94 
95  SiPMArray::SiPMGroup::SizeType
97  const
98  {
99  SiPMGroup::SizeType tot = fSiPMs.GetNumberOfComponents();
100  return tot / GetRows();
101  }
102 
103  const Module&
105  const
106  {
107  return fModule;
108  }
109 
111  (int pId, const det::VManager::IndexMap& parentMap, const Module& parent) :
112  MDetectorComponent<SiPMArray>::Type(pId, parentMap),
113  fSiPMs(*this),
114  fModule(parent)
115  {
116  fSiPMs.Update(GetIdsMap());
117  InitSiPMs();
118  }
119 
120  void
122  {
123  if (fSiPMs.GetNumberOfComponents()) {
124  // Take the minimun element to make everything relative to this id.
125  /*
126  * Something like this can't be done cause the iterators doesn't model
127  * asignable concept.
128  *
129  * std::min_element(SiPMsBegin(), SiPMsEnd(),
130  * boost::bind(&SiPM::GetId, _1) < boost::bind(&SiPM::GetId, _2))->GetId()
131  *./det/ComponentGroup.h:108: error: non-static reference member
132  * 'const det::ComponentGroup<mdet::SiPMArray, mdet::SiPM, det::ParentCreator,
133  * mdet::MManagerProvider>&
134  * det::ComponentGroup<mdet::SiPMArray, mdet::SiPM, det::ParentCreator, mdet::MManagerProvider>
135  * ::InternalConstFunctor::fContainer', can't use default assignment operator
136  */
137  { // scope this!
140  // It's know that there's one at least.
141  fFirstIdSiPMArray = i->GetId(); // Note that we're initializing the member variable.
142  for (++i; i != e; ++i)
143  fFirstIdSiPMArray = std::min(fFirstIdSiPMArray, i->GetId());
144  }
145  // The code inside asumes at least one: it initializes neighbors;
146  // which don't exist if there's only one.
147  if (fSiPMs.GetNumberOfComponents() > 1) {
148 
149  // To accumulate the ids to check'em.
150  std::vector<int> check;
151  // Preallocation.
152  check.reserve(fSiPMs.GetNumberOfComponents());
153  // Create a vector to Check Consecutiveness
154  for (SiPMIterator i = fSiPMs.Begin(); i != fSiPMs.End(); ++i) {
155  const int id = i->GetId();
156  check.push_back(id);
157 
158  } // End loop over SiPMs.
159  //
160  // Check Consecutiveness.
161  //
162  // It's likely that it will be already sorted
163  // (DetectorComponent sorts while retreiving data)
164  // but ensure that it's needed.
165  //
166  // It's known that there's one element at least.
167  bool sorted = std::adjacent_find(check.begin(), check.end(),
168  boost::lambda::_1 > boost::lambda::_2) == check.end();
169  if (! sorted)
170  std::sort(check.begin(), check.end());
171  // Take the difference between all elements & overwrite the vector.
172  std::adjacent_difference(check.begin(), check.end(), check.begin());
173  // Remember that the first element is kept the same, so ignore it: that's why the + 1.
174  // Now take the min & max: should be one if there's consecutiveness.
175  typedef std::vector<int>::const_iterator It;
176  std::pair< It, It > mm = boost::minmax_element(check.begin() + 1, check.end());
177  if (*mm.first != 1 || *mm.second != 1) {
178  std::ostringstream ss;
179  ss << "There is no consecutiveness in the SiPMs of SiPMArray ";
180  AddIdMessage(ss);
181  ss << ".";
182  FATAL(ss);
183  }
184  }
185  }
186  }
187 
188 
189 
190  void
191  SiPMArray::Update(bool invalidateData, bool invalidateComponents)
192  {
193  MDetectorComponent<SiPMArray>::Type::Update(invalidateData, invalidateComponents);
194  fSiPMs.Update(GetIdsMap(), invalidateData, invalidateComponents);
195  // After update SiPMs, we may re-init them; if no component invalidation then
196  // we skip this part which initializes fFirstIdSiPMArray (which won't change if no
197  // component invalidation is performed).
198  if (invalidateComponents)
199  InitSiPMs();
200  }
201 
202 }
SiPMConstIterator SiPMsBegin() const
Begin iterator over the contained sipms.
Definition: SiPMArray.h:59
void InitSiPMs()
Initilization and validations related to sipms.
Definition: SiPMArray.cc:121
constexpr double mm
Definition: AugerUnits.h:113
SiPMGroup fSiPMs
Definition: SiPMArray.h:115
SiPMGroup::SizeType GetRows() const
Retrieves the number of rows.
Definition: SiPMArray.cc:77
static const char *const kComponentsNames[13]
det::DetectorComponent< C, MManagerProvider > Type
Type specializing det::DetectorComponent for Muon hierarchy.
void Update(std::vector< double > &init, const std::vector< double > &res)
Definition: Util.h:100
SiPMConstIterator SiPMsEnd() const
End iterator over the contained sipms.
Definition: SiPMArray.h:65
static const char *const kComponentsIds[13]
#define FATAL(message)
Macro for logging fatal messages.
Definition: ErrorLogger.h:167
static const char *const kComponentName
Definition: SiPMArray.h:52
const VManager::IndexMap & GetIdsMap() const
The id identifying this component within its detector hierarhy.
const Module & GetModule() const
Definition: SiPMArray.cc:104
Array of Scintillator.
SiPMGroup::SizeType GetCols() const
Retrieves the number of columns.
Definition: SiPMArray.cc:96
SiPMGroup::ConstIterator SiPMConstIterator
Definition: SiPMArray.h:50
SiPMGroup::Iterator SiPMIterator
Non-const private alias.
Definition: SiPMArray.h:47
SiPMArray(int pId, const det::VManager::IndexMap &parentMap, const Module &parent)
Definition: SiPMArray.cc:111
std::map< std::string, std::string > IndexMap
Definition: VManager.h:133
static const char *const kComponentId
Definition: SiPMArray.h:54
void Update(bool invalidateData, bool invalidateComponents)
Perform update in this component and forward to subcomponents.
Definition: SiPMArray.cc:191
const Module & fModule
Definition: SiPMArray.h:117
int fFirstIdSiPMArray
Minimum id among SiPM Array ids.
Definition: SiPMArray.h:121
int GetId() const
The id of this component.
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165

, generated on Tue Sep 26 2023.