20#include <TVirtualCollectionProxy.h>
21#include <ROOT/RNTupleModel.hxx>
33 setCache( auxid, ptr );
35 using AuxVectorData::setStore;
36 virtual size_t size_v()
const {
return m_size; }
37 virtual size_t capacity_v()
const {
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
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;
316 const std::type_info* type_info = branchConfig.
auxVecType;
320 msg << MSG::ERROR <<
"BranchConfig not properly configured for " << outputData.
auxName <<
endmsg;
321 return StatusCode::FAILURE;
324 if( !
m_field )
return StatusCode::FAILURE;
328 return StatusCode::FAILURE;
330 return StatusCode::SUCCESS;
337 msg << MSG::ERROR <<
"setup(TTree, ...) called, but only setup(ROOT::RNTupleModel, ...) should be implemented for this processor" <<
endmsg;
338 return StatusCode::FAILURE;
344 return StatusCode::SUCCESS;
346 return StatusCode::FAILURE;
351 if( !rawDataPtr &&
index > 0 )
return StatusCode::FAILURE;
354 TempInterface dstiface(
index + 1,
m_acc->auxid(), rawDataPtr );
355 m_factory->copy(
m_acc->auxid(), dstiface,
index, *element.container(), element.index(), 1 );
358 return StatusCode::FAILURE;
360 return StatusCode::SUCCESS;
372 static const bool ALLOW_MISSING =
false;
375 ALLOW_MISSING,
msg() );
378 return StatusCode::FAILURE;
384 return StatusCode::SUCCESS;
390 if( !auxItemExists(outputData.
auxName) ) {
392 return StatusCode::FAILURE;
394 m_fields.emplace_back( std::make_unique<ElementFieldProcessor>() );
396 return StatusCode::SUCCESS;
402 ATH_MSG_ERROR(
"ElementProcessor::addBranch for TTree should not be called");
403 return StatusCode::FAILURE;
416 if( !auxItemExists(outputData.
auxName) ) {
418 return StatusCode::FAILURE;
420 m_fields.emplace_back( std::make_unique<ContainerFieldProcessor>() );
422 return StatusCode::SUCCESS;
428 ATH_MSG_ERROR(
"ContainerProcessor::addBranch for TTree should not be called");
429 return StatusCode::FAILURE;
434 static const bool ALLOW_MISSING =
false;
435 const TClass* cl =
nullptr;
438 ALLOW_MISSING, cl,
msg() );
443 return StatusCode::FAILURE;
453 return StatusCode::FAILURE;
458 static const TClass*
const auxElementClass =
461 m_collProxy->GetValueClass()->GetBaseClassOffset( auxElementClass );
465 <<
"\" doesn't seem to inherit from \""
466 << auxElementClass->GetName() <<
"\"" );
467 return StatusCode::FAILURE;
472 const_cast< void*
>(
static_cast< const void*
>( &container ) );
473 TVirtualCollectionProxy::TPushPop helper(
m_collProxy, cPtr );
480 for (UInt_t i = 0; i < cSize; ++i) {
481 char* elPtr =
static_cast< char*
>(
m_collProxy->At( i ) );
483 ATH_MSG_ERROR(
"Failed to get element " << i <<
" from container" );
484 return StatusCode::FAILURE;
494 return StatusCode::SUCCESS;
514 return StatusCode::SUCCESS;
521 std::unordered_set<std::string> nonContainers,
523 ROOT::RNTupleModel& model ) {
526 std::vector<BranchConfig> branchConfigs;
527 branchConfigs.reserve( branches.size() );
528 for (
const std::string& branchDecl : branches ) {
529 branchConfigs.emplace_back();
530 ATH_CHECK( branchConfigs.back().parse( branchDecl,
msg() ) );
531 if (!branchConfigs.back().basketSize.has_value())
540 std::set<std::string> decosWithoutType;
541 for (
auto& branchConfig : branchConfigs) {
542 ATH_CHECK ( branchConfig.configureTypes (decosWithoutType,
msg()) );
544 if (!decosWithoutType.empty()) {
545 msg() << MSG::ERROR <<
"The following decorations have no type information:";
546 for (
const auto& deco : decosWithoutType) {
547 msg() <<
" " << deco;
550 return StatusCode::FAILURE;
554 for (
auto& branchConfig : branchConfigs) {
555 ATH_CHECK ( branchConfig.configureSystematics (sysSvc,
msg()) );
560 if (!sysVector.at(0).empty()) {
561 ATH_MSG_ERROR (
"The first systematic in the list is not nominal!");
562 return StatusCode::FAILURE;
566 std::vector<OutputBranchData> outputBranches;
569 std::unordered_set<std::string> allBranches;
572 for(
const auto& branchConfig : branchConfigs ) {
575 std::unordered_set<std::string> branchesForRule;
578 for(
const auto& sys : sysVector ) {
580 if (branchConfig.nominalOnly && !sys.empty())
continue;
583 outputData.
sysIndex = &sys - &sysVector.front();
589 if (branchesForRule.contains(outputData.
branchName))
591 ANA_MSG_VERBOSE (
"Branch \"" << outputData.
branchName <<
"\" for rule \"" << branchConfig.branchDecl <<
"\" and systematic \"" << sys.name() <<
"\" already exists, skipping." );
594 branchesForRule.insert(outputData.
branchName);
598 if (allBranches.contains(outputData.
branchName))
601 return StatusCode::FAILURE;
604 outputBranches.push_back(std::move(outputData));
613 return a.sysIndex < b.sysIndex; });
615 for (
auto &outputData : outputBranches)
619 return StatusCode::SUCCESS;
624 ROOT::RNTupleModel& model ) {
628 <<
"\" from container/variable \"" << outputData.
sgName
629 <<
"." << outputData.
auxName <<
"\"" );
631 return StatusCode::SUCCESS;
638 return StatusCode::SUCCESS;
642 std::string processorName = sgName;
644 processorName +=
":metTerm=" + branchConfig.
metTermName;
648 return *iter->second;
651 return *
m_processors.emplace (processorName, std::make_unique<ElementProcessorMet>(sgName, branchConfig.
metTermName)).first->second;
655 return *(
m_processors.emplace(processorName, std::make_unique<ElementProcessor>(sgName)).first->second);
657 return *(
m_processors.emplace(processorName, std::make_unique<ContainerProcessor>(sgName)).first->second);
#define ATH_CHECK
Evaluate an expression and check for errors.
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
std::optional< int > defaultBasketSize
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.
Helper class to provide const generic access to aux data.
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.
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