MVAWriter.h
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////
2 // \version
3 //
4 // \brief Wrapper for saving MVA results into art::Event
5 //
6 // \author robert.sulej@cern.ch
7 //
8 //////////////////////////////////////////////////////////////////////////////
9 #ifndef ANAB_MVAWRITER_H
10 #define ANAB_MVAWRITER_H
11 
15 
17 
18 namespace anab {
19 
20 /// Index to the MVA output / FeatureVector collection, used when result vectors are added or set.
21 typedef size_t FVector_ID;
22 typedef size_t MVAOutput_ID;
23 
24 template <size_t N>
26 public:
27 
28  /// Name provided to the constructor is used as an instance name for FVecDescription<N>
29  /// and FeatureVector<N> (for which it is combined with the processed data product names).
30  /// The name is used as an instance name for the FVecDescription data product
31  /// which lets you to save multiple vector collections from a single art module.
32  FVectorWriter(art::ProducesCollector& collector, const char* name = "") :
33  fCollector(collector), fInstanceName(name),
35  fDescriptions(nullptr)
36  { }
37 
38  /// Register the collection of metadata type FVecDescription<N> (once for all data types
39  /// for which vectors are saved) and the collection of FeatureVectors<N> (using data type name
40  /// added to fInstanceName as instance name of the collection made for the type T).
41  template <class T>
42  void produces_using();
43 
44  /// Initialize container for FeatureVectors and, if not yet done, the container for
45  /// metadata, then creates metadata for data products of type T. FeatureVector container
46  /// is initialized to hold dataSize vectors (if dataSize > 0): use setOutput() to
47  /// store values.
48  /// Returns index of collection which should be used when saving actual output values.
49  template <class T>
50  FVector_ID initOutputs(std::string const & dataTag, size_t dataSize,
51  std::vector< std::string > const & names = std::vector< std::string >(N, ""));
52 
53  template <class T>
54  FVector_ID initOutputs(art::InputTag const & dataTag, size_t dataSize,
55  std::vector< std::string > const & names = std::vector< std::string >(N, ""))
56  { return initOutputs<T>(dataTag.encode(), dataSize, names); }
57 
58  void setVector(FVector_ID id, size_t key, std::array<float, N> const & values) { (*(fVectors[id]))[key] = values; }
59  void setVector(FVector_ID id, size_t key, std::array<double, N> const & values) { (*(fVectors[id]))[key] = values; }
60  void setVector(FVector_ID id, size_t key, std::vector<float> const & values) { (*(fVectors[id]))[key] = values; }
61  void setVector(FVector_ID id, size_t key, std::vector<double> const & values) { (*(fVectors[id]))[key] = values; }
62 
63 
64  /// Initialize container for FeatureVectors and, if not yet done, the container for
65  /// metadata, then creates metadata for data products of type T. FeatureVector container
66  /// is initialized as EMPTY and vectors should be added with addOutput() function.
67  /// Returns index of collection which should be used when adding actual output values.
68  template <class T>
69  FVector_ID initOutputs(art::InputTag const & dataTag,
70  std::vector< std::string > const & names = std::vector< std::string >(N, ""))
71  { return initOutputs<T>(dataTag.encode(), 0, names); }
72 
73  template <class T>
74  FVector_ID initOutputs(
75  std::vector< std::string > const & names = std::vector< std::string >(N, ""))
76  { return initOutputs<T>(std::string(""), 0, names); }
77 
78  void addVector(FVector_ID id, std::array<float, N> const & values) { fVectors[id]->emplace_back(values); }
79  void addVector(FVector_ID id, std::array<double, N> const & values) { fVectors[id]->emplace_back(values); }
80  void addVector(FVector_ID id, std::vector<float> const & values) { fVectors[id]->emplace_back(values); }
81  void addVector(FVector_ID id, std::vector<double> const & values) { fVectors[id]->emplace_back(values); }
82 
83  /// Set tag of associated data products in case it was not ready at the initialization time.
84  void setDataTag(FVector_ID id, art::InputTag const & dataTag) { (*fDescriptions)[id].setDataTag(dataTag.encode()); }
85 
86  /// Check consistency and save all the results in the event.
87  void saveOutputs(art::Event & evt);
88 
89  /// Get the number of contained feature vectors.
90  size_t size(FVector_ID id) const { return fVectors[id]->size(); }
91 
92  /// Get the length of a single feature vector.
93  size_t length() const { return N; }
94 
95  /// Get copy of the feature vector for the type T, at index "key".
96  template <class T>
97  std::array<float, N> getVector(size_t key) const
98  {
99  std::array<float, N> vout;
100  auto const & src = ( *(fVectors[getProductID<T>()]) )[key];
101  for (size_t i = 0; i < N; ++i) vout[i] = src[i];
102  return vout;
103  }
104 
105  /// Get copy of the feature vector for the type T, idicated with art::Ptr::key().
106  template <class T>
107  std::array<float, N> getVector(art::Ptr<T> const & item) const
108  {
109  std::array<float, N> vout;
110  auto const & src = ( *(fVectors[getProductID<T>()]) )[item.key()];
111  for (size_t i = 0; i < N; ++i) vout[i] = src[i];
112  return vout;
113  }
114 
115  friend std::ostream& operator<< (std::ostream &o, FVectorWriter const& a)
116  {
117  o << "FVectorWriter for " << a.fInstanceName << ", " << N << " outputs";
118  if (!a.fRegisteredDataTypes.empty())
119  {
120  o << ", ready to write results made for:" << std::endl;
121  for (auto const & n : a.fRegisteredDataTypes) { o << "\t" << n << std::endl; }
122  }
123  else { o << ", nothing registered for writing to the events" << std::endl; }
124  return o;
125  }
126 
127 protected:
128  // Data collected for each event:
129  template <class T> FVector_ID getProductID() const;
130 
131  std::vector< std::unique_ptr< std::vector< anab::FeatureVector<N> > > > fVectors;
132 
133 private:
134  // Data initialized for the module life:
137 
138  std::vector< std::string > fRegisteredDataTypes;
140 
141  std::unordered_map< size_t, FVector_ID > fTypeHashToID;
142 
143  std::unique_ptr< std::vector< anab::FVecDescription<N> > > fDescriptions;
145  {
146  fTypeHashToID.clear(); fVectors.clear();
147  fDescriptions.reset(nullptr);
148  }
149 
150  /// Check if the the writer is configured to write results for data product type name.
151  bool dataTypeRegistered(const std::string & dname) const;
152  /// Check if the containers for results prepared for "tname" data type are ready.
153  bool descriptionExists(const std::string & tname) const;
154 };
155 
156 /// Helper for registering in the art::EDProducer all data products needed for
157 /// N-output MVA results: keep MVADescriptions<N> for all types T in one collection
158 /// while separate instance names are used for the MVA output value collections for
159 /// each type T.
160 /// Use one instance of this class per one MVA model, applied to one or more types.
161 template <size_t N>
162 class MVAWriter : public FVectorWriter<N>, public MVAWrapperBase {
163 public:
164 
165  /// Name provided to the constructor is used as an instance name for MVADescription<N>
166  /// and FeatureVector<N> (for which it is combined with the processed data product names).
167  /// Good idea is to use the name as an indication of what MVA model was used on the data
168  /// (like eg. "emtrack" for outputs from a model distinguishing EM from track-like hits
169  /// and clusters). The name is used as an instance name for the MVADescription data product
170  /// which lets you to save multiple MVA results from a single art module.
171  MVAWriter(art::ProducesCollector& collector, const char* name = "") :
172  FVectorWriter<N>(collector, name)
173  { }
174 
175  void setOutput(FVector_ID id, size_t key, std::array<float, N> const & values) { FVectorWriter<N>::setVector(id, key, values); }
176  void setOutput(FVector_ID id, size_t key, std::array<double, N> const & values) { FVectorWriter<N>::setVector(id, key, values); }
177  void setOutput(FVector_ID id, size_t key, std::vector<float> const & values) { FVectorWriter<N>::setVector(id, key, values); }
178  void setOutput(FVector_ID id, size_t key, std::vector<double> const & values) { FVectorWriter<N>::setVector(id, key, values); }
179 
180  void addOutput(FVector_ID id, std::array<float, N> const & values) { FVectorWriter<N>::addVector(id, values); }
181  void addOutput(FVector_ID id, std::array<double, N> const & values) { FVectorWriter<N>::addVector(id, values); }
182  void addOutput(FVector_ID id, std::vector<float> const & values) { FVectorWriter<N>::addVector(id, values); }
183  void addOutput(FVector_ID id, std::vector<double> const & values) { FVectorWriter<N>::addVector(id, values); }
184 
185 
186  /// Get MVA results accumulated over the vector of items (eg. over hits associated to a cluster).
187  /// NOTE: MVA outputs for these items has to be added to the MVAWriter first!
188  template <class T>
189  std::array<float, N> getOutput(std::vector< art::Ptr<T> > const & items) const
190  { return pAccumulate<T, N>(items, *(FVectorWriter<N>::fVectors[FVectorWriter<N>::template getProductID<T>()])); }
191 
192  /// Get MVA results accumulated with provided weights over the vector of items
193  /// (eg. over clusters associated to a track, weighted by the cluster size; or
194  /// over hits associated to a cluster, weighted by the hit area).
195  /// NOTE: MVA outputs for these items has to be added to the MVAWriter first!
196  template <class T>
197  std::array<float, N> getOutput(std::vector< art::Ptr<T> > const & items,
198  std::vector<float> const & weights) const
199  { return pAccumulate<T, N>(items, weights, *(FVectorWriter<N>::fVectors[FVectorWriter<N>::template getProductID<T>()])); }
200 
201  /// Get MVA results accumulated with provided weighting function over the vector
202  /// of items (eg. over clusters associated to a track, weighted by the cluster size;
203  /// or over hits associated to a cluster, weighted by the hit area).
204  /// NOTE: MVA outputs for these items has to be added to the MVAWriter first!
205  template <class T>
206  std::array<float, N> getOutput(std::vector< art::Ptr<T> > const & items,
207  std::function<float (T const &)> fweight) const
208  { return pAccumulate<T, N>(items, fweight, *(FVectorWriter<N>::fVectors[FVectorWriter<N>::template getProductID<T>()])); }
209 
210  template <class T>
211  std::array<float, N> getOutput(std::vector< art::Ptr<T> > const & items,
212  std::function<float (art::Ptr<T> const &)> fweight) const
213  { return pAccumulate<T, N>(items, fweight, *(FVectorWriter<N>::fVectors[FVectorWriter<N>::template getProductID<T>()])); }
214 
215  /// Get copy of the MVA output vector for the type T, at index "key".
216  template <class T>
217  std::array<float, N> getOutput(size_t key) const { return FVectorWriter<N>::template getVector<T>(key); }
218 
219  /// Get copy of the MVA output vector for the type T, idicated with art::Ptr::key().
220  template <class T>
221  std::array<float, N> getOutput(art::Ptr<T> const & item) const { return FVectorWriter<N>::template getVector<T>(item); }
222 };
223 
224 } // namespace anab
225 
226 
227 //----------------------------------------------------------------------------
228 // FVectorWriter functions.
229 //
230 template <size_t N>
231 template <class T>
233 {
234  auto const & ti = typeid(T);
235  auto search = fTypeHashToID.find(getProductHash(ti));
236  if (search != fTypeHashToID.end()) { return search->second; }
237  else
238  {
239  throw cet::exception("FVectorWriter") << "Feature vectors not initialized for product " << getProductName(ti) << std::endl;
240  }
241 }
242 //----------------------------------------------------------------------------
243 
244 template <size_t N>
246 {
247  for (auto const & s : fRegisteredDataTypes)
248  {
249  if (s == dname) { return true; }
250  }
251  return false;
252 }
253 //----------------------------------------------------------------------------
254 
255 template <size_t N>
256 template <class T>
258 {
259  std::string dataName = getProductName(typeid(T));
260  if (dataTypeRegistered(dataName))
261  {
262  throw cet::exception("FVectorWriter") << "Type " << dataName << "was already registered." << std::endl;
263  }
264 
266  {
267  fCollector.produces< std::vector< anab::FVecDescription<N> > >(fInstanceName);
269  }
270 
271  fCollector.produces< std::vector< anab::FeatureVector<N> > >(fInstanceName + dataName);
272  fRegisteredDataTypes.push_back(dataName);
273 }
274 //----------------------------------------------------------------------------
275 
276 template <size_t N>
278 {
279  if (!fDescriptions) return false;
280 
281  std::string n = fInstanceName + tname;
282  for (auto const & d : *fDescriptions)
283  {
284  if (d.outputInstance() == n) { return true; }
285  }
286  return false;
287 }
288 //----------------------------------------------------------------------------
289 
290 template <size_t N>
291 template <class T>
293  std::string const & dataTag, size_t dataSize,
294  std::vector< std::string > const & names)
295 {
296  size_t dataHash = getProductHash(typeid(T));
297  std::string dataName = getProductName(typeid(T));
298 
299  if (!dataTypeRegistered(dataName))
300  {
301  throw cet::exception("FVectorWriter") << "Type " << dataName << "not registered with produces_using() function." << std::endl;
302  }
303 
304  if (!fDescriptions)
305  {
306  fDescriptions = std::make_unique< std::vector< anab::FVecDescription<N> > >();
307  }
308  else if (descriptionExists(dataName))
309  {
310  throw cet::exception("FVectorWriter") << "FVecDescription<N> already initialized for " << dataName << std::endl;
311  }
312  fDescriptions->emplace_back(dataTag, fInstanceName + dataName, names);
313 
314  fVectors.push_back( std::make_unique< std::vector< anab::FeatureVector<N> > >() );
315  anab::FVector_ID id = fVectors.size() - 1;
316  fTypeHashToID[dataHash] = id;
317 
318  if (dataSize) { fVectors[id]->resize(dataSize, anab::FeatureVector<N>(0.0F)); }
319 
320  return id;
321 }
322 //----------------------------------------------------------------------------
323 
324 template <size_t N>
326 {
327  for (auto const & n : fRegisteredDataTypes)
328  {
329  if (!descriptionExists(n))
330  {
331  throw cet::exception("FVectorWriter") << "No FVecDescription<N> prepared for type " << n << std::endl;
332  }
333  }
334 
335  if (fVectors.size() != fDescriptions->size())
336  {
337  throw cet::exception("FVectorWriter") << "FVecDescription<N> vector length not equal to the number of FeatureVector<N> vectors" << std::endl;
338  }
339 
340  for (size_t i = 0; i < fVectors.size(); ++i)
341  {
342  auto const & outInstName = (*fDescriptions)[i].outputInstance();
343  if ((*fDescriptions)[i].dataTag().empty())
344  {
345  throw cet::exception("FVectorWriter") << "FVecDescription<N> reco data tag not set for " << outInstName << std::endl;
346  }
347  evt.put(std::move(fVectors[i]), outInstName);
348  }
350  clearEventData();
351 }
352 //----------------------------------------------------------------------------
353 
354 #endif //ANAB_MVAREADER
void addVector(FVector_ID id, std::vector< float > const &values)
Definition: MVAWriter.h:80
static QCString name
Definition: declinfo.cpp:673
void setOutput(FVector_ID id, size_t key, std::array< double, N > const &values)
Definition: MVAWriter.h:176
std::array< float, N > getVector(art::Ptr< T > const &item) const
Get copy of the feature vector for the type T, idicated with art::Ptr::key().
Definition: MVAWriter.h:107
std::unordered_map< size_t, FVector_ID > fTypeHashToID
Definition: MVAWriter.h:141
size_t length() const
Get the length of a single feature vector.
Definition: MVAWriter.h:93
std::string string
Definition: nybbler.cc:12
void setVector(FVector_ID id, size_t key, std::vector< double > const &values)
Definition: MVAWriter.h:61
std::array< float, N > getOutput(std::vector< art::Ptr< T > > const &items, std::function< float(art::Ptr< T > const &)> fweight) const
Definition: MVAWriter.h:211
void setOutput(FVector_ID id, size_t key, std::array< float, N > const &values)
Definition: MVAWriter.h:175
size_t size(FVector_ID id) const
Get the number of contained feature vectors.
Definition: MVAWriter.h:90
struct vector vector
std::array< float, N > getOutput(std::vector< art::Ptr< T > > const &items, std::vector< float > const &weights) const
Definition: MVAWriter.h:197
void setVector(FVector_ID id, size_t key, std::array< double, N > const &values)
Definition: MVAWriter.h:59
void setOutput(FVector_ID id, size_t key, std::vector< double > const &values)
Definition: MVAWriter.h:178
bool descriptionExists(const std::string &tname) const
Check if the containers for results prepared for "tname" data type are ready.
Definition: MVAWriter.h:277
size_t FVector_ID
Index to the MVA output / FeatureVector collection, used when result vectors are added or set...
Definition: MVAWriter.h:21
std::string encode() const
Definition: InputTag.cc:97
std::string getProductName(std::type_info const &ti) const
FVector_ID initOutputs(std::vector< std::string > const &names=std::vector< std::string >(N,""))
Definition: MVAWriter.h:74
void addVector(FVector_ID id, std::array< float, N > const &values)
Definition: MVAWriter.h:78
MVAWriter(art::ProducesCollector &collector, const char *name="")
Definition: MVAWriter.h:171
void addVector(FVector_ID id, std::vector< double > const &values)
Definition: MVAWriter.h:81
std::array< float, N > getVector(size_t key) const
Get copy of the feature vector for the type T, at index "key".
Definition: MVAWriter.h:97
FVector_ID initOutputs(art::InputTag const &dataTag, size_t dataSize, std::vector< std::string > const &names=std::vector< std::string >(N,""))
Definition: MVAWriter.h:54
size_t MVAOutput_ID
Definition: MVAWriter.h:22
FVector_ID initOutputs(std::string const &dataTag, size_t dataSize, std::vector< std::string > const &names=std::vector< std::string >(N,""))
void produces(std::string const &instanceName={}, Persistable const persistable=Persistable::Yes)
Helper functions for MVAReader and MVAWriter wrappers.
art::ProducesCollector & fCollector
Definition: MVAWriter.h:135
def key(type, name=None)
Definition: graph.py:13
void addOutput(FVector_ID id, std::array< double, N > const &values)
Definition: MVAWriter.h:181
std::void_t< T > n
const double a
def move(depos, offset)
Definition: depos.py:107
key_type key() const noexcept
Definition: Ptr.h:216
std::array< float, N > getOutput(art::Ptr< T > const &item) const
Get copy of the MVA output vector for the type T, idicated with art::Ptr::key().
Definition: MVAWriter.h:221
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
void addOutput(FVector_ID id, std::vector< double > const &values)
Definition: MVAWriter.h:183
std::unique_ptr< std::vector< anab::FVecDescription< N > > > fDescriptions
Definition: MVAWriter.h:143
Definition: search.py:1
Q_UINT16 values[128]
std::array< float, N > getOutput(std::vector< art::Ptr< T > > const &items) const
Definition: MVAWriter.h:189
void saveOutputs(art::Event &evt)
Check consistency and save all the results in the event.
Definition: MVAWriter.h:325
std::array< float, N > getOutput(std::vector< art::Ptr< T > > const &items, std::function< float(T const &)> fweight) const
Definition: MVAWriter.h:206
void addOutput(FVector_ID id, std::array< float, N > const &values)
Definition: MVAWriter.h:180
Helper functions for MVAReader/Writer and FVecReader/Writer wrappers.
FVector_ID getProductID() const
std::vector< std::string > fRegisteredDataTypes
Definition: MVAWriter.h:138
bool fIsDescriptionRegistered
Definition: MVAWriter.h:139
FVector_ID initOutputs(art::InputTag const &dataTag, std::vector< std::string > const &names=std::vector< std::string >(N,""))
Definition: MVAWriter.h:69
void setVector(FVector_ID id, size_t key, std::array< float, N > const &values)
Definition: MVAWriter.h:58
std::vector< std::unique_ptr< std::vector< anab::FeatureVector< N > > > > fVectors
Definition: MVAWriter.h:131
void setOutput(FVector_ID id, size_t key, std::vector< float > const &values)
Definition: MVAWriter.h:177
bool dataTypeRegistered(const std::string &dname) const
Check if the the writer is configured to write results for data product type name.
Definition: MVAWriter.h:245
void setDataTag(FVector_ID id, art::InputTag const &dataTag)
Set tag of associated data products in case it was not ready at the initialization time...
Definition: MVAWriter.h:84
std::string fInstanceName
Definition: MVAWriter.h:136
std::array< float, N > getOutput(size_t key) const
Get copy of the MVA output vector for the type T, at index "key".
Definition: MVAWriter.h:217
void setVector(FVector_ID id, size_t key, std::vector< float > const &values)
Definition: MVAWriter.h:60
TCEvent evt
Definition: DataStructs.cxx:7
size_t getProductHash(std::type_info const &ti) const
static std::vector< std::string > const names
Definition: FragmentType.hh:8
void addOutput(FVector_ID id, std::vector< float > const &values)
Definition: MVAWriter.h:182
void function(int client, int *resource, int parblock, int *test, int p)
FVectorWriter(art::ProducesCollector &collector, const char *name="")
Definition: MVAWriter.h:32
void addVector(FVector_ID id, std::array< double, N > const &values)
Definition: MVAWriter.h:79
Definition: fwd.h:31
static QCString * s
Definition: config.cpp:1042
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:97
QTextStream & endl(QTextStream &s)
friend std::ostream & operator<<(std::ostream &o, FVectorWriter const &a)
Definition: MVAWriter.h:115