2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
5 // $Id: RingerPreProcessorWrapper.icc 791627 2017-01-10 04:45:53Z wsfreund $
6 #ifndef RINGERSELECTORTOOLS_PROCEDURES_RINGERPREPROCESSORWRAPPER_ICC
7 #define RINGERSELECTORTOOLS_PROCEDURES_RINGERPREPROCESSORWRAPPER_ICC
9 #include "RingerPreProcessorWrapper.h"
10 #include "RingerProcedureWrapper.icc"
11 #include "Normalizations.h"
12 #include "RingerSelectorTools/RingerSelectorToolsDefs.h"
14 #include <type_traits>
20 namespace WrapperHelperFcns {
23 * Return the pre-processing on dirObj of ppType
26 PreProcessing::IPreProcessorVarDep* getPP(preProcEnum_t ppType,
29 using namespace PreProcessing;
30 // For the interface case, we will have to create each pre-processing
31 // depending on the information written on ppType:
34 case preProcEnum_t::Norm1:
36 return Norm::Norm1VarDep::read( dirObj );
39 case preProcEnum_t::Norm2:
41 return Norm::Norm2VarDep::read( dirObj );
44 case preProcEnum_t::Sqrt:
46 return Norm::SqrtVarDep::read( dirObj );
49 case preProcEnum_t::ConstantValue:
51 return Norm::ConstantValueVarDep::read( dirObj );
54 case preProcEnum_t::Sequential:
56 return Norm::SequentialVarDep::read( dirObj );
59 case preProcEnum_t::Spherization:
61 return Norm::SpherizationVarDep::read( dirObj );
64 case preProcEnum_t::MinMax:
66 return Norm::MinMaxVarDep::read( dirObj );
71 throw std::runtime_error( std::string("Cannot read preprocessor of ") +
72 "type: " + toStr(ppType) );
76 } // private namespace
79 // Import Wrapper Helper functions
80 using namespace WrapperHelperFcns;
82 // =============================================================================
83 // ----------------------------------------
84 // RingerProcedureWrapper for PreProcessors
85 // ----------------------------------------
86 // =============================================================================
88 // =============================================================================
91 /*EtaDependency*/int etaDependency,
92 /*EtDependency*/int etDependency,
93 /*SegmentationType*/int segType
95 void RingerProcedureWrapper<
100 true, // isPreProcessor
101 false, // isDiscriminator
102 false> // isThreshold
105 for ( size_t segIdx = 0; segIdx < m_ppCol.size() ; ++segIdx){
106 for ( size_t etIdx = 0; etIdx < m_ppCol[segIdx].size() ; ++etIdx){
107 for ( size_t etaIdx = 0; etaIdx < m_ppCol[segIdx][etIdx].size();
110 delete m_ppCol[segIdx][etIdx][etaIdx];
118 // =============================================================================
121 /*EtaDependency*/int etaDependency,
122 /*EtDependency*/int etDependency,
123 /*SegmentationType*/int segType
125 void RingerProcedureWrapper<
133 ::applyPreProcessing(
134 const DepVarStruct &depVar,
135 std::vector<float> &transformVec) const
138 ATH_MSG_DEBUG("Applying internal layer pre-processing.");
141 // This method only applies for segType NoSegmentation.
142 ensureNoSegmentationOnlyFcn(static_cast<SegmentationType>(segType));
144 // If not dependent, simply run for the first position in the vector:
145 if ( !etaDependency && !etDependency ){
146 m_pp->execute(transformVec);
150 // Initialize eta and et indexes:
151 size_t etaIdx(0), etIdx(0);
152 // Get the correct pp to be applied:
153 if (etaDependency == EtaDependency::EtaDependent){
154 etaIdx = findEtaBin(depVar.eta, m_ppCol[0]);
157 if (etDependency == EtDependency::EtDependent){
158 etIdx = findEtBin(depVar.et, m_ppCol[0]);
162 ATH_MSG_VERBOSE("Applying pre-processing at etaIdx ("
163 << etaIdx << ") and etIdx (" << etIdx << ").");
167 m_ppCol[0][etIdx][etaIdx]->execute(transformVec);
170 // =============================================================================
173 /*EtaDependency*/int etaDependency,
174 /*EtDependency*/int etDependency,
175 /*SegmentationType*/int segType
177 void RingerProcedureWrapper<
185 ::applyPreProcessing(
186 const DepVarStruct &depVar,
187 const xAOD::CaloRings *clrings,
188 const TrackPatternsHolder *trackPat,
189 std::vector<float> &transformVec) const
193 ATH_MSG_DEBUG("Applying first discrimination layer pre-processing.");
196 // Erase any previous information
197 transformVec.clear();
199 // Initialize eta and et indexes:
200 size_t etaIdx(0), etIdx(0);
201 // Get the correct idx to be applied:
202 if ( etaDependency == EtaDependency::EtaDependent ) {
203 etaIdx = findEtaBin(depVar.eta, m_ppCol[0]);
205 if ( etDependency == EtDependency::EtDependent ) {
206 etIdx = findEtBin(depVar.et, m_ppCol[0]);
211 case SegmentationType::NoSegmentation:
214 ATH_MSG_VERBOSE("Applying NonSegmented pre-processing at etaIdx ("
215 << etaIdx << ") and etIdx (" << etIdx << ").");
218 clrings->exportRingsTo(transformVec);
221 trackPat->exportPatternsTo(transformVec);
223 // Apply pre-processing to all transformVec:
224 m_ppCol[cPreProc++][etIdx][etaIdx]->execute(transformVec);
227 case SegmentationType::TrackCalSegmentation:
230 ATH_MSG_VERBOSE("Applying Track/Cal segmented pre-processing "
231 " at etaIdx (" << etaIdx << ") and etIdx ("
235 // Apply pre-processing to CaloRings as one:
236 clrings->exportRingsTo(transformVec);
239 m_ppCol[cPreProc++][etIdx][etaIdx],
245 transformVec.clear();
246 // Apply pre-processing to track patterns separated:
247 trackPat->exportPatternsTo(transformVec);
250 m_ppCol[cPreProc++][etIdx][etaIdx],
257 case SegmentationType::TrackCalPatTypeSegmentation:
259 // TODO Implement this if it is going to be used:
260 throw std::runtime_error(std::string("There is no implementation method "
261 "for ") + toStr(static_cast<SegmentationType>(segType)) );
263 case SegmentationType::TrackCalJointSections:
266 ATH_MSG_VERBOSE("Applying Track/Cal-JointSections segmented"
267 " pre-processing at etaIdx (" << etaIdx << ") and etIdx ("
271 // Apply pre-processing to each CalJointSection:
272 while ( cPreProc < static_cast<size_t>(
273 CalJointSection::NJointSections) )
275 transformVec.clear();
276 clrings->exportRingsTo( transformVec,
278 static_cast<CalJointSection>(cPreProc));
282 m_ppCol[cPreProc++][etIdx][etaIdx],
286 cPreProc += static_cast<size_t>(CalJointSection::NJointSections);
289 transformVec.clear();
290 // Apply pre-processing to track patterns separated:
291 trackPat->exportPatternsTo(transformVec);
294 m_ppCol[cPreProc++][etIdx][etaIdx],
301 case SegmentationType::TrackCalJointLayers:
304 ATH_MSG_VERBOSE("Applying Track/Cal-JointLayers segmented"
305 " pre-processing at etaIdx (" << etaIdx << ") and etIdx ("
309 // Apply pre-processing to each CalJointLayer:
310 while ( cPreProc < static_cast<size_t>(
311 CalJointLayer::NJointLayers) )
313 transformVec.clear();
314 clrings->exportRingsTo(
317 static_cast<CalJointLayer>(cPreProc));
321 m_ppCol[cPreProc++][etIdx][etaIdx],
325 cPreProc += static_cast<size_t>(CalJointLayer::NJointLayers);
328 transformVec.clear();
329 // Apply pre-processing to track Patterns separated:
330 trackPat->exportPatternsTo(transformVec);
333 m_ppCol[cPreProc++][etIdx][etaIdx],
342 throw std::runtime_error(std::string("There is no implementation method "
343 "for ") + toStr(static_cast<SegmentationType>(segType)) );
349 // =============================================================================
352 /*EtaDependency*/int etaDependency,
353 /*EtDependency*/int etDependency,
354 /*SegmentationType*/int segType
356 void RingerProcedureWrapper<
361 true, // isPreProcessor
362 false, // isDiscriminator
363 false> // isThreshold
366 checkCollection(m_ppCol,
367 static_cast<EtaDependency>(etaDependency),
368 static_cast<EtDependency>(etDependency));
369 if ( m_ppCol.size() != numberOfSegments(static_cast<SegmentationType>(segType))){
370 throw std::runtime_error(std::string("Cannot allocate segment ") +
371 "dependent vector of type " + toStr(static_cast<SegmentationType>(segType)) + " with size "
372 "different from " + std::to_string(numberOfSegments(static_cast<SegmentationType>(segType))) +
373 ". Current size is " + std::to_string(m_ppCol.size()) + ".");
375 } catch ( const std::runtime_error &e ) {
376 throw std::runtime_error(std::string("Couldn't initialize RingerPreProcessorWrapper due to: ")
381 // =============================================================================
384 /*EtaDependency*/int etaDependency,
385 /*EtDependency*/int etDependency,
386 /*SegmentationType*/int segType
388 void RingerProcedureWrapper<
393 true, // isPreProcessing
394 false, // isDiscriminator
395 false> // isThreshold
396 ::setMsgStream(MsgStream *msg) const {
397 // Propagate this stream into collection:
398 setCollectionMsgStream(msg,m_ppCol);
399 // Set stream to self
400 this->RedirectMsgStream::setMsgStream(msg);
403 // =============================================================================
406 /*EtaDependency*/int etaDependency,
407 /*EtDependency*/int etDependency,
408 /*SegmentationType*/int segType
410 std::string RingerProcedureWrapper<
415 true, // isPreProcessor
416 false, // isDiscriminator
417 false> // isThreshold
419 typedef typename RingerProcedureType<procedure_t>::procEnum_t procEnum_t;
420 std::stringstream ss;
421 ss << "RingerProcedureWrapper<"
422 << toStr(procedure_t::template procType<procEnum_t>() )
423 << ((std::is_same<procedure_t,
424 PreProcessing::IPreProcessorVarDep>::value)?",":"(VarDep),")
425 << toStr(static_cast<EtaDependency>(etaDependency)) << ","
426 << toStr(static_cast<EtDependency>(etDependency)) << ","
427 << toStr(static_cast<SegmentationType>(segType)) << ">";
431 // =============================================================================
434 /*EtaDependency*/int etaDependency,
435 /*EtDependency*/int etDependency,
436 /*SegmentationType*/int segType
438 std::string RingerProcedureWrapper<
443 true, // isPreProcessor
444 false, // isDiscriminator
445 false> // isThreshold
447 return staticFullName();
450 // =============================================================================
453 /*EtaDependency*/int etaDependency,
454 /*EtDependency*/int etDependency,
455 /*SegmentationType*/int segType
457 void RingerProcedureWrapper<
462 true, // isPreProcessor
463 false, // isDiscriminator
464 false> // isThreshold
465 ::print(MSG::Level lvl) const
467 if ( this->isStreamAvailable() ) {
468 if ( this->level() > lvl ){
469 // Don't waste time print nothing.
472 std::vector<unsigned> posVec(3);
473 this->msg() << lvl << fullName() << " contents: "<< endmsg;
474 for ( size_t segIdx = 0; segIdx < m_ppCol.size() ; ++segIdx){
476 for ( size_t etIdx = 0; etIdx < m_ppCol[segIdx].size() ; ++etIdx){
478 for ( size_t etaIdx = 0; etaIdx < m_ppCol[segIdx][etIdx].size();
482 this->msg() << lvl << m_ppCol[segIdx][etIdx][etaIdx]->name() <<
483 IOHelperFcns::makeIdxStr(posVec) << " configuration:" << endmsg;
484 m_ppCol[segIdx][etIdx][etaIdx]->print(lvl);
489 std::cerr << "Stream is not available, cannot print " <<
490 fullName() << "." << std::endl;
494 // =============================================================================
497 /*EtaDependency*/int etaDependency,
498 /*EtDependency*/int etDependency,
499 /*SegmentationType*/int segType
501 void RingerProcedureWrapper<
506 true, // isPreProcessor
507 false, // isDiscriminator
508 false> // isThreshold
509 ::write(TDirectory *baseDir, const char *idxStr) const
511 // ----------- Template basics ----------
512 // Create configuration directory
513 TDirectory *configDir = IOHelperFcns::makeDir(baseDir,
514 (std::string(this->name()) + idxStr).c_str() );
516 // Write basic template information:
517 preProcEnum_t ppType = procedure_t::template procType<preProcEnum_t>();
518 SegmentationType fileSegType = static_cast<SegmentationType>(segType);
519 EtaDependency fileEtaDep = static_cast<EtaDependency>(etaDependency);
520 EtDependency fileEtDep = static_cast<EtDependency>(etDependency);
521 // FIXME Why do I need to use const? Unfortunately if I don't use so, the
522 // compiler won't accept static_casting from discr_Enum_t to unsigned int:
523 // some issue with reference casting.
524 IOHelperFcns::writeVar<const preProcEnum_t, const unsigned int>( configDir,
527 IOHelperFcns::writeVar<const SegmentationType, const unsigned int>( configDir,
530 IOHelperFcns::writeVar<const EtaDependency, const unsigned int>( configDir,
533 IOHelperFcns::writeVar<const EtDependency, const unsigned int>( configDir,
537 // Write size information:
538 unsigned ppSegDepSize = m_ppCol.size();
539 unsigned ppEtDepSize = m_ppCol[0].size();
540 unsigned ppEtaDepSize = m_ppCol[0][0].size();
541 IOHelperFcns::writeVar( configDir, "ppSegDepSize" , ppSegDepSize );
542 IOHelperFcns::writeVar( configDir, "ppEtDepSize" , ppEtDepSize );
543 IOHelperFcns::writeVar( configDir, "ppEtaDepSize" , ppEtaDepSize );
545 // Write PreProcessors Collection
546 std::vector<unsigned int> ppCount(3);
547 for (size_t segIdx = 0;
548 segIdx < m_ppCol.size();
552 for (size_t etIdx = 0;
553 etIdx < m_ppCol[segIdx].size();
557 for (size_t etaIdx = 0;
558 etaIdx < m_ppCol[segIdx][etIdx].size();
562 m_ppCol[segIdx][etIdx][etaIdx]->write(
564 IOHelperFcns::makeIdxStr(ppCount).c_str());
571 // =============================================================================
574 /*EtaDependency*/int etaDependency,
575 /*EtDependency*/int etDependency,
576 /*SegmentationType*/int segType
578 RingerProcedureWrapper<procedure_t,
585 RingerProcedureWrapper<
590 true, // isPreProcessor
591 false, // isDiscriminator
592 false> // isThreshold
593 ::read(TDirectory *configDir, unsigned /*version*/)
595 using namespace PreProcessing;
597 IOHelperFcns::checkDir(configDir);
599 // ----------- PreProcesings: ----------
600 // Read pre-processing collection size:
601 unsigned ppSegDepSize(0),
604 IOHelperFcns::readVar( configDir, "ppSegDepSize", ppSegDepSize );
605 IOHelperFcns::readVar( configDir, "ppEtDepSize" , ppEtDepSize );
606 IOHelperFcns::readVar( configDir, "ppEtaDepSize", ppEtaDepSize );
608 // Allocate pre-processing collection with size specified on file
609 PPDepProcCollection ppCol( ppSegDepSize,
610 std::vector< std::vector< procedure_t*> >(
611 ppEtDepSize, std::vector< procedure_t*>(
612 ppEtaDepSize, nullptr )));
614 // Allocate index position retriever:
615 std::vector<unsigned int> ppIdxVec(3);
617 // Retrieve dir list and loop on it:
618 std::shared_ptr<THashList> list(nullptr);
619 if ( !( list = IOHelperFcns::getDirList(configDir) ) ) {
620 std::runtime_error(std::string("Couldn't retrieve directory "
621 "list from wrapper folder"));
624 TIter iter( list.get() );
625 while ( TDirectory* dirObj = static_cast<TDirectory*>(iter()) ) {
627 const char* folderName = dirObj->GetName();
629 //ATH_MSG_VERBOSE("Scanning directory " << folderName );
631 // Get information about the pre-processing on the folder:
632 preProcEnum_t ppType;
633 EtaDependency fileEtaDep;
634 EtDependency fileEtDep;
636 IOHelperFcns::readVar<preProcEnum_t, unsigned int>(dirObj,
639 IOHelperFcns::readVar<EtaDependency, unsigned int>(dirObj,
642 IOHelperFcns::readVar<EtDependency, unsigned int>(dirObj,
645 } catch (const std::runtime_error &e){
646 throw std::runtime_error(std::string("Couldn't get pre-processing type "
647 "while") + "reading folder: " + folderName + ". Reason: "
650 // Check if holden information dependency information is ok:
651 if ( fileEtaDep != etaDependency ){
652 throw std::runtime_error(std::string("Folder \"") + folderName + "\" is "
653 + toStr(fileEtaDep) + " whereas Wrapper is " + toStr(static_cast<EtaDependency>(etaDependency)) + ".");
655 if ( fileEtDep != etDependency ){
656 throw std::runtime_error(std::string("Folder \"") + folderName + "\" is "
657 + toStr(fileEtDep) + " whereas Wrapper is " + toStr(static_cast<EtDependency>(etDependency)) + ".");
659 // Retrieve position indexes where we shall retrieve this pre-processing
660 IOHelperFcns::getIdxVecFromStr( folderName, ppIdxVec );
662 // Check if everything is ok on indexes retrived:
663 if ( ppIdxVec.size() < 3 ||
664 ppIdxVec[0] >= ppSegDepSize ||
665 ppIdxVec[1] >= ppEtDepSize ||
666 ppIdxVec[2] >= ppEtaDepSize )
668 throw std::runtime_error(std::string("There is something wrong with ")
669 + "folder idxStr: " + folderName + ". Got idxStr " +
670 IOHelperFcns::makeIdxStr(ppIdxVec) + ". Maximum pre-processing "
671 "collection size is : " + std::to_string(ppSegDepSize) + "," +
672 std::to_string(ppEtDepSize) + "," + std::to_string(ppEtaDepSize));
675 // Get a reference to the pointer (only used to reduce typing):
676 procedure_t *&thisPP = ppCol[ppIdxVec[0]]
680 // Check which procedure_t this pre-processing wrapper holds.
681 if ( std::is_same<procedure_t, IPreProcessorVarDep >::value )
683 // If the procedure_t is not the PreProcessor interface, code will
684 // never get here. We only use the interpret cast so that the compiler
685 // doesn't complain about type casting.
686 thisPP = dynamic_cast<procedure_t*>( getPP(ppType, dirObj) );
688 // Here it's easier, we already know the type that is written in the file,
689 // so all we need to do is loop over it and retrieve the discriminator.
690 preProcEnum_t wrapperPPType = procedure_t::template procType<preProcEnum_t>();
691 if ( ppType != wrapperPPType ){
692 throw std::runtime_error( std::string("There is a pre-processing of type ") +
693 toStr(ppType) + " whereas this wrapper can only hold pre-processings "
694 "of type " + toStr(wrapperPPType));
696 thisPP = procedure_t::read( dirObj );
698 // ATH_MSG_VERBOSE("Successfully read directory " << folderName);
701 // Create and return PreProcessors wrapper:
702 return new RingerProcedureWrapper(ppCol);
707 } // Namespace Ringer
709 #endif // RINGERSELECTORTOOLS_PROCEDURES_RINGERPREPROCESSORWRAPPER_ICC