20#include <TVirtualCollectionProxy.h>
21#include <ROOT/RNTupleModel.hxx>
32 TempInterface(
size_t size,
SG::auxid_t auxid,
void* ptr ) : m_size(size) {
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);
114 if ( type_info ==
typeid(std::string) ) {
120 msg << MSG::ERROR <<
"Unsupported type for RNTuple field \"" <<
fieldName <<
"\"" <<
endmsg;
124 bool auxItemExists(
const std::string& key ) {
129#ifdef XAOD_STANDALONE
141 if( ! evtStore.
retrieve( c, key ).isSuccess() ) {
142 msg << MSG::ERROR <<
"Couldn't retrieve container with key \"" <<
key
147 if( holder !=
nullptr ) {
149 cl = TClass::GetClass( *ti );
151 cl = TClass::GetClass(
typeid( *c ) );
153 if( ( allowMissing ==
false ) && ( cl ==
nullptr ) ) {
155 <<
"Couldn't find TClass dictionary for container \"" <<
key
171 if( ! evtStore.
retrieve( e, key ).isSuccess() ) {
172 msg << MSG::ERROR <<
"Couldn't retrieve object with key \"" <<
key
181 class ProxyWithName {
183 typedef const SG::DataProxy* argument_type;
184 ProxyWithName(
const std::string& name ) : m_name(
name ) {}
185 bool operator()( argument_type proxy )
const {
186 return (
proxy->name() == m_name );
198 auto proxies = evtStore.
proxies();
200 std::not_fn( ProxyWithName( key ) ) ),
208 <<
"Couldn't access data object as a data bucket?!?" <<
endmsg;
211 cl = TClass::GetClass( bucket->
tinfo() );
213 if(
msg.level() <= MSG::VERBOSE ) {
214 msg << MSG::VERBOSE <<
"No dictionary found for: "
219 if( !
cl->InheritsFrom(
"SG::AuxVectorBase" ) ) {
220 if(
msg.level() <= MSG::VERBOSE ) {
221 msg << MSG::VERBOSE <<
"Object \"" <<
key <<
"/" <<
cl->GetName()
222 <<
"\" does not inherit from SG::AuxVectorBase" <<
endmsg;
231 if( ! allowMissing ) {
232 msg << MSG::ERROR <<
"Couldn't retrieve object \"" <<
key
233 <<
"\" as SG::AuxVectorBase" <<
endmsg;
244 if( !evtStore.
retrieve( e, key ).isSuccess() ) {
246 msg << MSG::ERROR <<
"Couldn't retrieve object with key \"" <<
key
273 const std::type_info* type_info = branchConfig.
auxType;
278 msg << MSG::ERROR <<
"BranchConfig not properly configured for " << outputData.
auxName <<
endmsg;
279 return StatusCode::FAILURE;
282 return m_field ? StatusCode::SUCCESS : StatusCode::FAILURE;
289 msg << MSG::ERROR <<
"setup(TTree, ...) called, but only setup(ROOT::RNTupleModel, ...) should be implemented for this processor" <<
endmsg;
290 return StatusCode::FAILURE;
298 return StatusCode::SUCCESS;
315 const std::type_info* type_info = branchConfig.
auxVecType;
319 msg << MSG::ERROR <<
"BranchConfig not properly configured for " << outputData.
auxName <<
endmsg;
320 return StatusCode::FAILURE;
323 if( !
m_field )
return StatusCode::FAILURE;
327 return StatusCode::FAILURE;
329 return StatusCode::SUCCESS;
336 msg << MSG::ERROR <<
"setup(TTree, ...) called, but only setup(ROOT::RNTupleModel, ...) should be implemented for this processor" <<
endmsg;
337 return StatusCode::FAILURE;
342 m_ops.resize( size );
343 return StatusCode::SUCCESS;
345 return StatusCode::FAILURE;
350 if( !rawDataPtr &&
index > 0 )
return StatusCode::FAILURE;
353 TempInterface dstiface(
index + 1,
m_acc->auxid(), rawDataPtr );
357 return StatusCode::FAILURE;
359 return StatusCode::SUCCESS;
371 static const bool ALLOW_MISSING =
false;
374 ALLOW_MISSING,
msg() );
377 return StatusCode::FAILURE;
383 return StatusCode::SUCCESS;
389 if( !auxItemExists(outputData.
auxName) ) {
391 return StatusCode::FAILURE;
393 m_fields.emplace_back( std::make_unique<ElementFieldProcessor>() );
395 return StatusCode::SUCCESS;
401 ATH_MSG_ERROR(
"ElementProcessor::addBranch for TTree should not be called");
402 return StatusCode::FAILURE;
415 if( !auxItemExists(outputData.
auxName) ) {
417 return StatusCode::FAILURE;
419 m_fields.emplace_back( std::make_unique<ContainerFieldProcessor>() );
421 return StatusCode::SUCCESS;
427 ATH_MSG_ERROR(
"ContainerProcessor::addBranch for TTree should not be called");
428 return StatusCode::FAILURE;
433 static const bool ALLOW_MISSING =
false;
434 const TClass* cl =
nullptr;
437 ALLOW_MISSING, cl,
msg() );
442 return StatusCode::FAILURE;
452 return StatusCode::FAILURE;
457 static const TClass*
const auxElementClass =
460 m_collProxy->GetValueClass()->GetBaseClassOffset( auxElementClass );
464 <<
"\" doesn't seem to inherit from \""
465 << auxElementClass->GetName() <<
"\"" );
466 return StatusCode::FAILURE;
471 const_cast< void*
>(
static_cast< const void*
>( &container ) );
472 TVirtualCollectionProxy::TPushPop helper(
m_collProxy, cPtr );
479 for (UInt_t i = 0; i < cSize; ++i) {
480 char* elPtr =
static_cast< char*
>(
m_collProxy->At( i ) );
482 ATH_MSG_ERROR(
"Failed to get element " << i <<
" from container" );
483 return StatusCode::FAILURE;
493 return StatusCode::SUCCESS;
513 return StatusCode::SUCCESS;
520 std::unordered_set<std::string> nonContainers,
522 ROOT::RNTupleModel& model ) {
525 std::vector<BranchConfig> branchConfigs;
526 branchConfigs.reserve( branches.size() );
527 for (
const std::string& branchDecl : branches ) {
528 branchConfigs.emplace_back();
529 ATH_CHECK( branchConfigs.back().parse( branchDecl,
msg() ) );
530 if (!branchConfigs.back().basketSize.has_value())
539 std::set<std::string> decosWithoutType;
540 for (
auto& branchConfig : branchConfigs) {
541 ATH_CHECK ( branchConfig.configureTypes (decosWithoutType,
msg()) );
543 if (!decosWithoutType.empty()) {
544 msg() << MSG::ERROR <<
"The following decorations have no type information:";
545 for (
const auto& deco : decosWithoutType) {
546 msg() <<
" " << deco;
549 return StatusCode::FAILURE;
553 for (
auto& branchConfig : branchConfigs) {
554 ATH_CHECK ( branchConfig.configureSystematics (sysSvc,
msg()) );
559 if (!sysVector.at(0).empty()) {
560 ATH_MSG_ERROR (
"The first systematic in the list is not nominal!");
561 return StatusCode::FAILURE;
565 std::vector<OutputBranchData> outputBranches;
568 std::unordered_set<std::string> allBranches;
571 for(
const auto& branchConfig : branchConfigs ) {
574 std::unordered_set<std::string> branchesForRule;
577 for(
const auto& sys : sysVector ) {
579 if (branchConfig.nominalOnly && !sys.empty())
continue;
582 outputData.
sysIndex = &sys - &sysVector.front();
588 if (branchesForRule.contains(outputData.
branchName))
590 ANA_MSG_VERBOSE (
"Branch \"" << outputData.
branchName <<
"\" for rule \"" << branchConfig.branchDecl <<
"\" and systematic \"" << sys.name() <<
"\" already exists, skipping." );
593 branchesForRule.insert(outputData.
branchName);
597 if (allBranches.contains(outputData.
branchName))
600 return StatusCode::FAILURE;
603 outputBranches.push_back(std::move(outputData));
612 return a.sysIndex < b.sysIndex; });
614 for (
auto &outputData : outputBranches)
618 return StatusCode::SUCCESS;
623 ROOT::RNTupleModel& model ) {
627 <<
"\" from container/variable \"" << outputData.
sgName
628 <<
"." << outputData.
auxName <<
"\"" );
630 return StatusCode::SUCCESS;
637 return StatusCode::SUCCESS;
641 std::string processorName = sgName;
643 processorName +=
":metTerm=" + branchConfig.
metTermName;
647 return *iter->second;
650 return *
m_processors.emplace (processorName, std::make_unique<ElementProcessorMet>(sgName, branchConfig.
metTermName)).first->second;
654 return *(
m_processors.emplace(processorName, std::make_unique<ElementProcessor>(sgName)).first->second);
656 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
#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.
Base class for elements of a container that can have aux data.
const SG::AuxVectorData * container() const
Return the container holding this element.
size_t index() const
Return the index of this element within its container.
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 TEvent to make it look like StoreGate.
bool contains(const std::string &name) const
Check if an object is available for constant access.
T * retrieve(const std::string &name) const
Function retrieving a constant or non-constant object.
xAOD::TStore * tds() const
Return the underlying transient data store.
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.
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