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 718 of file TreeBranchHelpers.cxx.

719 {
720
721 // A security check.
722 if( ( ! m_acc ) || ( ! m_factory ) || ( ! m_data ) ) {
723 msg << MSG::FATAL << "Internal logic error detected" << endmsg;
724 return StatusCode::FAILURE;
725 }
726
727 // Get the data out of the xAOD object.
728 //const void* auxData = ( *m_acc )( element );
729
730 // Copy it into the output variable.
731 TempInterface dstiface (m_data->size(), m_acc->auxid(), m_data->toPtr());
732 m_factory->copy( m_acc->auxid(), dstiface, 0,
733 *element.container(), element.index(), 1 );
734
735 // Return gracefully.
736 return StatusCode::SUCCESS;
737 }
#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 739 of file TreeBranchHelpers.cxx.

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

◆ 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 634 of file TreeBranchHelpers.cxx.

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