ATLAS Offline Software
Loading...
Searching...
No Matches
RingerDiscriminatorWrapper.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include<iostream>
6#include<string>
7// $Id: RingerDiscriminatorWrapper.icc 791627 2017-01-10 04:45:53Z wsfreund $
8#ifndef RINGERSELECTORTOOLS_PROCEDURES_RINGERDISCRIMINATIONWRAPPER_ICC
9#define RINGERSELECTORTOOLS_PROCEDURES_RINGERDISCRIMINATIONWRAPPER_ICC
10
11#include "RingerDiscriminatorWrapper.h"
12#include "RingerProcedureWrapper.icc"
13
14#include "RingerSelectorTools/procedures/Normalizations.h"
15#include "RingerSelectorTools/procedures/NeuralNetwork.h"
16
17#include <type_traits>
18
19namespace Ringer {
20
21namespace WrapperHelperFcns {
22
23/**
24 * Return the discriminator on dirObj of ppType
25 **/
26inline
27Discrimination::IDiscriminatorVarDep* getDiscr(discrEnum_t discrType,
28 TDirectory *dirObj )
29{
30 using namespace Discrimination;
31 // For the interface case, we will have to create each pre-processing
32 // depending on the information written on ppType:
33 switch ( discrType )
34 {
35 case discrEnum_t::NNFeedForward:
36 {
37 return NNFeedForwardVarDep::read( dirObj );
38 break;
39 }
40 default:
41 {
42 throw std::runtime_error( std::string("Cannot read discriminator of ") +
43 "type: " + toStr(discrType) );
44 }
45 }
46}
47
48inline
49void addExtraDescription( std::vector<float> &input
50 , const DepVarStruct& depVar
51 , const Ringer::PreProcessing::Norm::ExtraPatternsNorm* extraPatNorm
52 , const Ringer::ExtraDescriptionPatterns& extraDescr )
53{
54 if ( extraPatNorm == nullptr ) {
55 throw std::runtime_error( std::string("Attempted to add description with empty norm") );
56 }
57 if( extraDescr.feedEta() ){
58 input.push_back( extraPatNorm->normEta( depVar.eta ) );
59 }
60 if( extraDescr.feedEt() ){
61 input.push_back( extraPatNorm->normEt( depVar.et ) );
62 }
63 if( extraDescr.feedPileupEstimation() ){
64 input.push_back( extraPatNorm->normPileupEstimation( depVar.pileupEstimation ) );
65 }
66}
67} // WrapperHelperFcns
68
69// Import Wrapper Helper functions
70using namespace WrapperHelperFcns;
71
72// =============================================================================
73// -----------------------------------------
74// RingerProcedureWrapper for Discriminators
75// -----------------------------------------
76// =============================================================================
77
78// =============================================================================
79template <
80 class procedure_t,
81 /*EtaDependency*/int etaDependency,
82 /*EtDependency*/int etDependency,
83 /*SegmentationType*/int segType
84>
85void RingerProcedureWrapper<
86 procedure_t,
87 etaDependency,
88 etDependency,
89 segType,
90 false, // isPreProcessor
91 true, // isDiscriminator
92 false> // isThreshold
93::releaseMemory()
94{
95 for ( size_t ppColIdx = 0; ppColIdx < m_ppWrapperCol.size(); ++ppColIdx){
96 if (m_ppWrapperCol[ppColIdx]){
97 m_ppWrapperCol[ppColIdx]->releaseMemory();
98 }
99 }
100 for ( size_t segIdx = 0; segIdx < m_discrCol.size() ; ++segIdx){
101 for ( size_t etIdx = 0; etIdx < m_discrCol[segIdx].size() ; ++etIdx){
102 for ( size_t etaIdx = 0; etaIdx < m_discrCol[segIdx][etIdx].size();
103 ++etaIdx)
104 {
105 delete m_discrCol[segIdx][etIdx][etaIdx];
106 }
107 }
108 }
109 m_discrCol.clear();
110 m_discr = nullptr;
111}
112
113// =============================================================================
114template <
115 class procedure_t,
116 /*EtaDependency*/int etaDependency,
117 /*EtDependency*/int etDependency,
118 /*SegmentationType*/int segType
119>
120void RingerProcedureWrapper<
121 procedure_t,
122 etaDependency,
123 etDependency,
124 segType,
125 false, // isPreProcessor
126 true, // isDiscriminator
127 false> // isThreshold
128::execute(
129 const DepVarStruct &depVar,
130 const xAOD::CaloRings *clrings,
131 const TrackPatternsHolder *trackPat,
132 std::vector<float> &output) const
133{
134#ifndef NDEBUG
135 ATH_MSG_DEBUG("Applying first discrimination layer discriminators.");
136#endif
137
138 // Clear any previous output:
139 output.clear();
140
141 // We will put pre-processing results into this vector:
142 std::vector<float> transformVec;
143
144#ifndef NDEBUG
145 ATH_MSG_DEBUG( "Allocating space on transformVec of size " <<
146 (((clrings)?(m_nRings):0) +
147 ((trackPat)?TrackPatternsHolder::numberOfPatterns():0)));
148#endif
149
150 // We grant it enougth space to handle worst case:
151 transformVec.reserve(
152 (clrings)?(m_nRings):(0 +
153 ((trackPat)?TrackPatternsHolder::numberOfPatterns():0))
154 );
155
156 std::vector<float> input = transformVec;
157
158 if ( m_ppWrapperCol.empty() ) {
159 // Otherwise simply push-back information:
160 if (clrings){
161 clrings->exportRingsTo(transformVec);
162 }
163 if (trackPat){
164 trackPat->exportPatternsTo(transformVec);
165 }
166 } else {
167 // FIXME: This does not work with multiple normalizations, we need to
168 // change this to something where the pre-processor will keep the
169 // segmentation information that it will receive and where should it divide
170 // it.
171
172 // If pre-processing available execute it:
173 for ( size_t ppIdx = 0; ppIdx < m_ppWrapperCol.size(); ++ppIdx ){
174 m_ppWrapperCol[ppIdx]->applyPreProcessing(
175 depVar,
176 clrings,
177 trackPat,
178 transformVec);
179 }
180 }
181
182 // Initialize eta and et indexes:
183 size_t etaIdx(0), etIdx(0);
184 // Get the correct idx to be applied:
185 if (etaDependency) {
186 etaIdx = findEtaBin(depVar.eta, m_discrCol[0]);
187 }
188 if (etDependency) {
189 etIdx = findEtBin(depVar.et, m_discrCol[0]);
190 }
191
192 size_t cDiscr = 0;
193
194 switch(segType){
195 case SegmentationType::NoSegmentation:
196 {
197
198#ifndef NDEBUG
199 ATH_MSG_VERBOSE("Applying NonSegmented"
200 " discriminator at etaIdx (" << etaIdx << ") and etIdx ("
201 << etIdx << ").");
202#endif
203 input = transformVec;
204 if ( static_cast<bool>(m_extraDescriptionPatterns) ) {
205 // Add demanded extra description
206 addExtraDescription( input, depVar, m_extraDescriptionNorms.at(etIdx).at(etaIdx), m_extraDescriptionPatterns );
207 }
208 // Apply discrimination to all transformed space:
209 m_discrCol[cDiscr++][etIdx][etaIdx]->execute(input,output);
210 break;
211 }
212 case SegmentationType::TrackCalSegmentation:
213 {
214#ifndef NDEBUG
215 ATH_MSG_VERBOSE("Applying Track/Cal segmented"
216 " discriminators at etaIdx (" << etaIdx << ") and etIdx ("
217 << etIdx << ").");
218#endif
219 if (clrings){
220 // Apply discrimination to CaloRings as one:
221 getCaloSegmentFromTransformVec( m_nRings,
222 transformVec,
223 input);
224
225 if ( static_cast<bool>(m_extraDescriptionPatterns) ) {
226 // Add demanded extra description
227 addExtraDescription( input, depVar, m_extraDescriptionNorms.at(etIdx).at(etaIdx), m_extraDescriptionPatterns );
228 }
229
230 executeSegmentedDiscr(
231 input,
232 m_discrCol[cDiscr++][etIdx][etaIdx],
233 output);
234 } else {
235 cDiscr += 1;
236 }
237 if (trackPat){
238 // Apply discrimination to Track separated:
239 getTrackSegmentFromTransformVec(
240 // If the CaloRings is available, then we have to increase the
241 // start index to jump all Calorimeter representations:
242 (clrings)?(m_nRings):0,
243 transformVec,
244 input);
245
246 if ( static_cast<bool>(m_extraDescriptionPatterns) ) {
247 // Add demanded extra description
248 addExtraDescription( input, depVar, m_extraDescriptionNorms.at(etIdx).at(etaIdx), m_extraDescriptionPatterns );
249 }
250
251 executeSegmentedDiscr(
252 input,
253 m_discrCol[cDiscr++][etIdx][etaIdx],
254 output);
255 } else {
256 cDiscr += 1;
257 }
258 break;
259 }
260 case SegmentationType::TrackCalPatTypeSegmentation:
261 {
262 // TODO Implement this if it is going to be used:
263 throw std::runtime_error(std::string("There is no implementation method "
264 "for ") + toStr(static_cast<SegmentationType>(segType)) );
265 }
266 case SegmentationType::TrackCalJointSections:
267 {
268#ifndef NDEBUG
269 ATH_MSG_VERBOSE("Applying Track/Cal-JointSections segmented"
270 " discriminators at etaIdx (" << etaIdx << ") and etIdx ("
271 << etIdx << ").");
272#endif
273 if (clrings){
274 // Apply discrimination to each CalJointSection:
275 while ( cDiscr < static_cast<size_t>(
276 CalJointSection::NJointSections) )
277 {
278 getCaloSegmentFromTransformVec(
279 *m_rsRawConfCol,
280 static_cast<CalJointSection>(cDiscr),
281 transformVec,
282 input);
283
284 if ( static_cast<bool>(m_extraDescriptionPatterns) ) {
285 // Add demanded extra description
286 addExtraDescription( input, depVar, m_extraDescriptionNorms.at(etIdx).at(etaIdx), m_extraDescriptionPatterns );
287 }
288
289 executeSegmentedDiscr(
290 input,
291 m_discrCol[cDiscr++][etIdx][etaIdx],
292 output);
293 }
294 } else {
295 cDiscr += static_cast<size_t>(CalJointSection::NJointSections);
296 }
297 if (trackPat) {
298 // Apply discrimination to Track separated:
299 getTrackSegmentFromTransformVec(
300 (clrings)?(m_nRings):0,
301 transformVec,
302 input);
303
304 if ( static_cast<bool>(m_extraDescriptionPatterns) ) {
305 // Add demanded extra description
306 addExtraDescription( input, depVar, m_extraDescriptionNorms.at(etIdx).at(etaIdx), m_extraDescriptionPatterns );
307 }
308
309 executeSegmentedDiscr(
310 input,
311 m_discrCol[cDiscr++][etIdx][etaIdx],
312 output);
313 } else {
314 cDiscr += 1;
315 }
316 break;
317 }
318 case SegmentationType::TrackCalJointLayers:
319 {
320#ifndef NDEBUG
321 ATH_MSG_VERBOSE("Applying Track/Cal-JointLayers segmented"
322 " discriminators at etaIdx (" << etaIdx << ") and etIdx ("
323 << etIdx << ").");
324#endif
325 if (clrings){
326 // Apply discrimination to each CalJointLayer:
327 while ( cDiscr < static_cast<size_t>(
328 CalJointLayer::NJointLayers) )
329 {
330 getCaloSegmentFromTransformVec(
331 *m_rsRawConfCol,
332 static_cast<CalJointLayer>(cDiscr),
333 transformVec,
334 input);
335
336 if ( static_cast<bool>(m_extraDescriptionPatterns) ) {
337 // Add demanded extra description
338 addExtraDescription( input, depVar, m_extraDescriptionNorms.at(etIdx).at(etaIdx), m_extraDescriptionPatterns );
339 }
340
341 executeSegmentedDiscr(
342 input,
343 m_discrCol[cDiscr++][etIdx][etaIdx],
344 output);
345 }
346 } else {
347 cDiscr += static_cast<size_t>(CalJointLayer::NJointLayers);
348 }
349 if (trackPat){
350 // Apply discrimination to Track separated:
351 getTrackSegmentFromTransformVec(
352 (clrings)?(m_nRings):0,
353 transformVec,
354 input);
355
356 if ( static_cast<bool>(m_extraDescriptionPatterns) ) {
357 // Add demanded extra description
358 addExtraDescription( input, depVar, m_extraDescriptionNorms.at(etIdx).at(etaIdx), m_extraDescriptionPatterns );
359 }
360
361 executeSegmentedDiscr(
362 input,
363 m_discrCol[cDiscr++][etIdx][etaIdx],
364 output);
365 } else {
366 cDiscr += 1;
367 }
368 break;
369 }
370 }
371 return;
372}
373
374// =============================================================================
375template <
376 class procedure_t,
377 /*EtaDependency*/int etaDependency,
378 /*EtDependency*/int etDependency,
379 /*SegmentationType*/int segType
380>
381void RingerProcedureWrapper<
382 procedure_t,
383 etaDependency,
384 etDependency,
385 segType,
386 false, // isPreProcessor
387 true, // isDiscriminator
388 false> // isThreshold
389::execute(
390 const DepVarStruct &depVar,
391 const std::vector<float> &input,
392 std::vector<float> &output) const
393{
394#ifndef NDEBUG
395 ATH_MSG_DEBUG("Applying internal discrimination layer discriminators.");
396#endif
397
398 // This method only applies for segType NoSegmentation.
399 ensureNoSegmentationOnlyFcn(static_cast<SegmentationType>(segType));
400
401 // Copy input:
402 std::vector<float> inputCopy = input;
403 // First, execute pp wrapper collection:
404 for ( size_t ppIdx = 0; ppIdx < m_ppWrapperCol.size(); ++ppIdx ){
405 m_ppWrapperCol[ppIdx]->applyPreProcessing(depVar,inputCopy);
406 }
407
408 if (!etaDependency && !etDependency){
409 m_discr->execute(inputCopy,output);
410 return;
411 }
412
413 // Initialize eta and et indexes:
414 size_t etaIdx(0), etIdx(0);
415
416 // Get the correct idx to be applied:
417 if (etaDependency){
418 etaIdx = findEtaBin(depVar.eta, m_discrCol[0]);
419 }
420 if (etDependency){
421 etIdx = findEtBin(depVar.et, m_discrCol[0]);
422 }
423
424 if ( static_cast<bool>(m_extraDescriptionPatterns) ) {
425 // Add demanded extra description
426 addExtraDescription( inputCopy, depVar, m_extraDescriptionNorms.at(etIdx).at(etaIdx), m_extraDescriptionPatterns );
427 }
428
429 // Apply it:
430 m_discrCol[0][etIdx][etaIdx]->execute(inputCopy,output);
431}
432
433// =============================================================================
434template <
435 class procedure_t,
436 /*EtaDependency*/int etaDependency,
437 /*EtDependency*/int etDependency,
438 /*SegmentationType*/int segType
439>
440void RingerProcedureWrapper<
441 procedure_t,
442 etaDependency,
443 etDependency,
444 segType,
445 false, // isPreProcessor
446 true, // isDiscriminator
447 false> // isThreshold
448::checkPPWrapperCol() const {
449 if (m_ppWrapperCol.empty()){
450 throw std::runtime_error(std::string(
451 "Attempted to start Discriminator Wrapper with"
452 " PreProcessing Wrapper collection that is empty.\n"
453 "In this case, do not input PreProcessing"
454 " Wrapper collection in Discriminator"
455 " Wrapper construction."));
456
457 }
458 for ( size_t ppWrapperIdx = 0; ppWrapperIdx < m_ppWrapperCol.size();
459 ++ppWrapperIdx ){
460 if( !m_ppWrapperCol[ppWrapperIdx] ||
461 m_ppWrapperCol[ppWrapperIdx]->empty() ){
462 throw std::runtime_error(std::string(
463 "Attempted to start Discriminator Wrapper with"
464 " PreProcessing Wrapper collection with"
465 " empty PreProcessing Wrapper."));
466 }
467 }
468}
469
470// =============================================================================
471template <
472 class procedure_t,
473 /*EtaDependency*/int etaDependency,
474 /*EtDependency*/int etDependency,
475 /*SegmentationType*/int segType
476>
477void RingerProcedureWrapper<
478 procedure_t,
479 etaDependency,
480 etDependency,
481 segType,
482 false, // isPreProcessor
483 true, // isDiscriminator
484 false> // isThreshold
485::checkExtraPatNorm() const {
486 if ( m_extraDescriptionNorms.size() != m_discrCol[0].size() ){
487 throw std::runtime_error( std::string("Extra normalization and discriminator et size do not match") );
488 }
489 if ( m_extraDescriptionNorms[0].size() != m_discrCol[0][0].size() ) {
490 throw std::runtime_error( std::string("Extra normalization and discriminator eta size do not match") );
491 }
492}
493
494// =============================================================================
495template <
496 class procedure_t,
497 /*EtaDependency*/int etaDependency,
498 /*EtDependency*/int etDependency,
499 /*SegmentationType*/int segType
500>
501void RingerProcedureWrapper<
502 procedure_t,
503 etaDependency,
504 etDependency,
505 segType,
506 false, // isPreProcessor
507 true, // isDiscriminator
508 false> // isThreshold
509::checkDiscrCol() const {
510 try {
511 checkCollection(m_discrCol,
512 static_cast<EtaDependency>(etaDependency),
513 static_cast<EtDependency>(etDependency));
514 if (segType && m_discrCol.size() < 2 ){
515 throw std::runtime_error(std::string("Cannot allocate dependency vector "
516 "with size lesser than one when using segmentation dependency."));
517 }
518 } catch ( const std::runtime_error &e ) {
519 throw std::runtime_error(std::string("Couldn't initialize RingerDiscriminationWrapper collection due to: ")
520 + e.what() );
521 }
522}
523
524// =============================================================================
525template <
526 class procedure_t,
527 /*EtaDependency*/int etaDependency,
528 /*EtDependency*/int etDependency,
529 /*SegmentationType*/int segType
530>
531void RingerProcedureWrapper<
532 procedure_t,
533 etaDependency,
534 etDependency,
535 segType,
536 false, // isPreProcessor
537 true, // isDiscriminator
538 false> // isThreshold
539::setMsgStream(MsgStream *msg) const {
540 // The pre-processors wrapper collection:
541 for ( size_t ppWrapperIdx = 0; ppWrapperIdx < m_ppWrapperCol.size(); ++ppWrapperIdx ){
542 if ( m_ppWrapperCol[ppWrapperIdx] ) {
543 m_ppWrapperCol[ppWrapperIdx]->setMsgStream(msg);
544 }
545 }
546 // The discrimination collection:
547 setCollectionMsgStream(msg,m_discrCol);
548 // Set the wrapper message stream:
549 this->RedirectMsgStream::setMsgStream(msg);
550}
551
552// =============================================================================
553template <
554 class procedure_t,
555 /*EtaDependency*/int etaDependency,
556 /*EtDependency*/int etDependency,
557 /*SegmentationType*/int segType
558>
559std::string RingerProcedureWrapper<
560 procedure_t,
561 etaDependency,
562 etDependency,
563 segType,
564 false, // isPreProcessor
565 true, // isDiscriminator
566 false> // isThreshold
567::staticFullName() {
568 typedef typename RingerProcedureType<procedure_t>::procEnum_t procEnum_t;
569 std::stringstream ss;
570 ss << "RingerProcedureWrapper<"
571 << toStr(procedure_t::template procType<procEnum_t>() )
572 << ((std::is_same<procedure_t,
573 Discrimination::IDiscriminatorVarDep>::value)?",":
574 "(VarDep),")
575 << toStr(static_cast<EtaDependency>(etaDependency)) << ","
576 << toStr(static_cast<EtDependency>(etDependency)) << ","
577 << toStr(static_cast<SegmentationType>(segType)) << ">";
578 return ss.str();
579}
580
581// =============================================================================
582template <
583 class procedure_t,
584 /*EtaDependency*/int etaDependency,
585 /*EtDependency*/int etDependency,
586 /*SegmentationType*/int segType
587>
588std::string RingerProcedureWrapper<
589 procedure_t,
590 etaDependency,
591 etDependency,
592 segType,
593 false, // isPreProcessor
594 true, // isDiscriminator
595 false> // isThreshold
596::fullName() const {
597 return staticFullName();
598}
599
600// =============================================================================
601template <
602 class procedure_t,
603 /*EtaDependency*/int etaDependency,
604 /*EtDependency*/int etDependency,
605 /*SegmentationType*/int segType
606>
607void RingerProcedureWrapper<
608 procedure_t,
609 etaDependency,
610 etDependency,
611 segType,
612 false, // isPreProcessor
613 true, // isDiscriminator
614 false> // isThreshold
615::print(MSG::Level lvl) const
616{
617 if ( this->isStreamAvailable() ) {
618 if ( this->level() > lvl ){
619 // Don't waste time to print nothing.
620 return;
621 }
622 this->msg() << lvl << " -------- Printing PreProcesorWrappers -------- "
623 << endmsg;
624 // Print pre-processing collection:
625 for ( size_t ppWrapIdx = 0; ppWrapIdx < m_ppWrapperCol.size(); ++ppWrapIdx )
626 {
627 this->msg() << lvl << "PreProcessingWrapper"
628 << IOHelperFcns::makeIdxStr(ppWrapIdx) << endmsg;
629 m_ppWrapperCol[ppWrapIdx]->print( lvl );
630 }
631 this->msg() << lvl << " --- Finished printing PreProcessorWrappers --- "
632 << endmsg;
633 // Print discriminators
634 std::vector<unsigned> posVec(3);
635 for ( size_t segIdx = 0; segIdx < m_discrCol.size() ; ++segIdx){
636 posVec[0] = segIdx;
637 for ( size_t etIdx = 0; etIdx < m_discrCol[segIdx].size() ; ++etIdx){
638 posVec[1] = etIdx;
639 for ( size_t etaIdx = 0; etaIdx < m_discrCol[segIdx][etIdx].size();
640 ++etaIdx)
641 {
642 posVec[2] = etaIdx;
643 this->msg() << lvl << m_discrCol[segIdx][etIdx][etaIdx]->name() <<
644 IOHelperFcns::makeIdxStr(posVec) << " configuration:" << endmsg;
645 m_discrCol[segIdx][etIdx][etaIdx]->print(lvl);
646 }
647 }
648 }
649 } else {
650 std::cerr << "Stream is not available, cannot print " << fullName() << "."
651 << std::endl;
652 }
653}
654
655// =============================================================================
656template <
657 class procedure_t,
658 /*EtaDependency*/int etaDependency,
659 /*EtDependency*/int etDependency,
660 /*SegmentationType*/int segType
661>
662void RingerProcedureWrapper<
663 procedure_t,
664 etaDependency,
665 etDependency,
666 segType,
667 false, // isPreProcessor
668 true, // isDiscriminator
669 false> // isThreshold
670::write(TDirectory *baseDir, const char *idxStr) const
671{
672
673 // ----------- Template basics ----------
674 // Create configuration directory
675 TDirectory *configDir = IOHelperFcns::makeDir(baseDir,
676 (std::string(name()) + idxStr).c_str() );
677
678 // Write basic template information:
679 discrEnum_t discrType = procedure_t::template procType<discrEnum_t>();
680 SegmentationType fileSegType = static_cast<SegmentationType>(segType);
681 EtaDependency fileEtaDep = static_cast<EtaDependency>(etaDependency);
682 EtDependency fileEtDep = static_cast<EtDependency>(etDependency);
683 // FIXME Why do I need to use const? Unfortunately if I don't use so, the
684 // compiler won't accept static_casting from discr_Enum_t to unsigned int:
685 // some issue with reference casting.
686 // It may have something to do with object life time, as const references
687 // have lifetime extended.
688 IOHelperFcns::writeVar<const discrEnum_t, const unsigned int>( configDir,
689 "discrType",
690 discrType);
691 IOHelperFcns::writeVar<const SegmentationType, const unsigned int>( configDir,
692 "segType",
693 fileSegType);
694 IOHelperFcns::writeVar<const EtaDependency, const unsigned int>( configDir,
695 "etaDependency",
696 fileEtaDep);
697 IOHelperFcns::writeVar<const EtDependency, const unsigned int>( configDir,
698 "etDependency",
699 fileEtDep);
700
701 // ----------- Pre-processing chain ----------
702 // Write flag whether there is pre-processing chain for this discriminator:
703 IPreProcWrapper::writeCol(m_ppWrapperCol, configDir);
704
705 // ------------ Discriminators: ---------------
706 // Write size information:
707 unsigned discrSegDepSize = m_discrCol.size();
708 unsigned discrEtDepSize = m_discrCol[0].size();
709 unsigned discrEtaDepSize = m_discrCol[0][0].size();
710 IOHelperFcns::writeVar( configDir, "discrSegDepSize" , discrSegDepSize );
711 IOHelperFcns::writeVar( configDir, "discrEtDepSize" , discrEtDepSize );
712 IOHelperFcns::writeVar( configDir, "discrEtaDepSize" , discrEtaDepSize );
713 // Write Discriminator collection
714 std::vector<unsigned int> discrCount(3);
715 for (size_t segIdx = 0;
716 segIdx < m_discrCol.size();
717 ++segIdx)
718 {
719 discrCount[0] = segIdx;
720 for (size_t etIdx = 0;
721 etIdx < m_discrCol[segIdx].size();
722 ++etIdx)
723 {
724 discrCount[1] = etIdx;
725 for (size_t etaIdx = 0;
726 etaIdx < m_discrCol[segIdx][etIdx].size();
727 ++etaIdx)
728 {
729 discrCount[2] = etaIdx;
730 m_discrCol[segIdx][etIdx][etaIdx]->write(
731 configDir,
732 IOHelperFcns::makeIdxStr(discrCount).c_str());
733 }
734 }
735 }
736 unsigned mask = m_extraDescriptionPatterns.to_ulong();
737 IOHelperFcns::writeVar( configDir
738 , "extraDescriptionPatterns"
739 , mask
740 );
741
742 // Work on the extra pattern normalization:
743 if (static_cast<bool>(m_extraDescriptionPatterns) ){
744 this->checkExtraPatNorm();
745 unsigned et(0), eta(0);
746 for ( const auto& extraNormVec : m_extraDescriptionNorms ) {
747 for ( const auto extraNorm : extraNormVec ) {
748 std::vector<unsigned> idxs{et,eta};
749 extraNorm->write( configDir, IOHelperFcns::makeIdxStr( idxs ).c_str() );
750 ++eta;
751 }
752 ++et; eta = 0;
753 }
754 }
755
756}
757
758// =============================================================================
759template <
760 class procedure_t,
761 /*EtaDependency*/int etaDependency,
762 /*EtDependency*/int etDependency,
763 /*SegmentationType*/int segType
764>
765RingerProcedureWrapper<procedure_t,
766 etaDependency,
767 etDependency,
768 segType,
769 false,
770 true,
771 false> *
772RingerProcedureWrapper<
773 procedure_t,
774 etaDependency,
775 etDependency,
776 segType,
777 false, // isPreProcessor
778 true, // isDiscriminator
779 false> // isThreshold
780::read(TDirectory *configDir, unsigned version)
781{
782
783 using namespace Discrimination;
784
785 IOHelperFcns::checkDir(configDir);
786
787 // ----------- Pre-processing chain ----------
788 // Create empty preprocessing wrapper collection:
789 IPreProcWrapperCollection ppWrapperCol;
790
791 //ATH_MSG_DEBUG("Reading Discrimination Wrapper of type \""
792 // << ppType.Data()
793 // << "\" named \"" << configDir->GetName()
794 // << "\" and dependency : ["
795 // << toStr(segType) << ","
796 // << toStr(etaDependency) << ","
797 // << toStr(etDependency) << "]");
798
799 // Check if this discriminator has pre-processing:
800 bool hasPP(false);
801 IOHelperFcns::readVar( configDir, "hasPP", hasPP );
802
803 // Fill preprocessing wrapper collection
804 if (hasPP) {
805 IPreProcWrapper::read( ppWrapperCol, configDir, version );
806 } else {
807 //ATH_MSG_VERBOSE("This Discrimination Wrapper hasn't pre-processors.");
808 }
809
810 // ----------- Discriminators: ----------
811 // Read discrimination collection size:
812 unsigned discrSegDepSize(0),
813 discrEtDepSize(0),
814 discrEtaDepSize(0);
815 IOHelperFcns::readVar( configDir, "discrSegDepSize", discrSegDepSize );
816 IOHelperFcns::readVar( configDir, "discrEtDepSize" , discrEtDepSize );
817 IOHelperFcns::readVar( configDir, "discrEtaDepSize", discrEtaDepSize );
818
819 // Allocate discriminator collection with size specified on file
820 DiscrDepProcCollection discrCol( discrSegDepSize,
821 std::vector< std::vector< procedure_t*> >(
822 discrEtDepSize, std::vector< procedure_t*>(
823 discrEtaDepSize, nullptr )));
824
825 // Allocate index position retriever:
826 std::vector<unsigned int> discrIdxVec(3,0);
827 std::vector<unsigned int> extraIdxVec(2,0);
828
829 // Retrieve dir list and loop on it:
830 std::shared_ptr<THashList> list(nullptr);
831 if ( !( list = IOHelperFcns::getDirList(configDir) ) ) {
832 std::runtime_error(std::string("Couldn't retrieve directory "
833 "list from wrapper folder"));
834 }
835
836 // Read description patterns:
837 unsigned mask(0);
838 try{
839 IOHelperFcns::readVar( configDir, "extraDescriptionPatterns", mask );
840 } catch ( std::exception &) {
841 // old file, all ok
842 }
843 Ringer::ExtraDescriptionPatterns extraDescriptionPatterns(mask);
844
845 ExtraPatternsNormCollection extraDescriptionNorms( discrEtDepSize
846 , std::vector< Ringer::PreProcessing::Norm::ExtraPatternsNorm* >( discrEtaDepSize, nullptr )
847 );
848
849 TIter iter( list.get() );
850 while ( TDirectory* dirObj = static_cast<TDirectory*>(iter()) ) {
851
852 const char* folderName = dirObj->GetName();
853
854 //ATH_MSG_VERBOSE("Scanning directory " << folderName );
855
856 // Filter pre-processing wrapper dirs:
857 if ( IOHelperFcns::startsWith( IRingerProcedureWrapper<PreProcessing::IPreProcessor>::wrapName, folderName) )
858 {
859 // Ok, we don't need to scan this directory, we've handled it before.
860 //ATH_MSG_VERBOSE("Directory is PreProcessorWrapper, continuing.." );
861 continue;
862 }
863 // Treat extra patterns normalization
864 if ( IOHelperFcns::startsWith( "ExtraPatternsNorm" , folderName) ){
865 if ( ! static_cast<bool>( extraDescriptionPatterns ) ){
866 throw std::runtime_error("Read ExtraPatternsNorm on file whereas no extra description is needed..." );
867 }
868 IOHelperFcns::getIdxVecFromStr( folderName, extraIdxVec );
869 auto* extraPatNorm = Ringer::PreProcessing::Norm::ExtraPatternsNormVarDep::read( dirObj );
870 extraDescriptionNorms[ extraIdxVec[0] ][ extraIdxVec[1] ] = extraPatNorm;
871 continue;
872 }
873 // Get information about the discriminator on the folder:
874 discrEnum_t discrType;
875 EtaDependency fileEtaDep;
876 EtDependency fileEtDep;
877 try {
878 IOHelperFcns::readVar<discrEnum_t, unsigned int>(dirObj,
879 "procType",
880 discrType);
881 IOHelperFcns::readVar<EtaDependency, unsigned int>(dirObj,
882 "etaDependency",
883 fileEtaDep);
884 IOHelperFcns::readVar<EtDependency, unsigned int>(dirObj,
885 "etDependency",
886 fileEtDep);
887 } catch (const std::runtime_error &e){
888 throw std::runtime_error(std::string("Couldn't get discriminator type "
889 "while") + "reading folder: " + folderName + ". Reason: "
890 + e.what() );
891 }
892 // Check if holden information dependency information is ok:
893 if ( fileEtaDep != etaDependency ){
894 throw std::runtime_error(std::string("Folder \"") + folderName + "\" is "
895 + toStr(fileEtaDep) + " whereas Wrapper is " + toStr(static_cast<EtaDependency>(etaDependency)) + ".");
896 }
897 if ( fileEtDep != etDependency ){
898 throw std::runtime_error(std::string("Folder \"") + folderName + "\" is "
899 + toStr(fileEtDep) + " whereas Wrapper is " + toStr(static_cast<EtDependency>(etDependency)) + ".");
900 }
901 // Retrieve position indexes where we shall retrieve this discriminator
902 IOHelperFcns::getIdxVecFromStr( folderName, discrIdxVec );
903
904 // Check if everything is ok on indexes retrieved:
905 if ( discrIdxVec.size() < 3 ||
906 discrIdxVec[0] >= discrSegDepSize ||
907 discrIdxVec[1] >= discrEtDepSize ||
908 discrIdxVec[2] >= discrEtaDepSize )
909 {
910 throw std::runtime_error(std::string("There is something wrong with ")
911 + "folder idxStr: " + folderName + ". Got idxStr " +
912 IOHelperFcns::makeIdxStr(discrIdxVec) + ". Maximum discrimination "
913 "collection size is : " + std::to_string(discrSegDepSize) + "," +
914 std::to_string(discrEtDepSize) + "," + std::to_string(discrEtaDepSize));
915 }
916
917 // Get a reference to the pointer (done only to reduce typing):
918 procedure_t *&thisDiscr = discrCol[discrIdxVec[0]]
919 [discrIdxVec[1]]
920 [discrIdxVec[2]];
921
922 // Check which procedure_t this discrimination wrapper holds.
923 if ( std::is_same<procedure_t, IDiscriminatorVarDep >::value )
924 {
925 // If the procedure_t is not the Discriminator interface, code will
926 // never get here. We only use the interpret cast so that the compiler
927 // doesn't complain about type casting.
928 thisDiscr = dynamic_cast<procedure_t*>( getDiscr(discrType, dirObj) );
929 } else {
930 // Here it's easier, we already know the type that is written in the file,
931 // so all we need to do is loop over it and retrieve the discriminator.
932 discrEnum_t wrapperDiscrType = procedure_t::template procType<discrEnum_t>();
933 if ( discrType != wrapperDiscrType ){
934 throw std::runtime_error( std::string("There is a discriminator of type ") +
935 toStr(discrType) + " whereas this wrapper can only hold discriminators "
936 "of type " + toStr(wrapperDiscrType));
937 }
938 thisDiscr = procedure_t::read( dirObj );
939 }
940 // ATH_MSG_VERBOSE("Successfully read directory " << folderName);
941 }
942
943 // Create Discrimination wrapper:
944 RingerProcedureWrapper *newWrapper = nullptr;
945 if (ppWrapperCol.empty()) {
946 newWrapper = new RingerProcedureWrapper(discrCol);
947 } else {
948 newWrapper = new RingerProcedureWrapper(ppWrapperCol, discrCol);
949 }
950
951 newWrapper->setExtraDescriptionPatterns( extraDescriptionPatterns );
952 newWrapper->setExtraDescriptionNorms( extraDescriptionNorms );
953
954 return newWrapper;
955
956}
957/// @}
958
959} // Namespace Ringer
960
961#endif // RINGERSELECTORTOOLS_PROCEDURES_RINGERDISCRIMINATIONWRAPPER_ICC