15#include "GaudiKernel/System.h"
19#include "TBranchElement.h"
20#include "TVirtualCollectionProxy.h"
21#include "TMethodCall.h"
23#include "TObjString.h"
24#include "TDirectory.h"
25#include "TDirectoryFile.h"
45char find_typecode (
const std::type_info& ti)
47 if (ti ==
typeid (
char*))
49 else if (ti ==
typeid (Char_t))
51 else if (ti ==
typeid (UChar_t))
53 else if (ti ==
typeid (Short_t))
55 else if (ti ==
typeid (UShort_t))
57 else if (ti ==
typeid (Int_t))
59 else if (ti ==
typeid (UInt_t))
61 else if (ti ==
typeid (Long_t))
63 else if (ti ==
typeid (ULong_t))
65 else if (ti ==
typeid (Float_t))
67 else if (ti ==
typeid (Double_t))
69 else if (ti ==
typeid (Long64_t))
71 else if (ti ==
typeid (ULong64_t))
73 else if (ti ==
typeid (Bool_t))
94 NameMatches(
const std::string& name ) : m_name(
name ) {}
97 bool operator()(
const std::string& pattern ) {
99 return TPRegexp( pattern ).Match( m_name );
146 StatusCode
init (TBranch* br,
char* defval,
size_t defsize);
229 if (
typeid (*br) ==
typeid (TBranch)) {
231 TLeaf* leaf = br->GetLeaf (br->GetName());
233 REPORT_MESSAGE (MSG::ERROR) <<
"For tree " << br->GetTree()->GetName()
234 <<
" can't find leaf for branch "
236 return StatusCode::FAILURE;
250 else if (TBranchElement* bre =
dynamic_cast<TBranchElement*
> (br)) {
251 assert (defval == 0);
254 if (TVirtualCollectionProxy* collprox = bre->GetCollectionProxy()) {
262 TClass* cl = gROOT->GetClass (bre->GetClassName());
264 REPORT_MESSAGE (MSG::ERROR) <<
"For tree " << br->GetTree()->GetName()
265 <<
" branch " << br->GetName()
266 <<
" can't find class "
267 << bre->GetClassName();
268 return StatusCode::FAILURE;
271 TMethodCall meth (cl,
"clear",
"");
272 if (meth.IsValid()) {
287 REPORT_MESSAGE (MSG::ERROR) <<
"For tree " << br->GetTree()->GetName()
288 <<
" branch " << br->GetName()
289 <<
" has unknown type "
290 <<
typeid(*br).name();
291 return StatusCode::FAILURE;
294 return StatusCode::SUCCESS;
306 std::memset (
m_leaf->GetValuePointer(), 0,
313 void* obj =
m_bre->GetObject();
314 TVirtualCollectionProxy::TPushPop pushcont(
m_proxy, obj);
322 void* obj =
m_bre->GetObject();
329 m_bre->SetAddress(0);
372 StatusCode
add (TBranch* br,
char* defval,
size_t defsize);
389 for (
size_t i = 0; i <
m_info.size(); i++)
409 return StatusCode::SUCCESS;
418 for (
size_t i = 0; i <
m_info.size(); i++)
440 const std::string&
master,
441 const std::vector< std::string >& allowedNames,
442 const std::vector< std::string >& vetoedNames,
463 std::map< std::string, FakeProxy* >::iterator itr =
m_fakeVars.begin();
464 std::map< std::string, FakeProxy* >::iterator end =
m_fakeVars.end();
465 for( ; itr != end; ++itr ) {
486 const std::type_info& ti,
488 const std::string& docstring ,
497 return StatusCode::SUCCESS;
501 if (
m_tree->GetBranch (name.c_str()) != 0) {
503 <<
" in tree " <<
m_tree->GetName();
504 return StatusCode::FAILURE;
511 char typecode = find_typecode (ti);
512 if (typecode !=
'\0') {
514 br =
m_tree->Branch (name.c_str(), 0, (name +
'/' + typecode).c_str());
516 return StatusCode::FAILURE;
519 TLeaf* leaf = br->GetLeaf (name.c_str());
521 return StatusCode::FAILURE;
524 ptr = leaf->GetValuePointer();
527 EDataType dt = TDataType::GetType (ti);
528 TDataType* tdt = gROOT->GetType (TDataType::GetTypeName (dt));
530 defsize = tdt->Size();
531 defcopied =
new char[defsize];
532 std::memcpy (defcopied, defval, defsize);
540 <<
"Requested a default value for variable " << name
541 <<
" of type " << System::typeinfoName (ti)
542 <<
"; but default values are only supported for basic types.";
543 return StatusCode::FAILURE;
549 return StatusCode::FAILURE;
552 br =
m_tree->Bronch (name.c_str(), cls->GetName(), 0);
554 return StatusCode::FAILURE;
556 TBranchElement* bre =
dynamic_cast<TBranchElement*
> (br);
558 REPORT_MESSAGE (MSG::ERROR) <<
"Unexpected branch type created for "
560 return StatusCode::FAILURE;
564 ptr = bre->GetObject();
568 br->SetTitle (docstring.c_str());
581 for (Long64_t i = 0; i <
m_tree->GetEntries(); i++)
584 return StatusCode::SUCCESS;
606 const std::type_info& ,
613 <<
"addDimensionedVariable not yet implemented.";
614 return StatusCode::FAILURE;
627 return StatusCode::FAILURE;
628 return StatusCode::SUCCESS;
638 TIter next (gROOT->GetListOfFiles());
639 while (TFile* f =
dynamic_cast<TFile*
>(next())) {
640 if (std::string(f->GetName()) ==
m_poolFile) {
648 <<
" to attach tree " <<
m_tree->GetName();
649 return StatusCode::FAILURE;
652 return StatusCode::SUCCESS;
662 return StatusCode::SUCCESS;
669 return StatusCode::FAILURE;
711 const std::type_info& ti)
717 return StatusCode::RECOVERABLE;
719 if (ti ==
typeid(TString)) {
720 ostmp.String() = *
reinterpret_cast<const TString*
> (obj);
722 cls = gROOT->GetClass (
"TObjString");
724 else if (ti ==
typeid(std::string)) {
725 ostmp.String() = *
reinterpret_cast<const std::string*
> (obj);
727 cls = gROOT->GetClass (
"TObjString");
730 std::string metaname;
731 TDirectory* dir =
m_tree->GetDirectory();
732 std::string thekey = key;
734 if (key.size() > 0 && key[key.size()-1] ==
'/') {
736 while (
dynamic_cast<TDirectoryFile*
> (dir) != 0 &&
738 dir = dir->GetMotherDir();
740 metaname = key.substr (0, key.size()-1);
741 thekey =
m_tree->GetName();
744 metaname =
m_tree->GetName();
748 TDirectory::TContext ctx (dir);
749 TDirectory* metadir = dir->GetDirectory (metaname.c_str());
751 metadir = dir->mkdir (metaname.c_str());
754 <<
"Can't create metadata dir " << metaname
755 <<
"in dir " << dir->GetName();
756 return StatusCode::RECOVERABLE;
761 if (key.size() > 0 && key[key.size()-1] ==
'/') {
763 while (metadir->FindObject (thekey.c_str())) {
765 std::ostringstream
ss;
766 ss <<
m_tree->GetName() <<
"-" << i;
771 if (metadir->WriteObjectAny (obj, cls, thekey.c_str(),
"overwrite") == 0) {
773 <<
"Can't write metadata object " << thekey
774 <<
" for tree " <<
m_tree->GetName();
775 return StatusCode::RECOVERABLE;
778 return StatusCode::SUCCESS;
790 TClass* cls = gROOT->GetClass (ti);
794 std::string tiname = System::typeinfoName (ti);
795 cls = gROOT->GetClass (tiname.c_str());
839 const std::type_info& ti,
843 std::map< std::string, FakeProxy* >::const_iterator itr =
847 <<
"\"Fake\" variable with name \"" << name <<
"\" already created";
848 return StatusCode::FAILURE;
857 return StatusCode::SUCCESS;
864 return StatusCode::SUCCESS;
869 <<
"Couldn't create \"fake\" variable of type: " << ti.name();
870 return StatusCode::FAILURE;
Helpers for checking error return status codes and reporting errors.
#define REPORT_MESSAGE(LVL)
Report a message.
#define REPORT_MESSAGE_WITH_CONTEXT(LVL, CONTEXT_NAME)
Report a message, with an explicitly specified context name.
#define CHECK(...)
Evaluate an expression and check for errors.
Proxy class for storing any kind of object.
static void * newPrimitive(const std::type_info &ti)
Create a new instance of a primitive.
::TClass * getClass(const std::type_info &ti)
Access the dictionary of a specific object.
unsigned int Dim_t
Currently unimplemented — see design note.
int m_entryOffsetLen
Specified entry offset buffer length.
TTree * m_tree
The underlying root tree.
bool isAllowed(const std::string &name)
Decide if a given variable name is allowed.
virtual StatusCode addVariable(const std::string &name, const std::type_info &ti, void *&ptr, const std::string &docstring="", const void *defval=0) override
Add a variable to the tuple.
std::vector< std::string > m_vetoedNames
List of names/regular expressions not allowed to be put into the output tree.
std::map< std::string, FakeProxy * > m_fakeVars
"Fake" variables, only kept in memory
int m_basketSize
Specified basket size.
virtual StatusCode addDimensionedVariable(const std::string &name, const std::type_info &ti, void *&ptr, const std::string &dim, const std::string &docstring="", const void *defval=0) override
Add a variable to the tuple.
std::string m_poolFile
If set, the name of a pool data file to which we should attach ourself.
std::vector< std::string > m_allowedNames
List of names/regular expressions allowed to be put into the output tree.
const TTree * tree() const
Return the underlying root tree.
RootD3PD(TTree *tree, const std::string &master, const std::vector< std::string > &allowedNames=std::vector< std::string >(), const std::vector< std::string > &vetoedNames=std::vector< std::string >(), int basketSize=-1, int entryOffsetLen=-1)
Constructor.
virtual StatusCode capture() override
Capture the current state of all variables and write to the tuple.
Root::Cleartable * m_cleartable
Helper to clear variables.
std::string m_master
The name of the master tree.
StatusCode attachPoolFile()
Try to attach to a pool file, if we haven't yet done so.
virtual StatusCode clear() override
Clear all the tuple variables.
TClass * getClass(const std::type_info &ti)
Try to convert from a std::type_info to a TClass.
const std::string & master() const
Return the name of the master tree.
virtual StatusCode addMetadata(const std::string &key, const void *obj, const std::type_info &ti) override
Add a new piece of metadata to the tuple.
void setPoolFile(const std::string &poolFile)
Set the name of a pool file to which we should attach.
StatusCode addFakeVariable(const std::string &name, const std::type_info &ti, void *&ptr)
Create a variable in memory only.
virtual StatusCode redim(const Dim_t *ptr) override
Currently unimplemented — see design note.
Hold information on how to clear one variable.
enum D3PD::Root::Clearinfo::Cleartype m_type
TVirtualCollectionProxy * m_proxy
The collection proxy for this variable. Used for COLLECTION.
TMethodCall m_meth
The clear method for this variable. Used for CLEAR.
Cleartype
The method to use to clear this variable.
@ CLEAR
Clear variable by calling clear().
@ COLLECTION
Clear variable via collection proxy.
@ COPY
Copy from a default (only for basic types).
@ ZERO
Clear variable by filling with zeros.
@ RESET
Clear variable by deleting and recreating.
TBranchElement * m_bre
The branch element for this variable, Used for COLLECTION, CLEAR, RESET.
StatusCode init(TBranch *br, char *defval, size_t defsize)
Initialize for clearing a variable.
size_t m_defsize
Default value size for COPY.
char * m_default
Default value for COPY. We own this.
void free()
Free allocated memory.
void clear()
Clear the variable.
TLeaf * m_leaf
The leaf for this variable. Used for ZERO.
Table giving information on how to clear all variables in a tree.
void clear()
Clear all branches.
StatusCode add(TBranch *br, char *defval, size_t defsize)
Initialize for clearing a variable.
std::vector< Clearinfo > m_info
Block filler tool for noisy FEB information.