ATLAS Offline Software
Loading...
Searching...
No Matches
CP::TreeBranchHelpers::ElementBranchProcessor Class Reference

Class writing one variable from an xAOD object into a branch. More...

#include <TreeBranchHelpers.h>

Inheritance diagram for CP::TreeBranchHelpers::ElementBranchProcessor:
Collaboration diagram for CP::TreeBranchHelpers::ElementBranchProcessor:

Public Member Functions

 ElementBranchProcessor ()=default
virtual ~ElementBranchProcessor ()=default
 ElementBranchProcessor (const ElementBranchProcessor &)=delete
ElementBranchProcessoroperator= (const ElementBranchProcessor &)=delete
virtual StatusCode setup (TTree &tree, const BranchConfig &branchConfig, OutputBranchData &outputData, MsgStream &msg) override
 Function setting up the object, and the branch.
virtual StatusCode setup (ROOT::RNTupleModel &, const BranchConfig &, OutputBranchData &, MsgStream &msg) override
StatusCode process (const SG::AuxElement &element, MsgStream &msg)
 Function processing the object, filling the variable.

Public Attributes

std::string m_branchName
 Name of the branch being written.
std::unique_ptr< SG::TypelessConstAccessorm_acc
 Object accessing the variable in question.
const SG::IAuxTypeVectorFactorym_factory = nullptr
 Pointer to the helper object that handles this variable.
std::unique_ptr< SG::IAuxTypeVectorm_data
 The object managing the memory of the written variable.
void * m_dataPtr = nullptr
 Helper variable, pointing at the object to be written.

Detailed Description

Class writing one variable from an xAOD object into a branch.

It is used for both setting up the branch in the outut TTree during the setup of the tree, and then to fill the "output variable" with the right payload during the event processing.

Note that since we may have a lot of such objects, I didn't want to make it inherit from asg::AsgMessaging. Which means that all of the class's functions need to receive its parent's message stream object to be able to log error messages "nicely".

Also note that since this is very much an internal class, all of its members are public. Since the owner of such objects should know perfectly well how they behave.

Definition at line 225 of file TreeBranchHelpers.h.

Constructor & Destructor Documentation

◆ ElementBranchProcessor() [1/2]

CP::TreeBranchHelpers::ElementBranchProcessor::ElementBranchProcessor ( )
default

◆ ~ElementBranchProcessor()

virtual CP::TreeBranchHelpers::ElementBranchProcessor::~ElementBranchProcessor ( )
virtualdefault

◆ ElementBranchProcessor() [2/2]

CP::TreeBranchHelpers::ElementBranchProcessor::ElementBranchProcessor ( const ElementBranchProcessor & )
delete

Member Function Documentation

◆ operator=()

ElementBranchProcessor & CP::TreeBranchHelpers::ElementBranchProcessor::operator= ( const ElementBranchProcessor & )
delete

◆ process()

StatusCode CP::TreeBranchHelpers::ElementBranchProcessor::process ( const SG::AuxElement & element,
MsgStream & msg )

Function processing the object, filling the variable.

This function is called by ElementProcessorRegular, to extract one variable from the standalone object, and move its payload into the memory address from which the output tree is writing its branch.

Parameters
elementThe standalone object to get the auxiliary variable from
msgReference to the parent's MsgStream object
Returns
The usual StatusCode values

Definition at line 720 of file TreeBranchHelpers.cxx.

721 {
722
723 // A security check.
724 if( ( ! m_acc ) || ( ! m_factory ) || ( ! m_data ) ) {
725 msg << MSG::FATAL << "Internal logic error detected" << endmsg;
726 return StatusCode::FAILURE;
727 }
728
729 // Get the data out of the xAOD object.
730 //const void* auxData = ( *m_acc )( element );
731
732 // Copy it into the output variable.
733 TempInterface dstiface (m_data->size(), m_acc->auxid(), m_data->toPtr());
734 m_factory->copy( m_acc->auxid(), dstiface, 0,
735 *element.container(), element.index(), 1 );
736
737 // Return gracefully.
738 return StatusCode::SUCCESS;
739 }
#define endmsg
std::unique_ptr< SG::IAuxTypeVector > m_data
The object managing the memory of the written variable.
const SG::IAuxTypeVectorFactory * m_factory
Pointer to the helper object that handles this variable.
std::unique_ptr< SG::TypelessConstAccessor > m_acc
Object accessing the variable in question.
MsgStream & msg
Definition testRead.cxx:32

◆ setup() [1/2]

StatusCode CP::TreeBranchHelpers::ElementBranchProcessor::setup ( ROOT::RNTupleModel & ,
const BranchConfig & ,
OutputBranchData & ,
MsgStream & msg )
overridevirtual

Implements CP::TreeBranchHelpers::IComponentProcessor.

Definition at line 741 of file TreeBranchHelpers.cxx.

742 {
743 msg << MSG::ERROR << "ElementBranchProcessor::setup for RNTuple should not be called" << endmsg;
744 return StatusCode::FAILURE;
745 }

◆ setup() [2/2]

StatusCode CP::TreeBranchHelpers::ElementBranchProcessor::setup ( TTree & tree,
const BranchConfig & branchConfig,
OutputBranchData & outputData,
MsgStream & msg )
overridevirtual

