20#include <TVirtualCollectionProxy.h>
21#include <ROOT/RNTupleModel.hxx>
33 setCache( auxid, ptr );
35 using AuxVectorData::setStore;
36 size_t size_v()
const override {
return m_size; }
37 size_t capacity_v()
const override {
return m_size; }
54 template <
typename TYPE>
55 std::shared_ptr<void> makeScalarField(ROOT::RNTupleModel& model,
56 const std::string& fieldName,
63 template <
typename TYPE>
64 std::shared_ptr<void> makeVecField(ROOT::RNTupleModel& model,
65 const std::string& fieldName,
75 std::shared_ptr<void> makeField( ROOT::RNTupleModel& model,
76 const std::string& fieldName,
77 const std::type_info& type_info,
85 if ( type_info ==
typeid(
float) )
return makeScalarField<float>(model, fieldName, rawPtr);
86 if ( type_info ==
typeid(
double) )
return makeScalarField<double>(model, fieldName, rawPtr);
87 if ( type_info ==
typeid(
int) )
return makeScalarField<int>(model, fieldName, rawPtr);
88 if ( type_info ==
typeid(
unsigned int) )
return makeScalarField<unsigned int>(model, fieldName, rawPtr);
89 if ( type_info ==
typeid(
short) )
return makeScalarField<short>(model, fieldName, rawPtr);
90 if ( type_info ==
typeid(
unsigned short) )
return makeScalarField<unsigned short>(model, fieldName, rawPtr);
91 if ( type_info ==
typeid(
long) )
return makeScalarField<long>(model, fieldName, rawPtr);
92 if ( type_info ==
typeid(
unsigned long) )
return makeScalarField<unsigned long>(model, fieldName, rawPtr);
93 if ( type_info ==
typeid(
long long) )
return makeScalarField<long long>(model, fieldName, rawPtr);
94 if ( type_info ==
typeid(
unsigned long long) )
return makeScalarField<unsigned long long>(model, fieldName, rawPtr);
95 if ( type_info ==
typeid(
char) )
return makeScalarField<char>(model, fieldName, rawPtr);
96 if ( type_info ==
typeid(
unsigned char) )
return makeScalarField<unsigned char>(model, fieldName, rawPtr);
97 if ( type_info ==
typeid(
bool) )
return makeScalarField<bool>(model, fieldName, rawPtr);
100 if ( type_info ==
typeid(std::vector<float>) )
return makeVecField<float>(model, fieldName, rawPtr, ops);
101 if ( type_info ==
typeid(std::vector<double>) )
return makeVecField<double>(model, fieldName, rawPtr, ops);
102 if ( type_info ==
typeid(std::vector<int>) )
return makeVecField<int>(model, fieldName, rawPtr, ops);
103 if ( type_info ==
typeid(std::vector<unsigned int>) )
return makeVecField<unsigned int>(model, fieldName, rawPtr, ops);
104 if ( type_info ==
typeid(std::vector<short>) )
return makeVecField<short>(model, fieldName, rawPtr, ops);
105 if ( type_info ==
typeid(std::vector<unsigned short>) )
return makeVecField<unsigned short>(model, fieldName, rawPtr, ops);
106 if ( type_info ==
typeid(std::vector<long>) )
return makeVecField<long>(model, fieldName, rawPtr, ops);
107 if ( type_info ==
typeid(std::vector<unsigned long>) )
return makeVecField<unsigned long>(model, fieldName, rawPtr, ops);
108 if ( type_info ==
typeid(std::vector<long long>) )
return makeVecField<long long>(model, fieldName, rawPtr, ops);
109 if ( type_info ==
typeid(std::vector<unsigned long long>) )
return makeVecField<unsigned long long>(model, fieldName, rawPtr, ops);
110 if ( type_info ==
typeid(std::vector<char>) )
return makeVecField<char>(model, fieldName, rawPtr, ops);
111 if ( type_info ==
typeid(std::vector<unsigned char>) )
return makeVecField<unsigned char>(model, fieldName, rawPtr, ops);
112 if ( type_info ==
typeid(std::vector<bool>) )
return makeVecField<bool>(model, fieldName, rawPtr, ops);
113 if ( type_info ==
typeid(std::vector<std::string>) )
return makeVecField<std::string>(model, fieldName, rawPtr, ops);
115 if ( type_info ==
typeid(std::string) ) {
121 msg << MSG::ERROR <<
"Unsupported type for RNTuple field \"" <<
fieldName <<
"\"" <<
endmsg;
125 bool auxItemExists(
const std::string& key ) {
130#ifdef XAOD_STANDALONE
142 if( ! evtStore.
retrieve( c, key ).isSuccess() ) {
143 msg << MSG::ERROR <<
"Couldn't retrieve container with key \"" <<
key
148 if( holder !=
nullptr ) {
150 cl = TClass::GetClass( *ti );
152 cl = TClass::GetClass(
typeid( *c ) );
154 if( ( allowMissing ==
false ) && ( cl ==
nullptr ) ) {
156 <<
"Couldn't find TClass dictionary for container \"" <<
key
172 if( ! evtStore.
retrieve( e, key ).isSuccess() ) {
173 msg << MSG::ERROR <<
"Couldn't retrieve object with key \"" <<
key
182 class ProxyWithName {
184 typedef const SG::DataProxy* argument_type;
185 ProxyWithName(
const std::string& name ) : m_name(
name ) {}
186 bool operator()( argument_type proxy )
const {
187 return (
proxy->name() == m_name );
199 auto proxies = evtStore.
proxies();
201 std::not_fn( ProxyWithName( key ) ) ),
209 <<
"Couldn't access data object as a data bucket?!?" <<
endmsg;
212 cl = TClass::GetClass( bucket->
tinfo() );
214 if(
msg.level() <= MSG::VERBOSE ) {
215 msg << MSG::VERBOSE <<
"No dictionary found for: "
220 if( !
cl->InheritsFrom(
"SG::AuxVectorBase" ) ) {
221 if(
msg.level() <= MSG::VERBOSE ) {
222 msg << MSG::VERBOSE <<
"Object \"" <<
key <<
"/" <<
cl->GetName()
223 <<
"\" does not inherit from SG::AuxVectorBase" <<
endmsg;
232 if( ! allowMissing ) {
233 msg << MSG::ERROR <<
"Couldn't retrieve object \"" <<
key
234 <<
"\" as SG::AuxVectorBase" <<
endmsg;
245 if( !evtStore.
retrieve( e, key ).isSuccess() ) {
247 msg << MSG::ERROR <<
"Couldn't retrieve object with key \"" <<
key
270 m_acc = std::make_unique<SG::TypelessConstAccessor>( *branchConfig.
auxType, outputData.
auxName );
274 const std::type_info* type_info = branchConfig.
auxType;
279 msg << MSG::ERROR <<
"BranchConfig not properly configured for " << outputData.
auxName <<
endmsg;
280 return StatusCode::FAILURE;
283 return m_field ? StatusCode::SUCCESS : StatusCode::FAILURE;
290 msg << MSG::ERROR <<
"setup(TTree, ...) called, but only setup(ROOT::RNTupleModel, ...) should be implemented for this processor" <<
endmsg;
291 return StatusCode::FAILURE;
298 m_factory->copy(
m_acc->auxid(), dstiface, 0, *element.container(), element.index(), 1 );
299 return StatusCode::SUCCESS;
312 m_acc = std::make_unique<SG::TypelessConstAccessor>( *branchConfig.
auxType, outputData.
auxName );
316 const std::type_info* type_info = branchConfig.
auxVecType;
317 if( *type_info ==
typeid(std::vector<bool>) ) {
319 msg << MSG::ERROR <<
"std::vector<bool> is not supported for container field " <<
m_fieldName <<
endmsg;
320 return StatusCode::FAILURE;
325 msg << MSG::ERROR <<
"BranchConfig not properly configured for " << outputData.
auxName <<
endmsg;
326 return StatusCode::FAILURE;
329 if( !
m_field )
return StatusCode::FAILURE;
333 return StatusCode::FAILURE;
335 return StatusCode::SUCCESS;
342 msg << MSG::ERROR <<
"setup(TTree, ...) called, but only setup(ROOT::RNTupleModel, ...) should be implemented for this processor" <<
endmsg;
343 return StatusCode::FAILURE;
349 return StatusCode::SUCCESS;
351 return StatusCode::FAILURE;
358 return StatusCode::FAILURE;
362 TempInterface dstiface(
index + 1,
m_acc->auxid(), rawDataPtr );
363 m_factory->copy(
m_acc->auxid(), dstiface,
index, *element.container(), element.index(), 1 );
366 return StatusCode::FAILURE;
368 return StatusCode::SUCCESS;
380 static const bool ALLOW_MISSING =
false;
383 ALLOW_MISSING,
msg() );
386 return StatusCode::FAILURE;
392 return StatusCode::SUCCESS;
398 if( !auxItemExists(outputData.
auxName) ) {
400 return StatusCode::FAILURE;
402 m_fields.emplace_back( std::make_unique<ElementFieldProcessor>() );
404 return StatusCode::SUCCESS;
410 ATH_MSG_ERROR(
"ElementProcessor::addBranch for TTree should not be called");
411 return StatusCode::FAILURE;
424 if( !auxItemExists(outputData.
auxName) ) {
426 return StatusCode::FAILURE;
428 m_fields.emplace_back( std::make_unique<ContainerFieldProcessor>() );
430 return StatusCode::SUCCESS;
436 ATH_MSG_ERROR(
"ContainerProcessor::addBranch for TTree should not be called");
437 return StatusCode::FAILURE;
442 static const bool ALLOW_MISSING =
false;
443 const TClass* cl =
nullptr;
446 ALLOW_MISSING, cl,
msg() );
451 return StatusCode::FAILURE;
461 return StatusCode::FAILURE;
466 static const TClass*
const auxElementClass =
469 m_collProxy->GetValueClass()->GetBaseClassOffset( auxElementClass );
473 <<
"\" doesn't seem to inherit from \""
474 << auxElementClass->GetName() <<
"\"" );
475 return StatusCode::FAILURE;
480 const_cast< void*
>(
static_cast< const void*
>( &container ) );
481 TVirtualCollectionProxy::TPushPop helper(
m_collProxy, cPtr );
488 for (UInt_t i = 0; i < cSize; ++i) {
489 char* elPtr =
static_cast< char*
>(
m_collProxy->At( i ) );
491 ATH_MSG_ERROR(
"Failed to get element " << i <<
" from container" );
492 return StatusCode::FAILURE;
502 return StatusCode::SUCCESS;
517 if( term ==
nullptr ) {
519 return StatusCode::FAILURE;
527 return StatusCode::SUCCESS;
534 std::unordered_set<std::string> nonContainers,
536 ROOT::RNTupleModel& model ) {
539 std::vector<BranchConfig> branchConfigs;
540 branchConfigs.reserve( branches.size() );
541 for (
const std::string& branchDecl : branches ) {
542 branchConfigs.emplace_back();
543 ATH_CHECK( branchConfigs.back().parse( branchDecl,
msg() ) );
551 std::set<std::string> decosWithoutType;
552 for (
auto& branchConfig : branchConfigs) {
553 ATH_CHECK ( branchConfig.configureTypes (decosWithoutType,
msg()) );
555 if (!decosWithoutType.empty()) {
556 msg() << MSG::ERROR <<
"The following decorations have no type information:";
557 for (
const auto& deco : decosWithoutType) {
558 msg() <<
" " << deco;
561 return StatusCode::FAILURE;
565 for (
auto& branchConfig : branchConfigs) {
566 ATH_CHECK ( branchConfig.configureSystematics (sysSvc,
msg()) );
571 if (!sysVector.at(0).empty()) {
572 ATH_MSG_ERROR (
"The first systematic in the list is not nominal!");
573 return StatusCode::FAILURE;
577 std::vector<OutputBranchData> outputBranches;
580 std::unordered_set<std::string> allBranches;
583 for(
const auto& branchConfig : branchConfigs ) {
586 std::unordered_set<std::string> branchesForRule;
589 for(
const auto& sys : sysVector ) {
591 if (branchConfig.nominalOnly && !sys.empty())
continue;
594 outputData.
sysIndex = &sys - &sysVector.front();
600 if (branchesForRule.contains(outputData.
branchName))
602 ANA_MSG_VERBOSE (
"Branch \"" << outputData.
branchName <<
"\" for rule \"" << branchConfig.branchDecl <<
"\" and systematic \"" << sys.name() <<
"\" already exists, skipping." );
605 branchesForRule.insert(outputData.
branchName);
609 if (allBranches.contains(outputData.
branchName))
612 return StatusCode::FAILURE;
615 outputBranches.push_back(std::move(outputData));
624 return a.sysIndex < b.sysIndex; });
626 for (
auto &outputData : outputBranches)
630 return StatusCode::SUCCESS;
635 ROOT::RNTupleModel& model ) {
639 <<
"\" from container/variable \"" << outputData.
sgName
640 <<
"." << outputData.
auxName <<
"\"" );
642 return StatusCode::SUCCESS;
649 return StatusCode::SUCCESS;
653 std::string processorName = sgName;
655 processorName +=
":metTerm=" + branchConfig.
metTermName;
659 return *iter->second;
662 return *
m_processors.emplace (processorName, std::make_unique<ElementProcessorMet>(sgName, branchConfig.
metTermName)).first->second;
666 return *(
m_processors.emplace(processorName, std::make_unique<ElementProcessor>(sgName)).first->second);
668 return *(
m_processors.emplace(processorName, std::make_unique<ContainerProcessor>(sgName)).first->second);
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
Base class for elements of a container that can have aux data.
Handle mappings between names and auxid_t.
Manage index tracking and synchronization of auxiliary data.
std::vector< size_t > vec
Interface for factory objects that create vectors.
static HEPVis_BooleanProcessor processor
size_t size() const
Number of registered mappings.
#define TYPE(CODE, TYP, IOTYP)
#define ATLAS_NOT_CONST_THREAD_SAFE
the interface for the central systematics service
virtual std::vector< CP::SystematicSet > makeSystematicsVector() const =0
get the list of systematics
const SG::IAuxTypeVectorFactory * m_factory
std::unique_ptr< SG::TypelessConstAccessor > m_acc
StatusCode process(const SG::AuxElement &element, size_t index, MsgStream &msg)
virtual StatusCode setup(ROOT::RNTupleModel &model, const BranchConfig &branchConfig, OutputBranchData &outputData, MsgStream &msg) override
std::shared_ptr< void > m_field
StatusCode resize(size_t size, MsgStream &msg)
virtual StatusCode addBranch(ROOT::RNTupleModel &model, const BranchConfig &branchConfig, OutputBranchData &outputData) override
std::vector< std::unique_ptr< ContainerFieldProcessor > > m_fields
TVirtualCollectionProxy * m_collProxy
ContainerProcessor(const std::string &sgName)
virtual StatusCode retrieveProcess(StoreType &evtStore) override
retrieve and process the object
std::unique_ptr< SG::TypelessConstAccessor > m_acc
StatusCode process(const SG::AuxElement &element, MsgStream &msg)
virtual StatusCode setup(ROOT::RNTupleModel &model, const BranchConfig &branchConfig, OutputBranchData &outputData, MsgStream &msg) override
std::shared_ptr< void > m_field
const SG::IAuxTypeVectorFactory * m_factory
ElementProcessorMet(const std::string &sgName, const std::string &termName)
virtual StatusCode retrieveProcess(StoreType &evtStore) override
retrieve and process the object
virtual StatusCode retrieveProcess(StoreType &evtStore) override
retrieve and process the object
ElementProcessor(const std::string &sgName)
std::vector< std::unique_ptr< ElementFieldProcessor > > m_fields
virtual StatusCode addBranch(ROOT::RNTupleModel &model, const BranchConfig &branchConfig, OutputBranchData &outputData) override
StatusCode process(StoreType &evtStore)
StatusCode setupTree(const std::vector< std::string > &branches, std::unordered_set< std::string > nonContainers, ISystematicsSvc &sysSvc, ROOT::RNTupleModel &model)
std::unordered_set< std::string > m_nonContainers
std::unordered_map< std::string, std::unique_ptr< TreeBranchHelpers::IObjectProcessor > > m_processors
TreeBranchHelpers::IObjectProcessor & getObjectProcessor(const BranchConfig &branchConfig, const std::string &sgName)
StatusCode setupBranch(const BranchConfig &branchConfig, OutputBranchData &outputData, ROOT::RNTupleModel &model)
the interface class for classes reading an object from the event store and processing it
virtual StatusCode addBranch(TTree &, const BranchConfig &, OutputBranchData &)=0
Add one branch to the output tree.
A non-templated base class for DataBucket, allows to access the transient object address as a void*.
virtual void * object()=0
virtual const std::type_info & tinfo() const =0
Return the type_info for the stored object.
virtual std::vector< const SG::DataProxy * > proxies() const =0
Return the list of all current proxies in store.
Handle mappings between names and auxid_t.
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Manage index tracking and synchronization of auxiliary data.
Manage lookup of vectors of auxiliary data.
DataObject * accessData()
Access DataObject on-demand using conversion service.
The Athena Transient Store API.
StatusCode retrieve(const T *&ptr) const
Retrieve the default object into a const T*.
MsgStream & msg() const
The standard message stream.
MsgStream & msg() const
The standard message stream.
AsgMessaging(const std::string &name)
Constructor with a name.
Wrapper for Event to make it look like StoreGate.
bool contains(const std::string &name) const
Check if an object is available for constant access.
xAOD::TStore * tds() const
Return the underlying transient data store.
T * retrieve(const std::string &name) const
Function retrieving a constant or non-constant object.
This class takes care of holding EDM objects in memory.
const std::type_info * getTypeInfo() const
const THolder * holder(const std::string &key) const
return holder for key
TreeBranchHelpers::OutputBranchData OutputBranchData
TreeBranchHelpers::BranchConfig BranchConfig
Select isolated Photons, Electrons and Muons.
const SG::AuxVectorData * getVectorData(const T &cont)
Selection rules: declare transient members.
static const auxid_t null_auxid
To signal no aux data item.
AuxElement(SG::AuxVectorData *container, size_t index)
Base class for elements of a container that can have aux data.
virtual const IAuxTypeVector * getVector(SG::auxid_t auxid) const override
Return vector interface for one aux data item.
size_t auxid_t
Identifier for a particular aux data item.
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
void stable_sort(DataModel_detail::iterator< DVL > beg, DataModel_detail::iterator< DVL > end)
Specialization of stable_sort for DataVector/List.
DataModel_detail::iterator< DVL > remove_if(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, Predicate pred)
Specialization of remove_if for DataVector/List.
MissingET_v1 MissingET
Version control by type defintion.
MissingETContainer_v1 MissingETContainer
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
std::function< void *()> getData
std::function< void(size_t)> resize
const SG::IAuxTypeVectorFactory * auxFactory
pointer to the aux vector factory
const std::type_info * auxVecType
the vector type of the decoration we read
const std::type_info * auxType
the type of the decoration we read
std::string metTermName
MET ONLY: the name of the MET term to write out.
const BranchConfig * branchConfig
the BranchConfig we are based on
std::size_t sysIndex
the index in the systematics list
StatusCode configureNames(const BranchConfig &branchConfig, const CP::SystematicSet &sys, ISystematicsSvc &sysSvc, MsgStream &msg)
configure names for systematics
std::string auxName
the name of the decoration in the aux-store
std::string sgName
the SG name of the object to read from
std::string branchName
the name of the output branch