Function setting up the object, and the branch.

This is pretty much the constructor of the class. I just decided to implement it as a regular function and not a "real" constructor, to be able to return a StatusCode value from the call. Since the setup of the object may very well fail.

Parameters
treeThe tree to set up the new branch in
auxNameThe name of the auxiliary variable to create a branch from
branchNameName of the branch to create in the tree
msgReference to the parent's MsgStream object
Returns
The usual StatusCode values

Implements CP::TreeBranchHelpers::IComponentProcessor.

Definition at line 636 of file TreeBranchHelpers.cxx.

637 {
638
639 // Remember the branch name.
640 m_branchName = outputData.branchName;
641
642 // Create the accessor.
643 m_acc.reset( new SG::TypelessConstAccessor( *branchConfig.auxType, outputData.auxName ) );
644
645 // Get a pointer to the vector factory.
646 m_factory = branchConfig.auxFactory;
647
648 // Create the data object.
649 m_data = m_factory->create( m_acc->auxid(), 1, 1, false );
650
651 // Pointer to the branch, to be created.
652 TBranch* br = nullptr;
653
654 // Decide whether we're dealing with a "primitive" or an "object" branch.
655 if( strlen( branchConfig.auxType->name() ) == 1 ) {
656
657 // This is a "primitive" variable...
658
659 // Get the type identifier for it that ROOT will understand.
660 const char rType = rootType( branchConfig.auxType->name()[ 0 ], msg );
661 if( rType == '\0' ) {
662 msg << MSG::ERROR << "Type not recognised for variable: "
663 << outputData.branchName << endmsg;
664 return StatusCode::FAILURE;
665 }
666
667 // Construct the type description.
668 std::ostringstream typeDesc;
669 typeDesc << outputData.branchName << "/" << rType;
670
671 // Create the primitive branch.
672 br = tree.Branch( outputData.branchName.c_str(), m_data->toPtr(),
673 typeDesc.str().c_str() );
674 if (branchConfig.basketSize.has_value())
675 br->SetBasketSize(branchConfig.basketSize.value());
676
677 } else {
678
679 // This is an "object" variable...
680
681 // Get a proper type name for the variable.
682 const std::string typeName = SG::normalizedTypeinfoName( *branchConfig.auxType );
683
684 // Access the dictionary for the type.
685 TClass* cl = TClass::GetClass( *branchConfig.auxType );
686 if( ! cl ) {
687 cl = TClass::GetClass( typeName.c_str() );
688 }
689 if( ! cl ) {
690 msg << MSG::ERROR << "Couldn't find dictionary for type: "
691 << typeName << endmsg;
692 return StatusCode::FAILURE;
693 }
694 if( ! cl->GetStreamerInfo() ) {
695 msg << MSG::ERROR << "No streamer info available for type: "
696 << cl->GetName() << endmsg;
697 return StatusCode::FAILURE;
698 }
699
700 // Create the object branch.
701 m_dataPtr = m_data->toPtr();
702 br = tree.Branch( outputData.branchName.c_str(), cl->GetName(), &m_dataPtr );
703 if (branchConfig.basketSize.has_value())
704 br->SetBasketSize(branchConfig.basketSize.value());
705
706 }
707
708 // Check that the branch creation succeeded.
709 if( ! br ) {
710 msg << MSG::ERROR << "Failed to create branch: " << outputData.branchName
711 << endmsg;
712 return StatusCode::FAILURE;
713 }
714
715 // Return gracefully.
716 return StatusCode::SUCCESS;
717 }
void * m_dataPtr
Helper variable, pointing at the object to be written.
std::string m_branchName
Name of the branch being written.
ConstAuxElement::TypelessConstAccessor TypelessConstAccessor
Definition AuxElement.h:567
std::string normalizedTypeinfoName(const std::type_info &info)
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
char rootType(char typeidType)
This function is used internally in the code when creating primitive dynamic auxiliary branches.
TChain * tree

Member Data Documentation

◆ m_acc

std::unique_ptr< SG::TypelessConstAccessor > CP::TreeBranchHelpers::ElementBranchProcessor::m_acc

Object accessing the variable in question.

Definition at line 270 of file TreeBranchHelpers.h.

◆ m_branchName

std::string CP::TreeBranchHelpers::ElementBranchProcessor::m_branchName

Name of the branch being written.

Definition at line 268 of file TreeBranchHelpers.h.

◆ m_data

std::unique_ptr< SG::IAuxTypeVector > CP::TreeBranchHelpers::ElementBranchProcessor::m_data

The object managing the memory of the written variable.

Definition at line 274 of file TreeBranchHelpers.h.

◆ m_dataPtr

void* CP::TreeBranchHelpers::ElementBranchProcessor::m_dataPtr = nullptr

Helper variable, pointing at the object to be written.

Definition at line 276 of file TreeBranchHelpers.h.

◆ m_factory

const SG::IAuxTypeVectorFactory* CP::TreeBranchHelpers::ElementBranchProcessor::m_factory = nullptr

Pointer to the helper object that handles this variable.

Definition at line 272 of file TreeBranchHelpers.h.


The documentation for this class was generated from the following files: