ATLAS Offline Software
Classes | Typedefs | Functions
RootUtils Namespace Reference

Classes

class  ILogger
 Very simple interface for writing log messages. More...
 
class  InitHist
 Initialize Root's getline history. More...
 
class  PyBytes
 
class  PyGILStateEnsure
 
class  PyLogger
 A concrete implementation of ILogger that calls back to Python. More...
 
class  PyROOTInspector
 
class  PyROOTIteratorFuncs
 Provide functions for iterator comparisons. More...
 
class  PyROOTPickle
 
class  PyROOTTTreePatch
 
class  PyROOTTypePatch
 Work around pyroot problem with __pair_base. More...
 
class  ScatterH2
 A 2-D histogram that can draw a proper scatter plot. More...
 
class  TRandomTLS
 Thread-local TRandom generator. More...
 
class  TreeNotifier
 Tree notification handler. More...
 
class  TSMethodCall
 Helper for making a thread-safe function call. More...
 
class  Type
 Wrapper for ROOT types. More...
 
class  WithRootErrorHandler
 Run a MT piece of code with an alternate root error handler. More...
 

Typedefs

using PyException = CPyCppyy::PyException
 

Functions

std::pair< std::string, bool > PyGetString (PyObject *s)
 Convert python string -> C++ string for py2 and py3. More...
 
PyBytes _pythonize_read_root_file (TFile *f, Int_t len)
 read len bytes from file f More...
 
Long64_t _pythonize_tell_root_file (TFile *f)
 tell the current position in file f More...
 
PyObjectCPPInstanceReduce (PyObject *self, PyObject *)
 PyROOT object proxy pickle support. More...
 
PyObjectCPPInstanceExpand (PyObject *, PyObject *args)
 Helper for (un)pickling of CPPInstance's. More...
 
PyObjecttreeSetNotify (PyObject *, PyObject *args)
 Implementation for pythonization of TTree::SetNotify. More...
 
PyObjecttreeGetNotify (PyObject *, PyObject *args)
 Implementation for pythonization of TTree::SetNotify. More...
 
PyObjectbranchSetAddress (PyObject *, PyObject *args)
 Pythonization of TBranch::SetAddress. More...
 
void installMethod (PyObject *pyclass, PyMethodDef &pdef, const char *name, PyCFunction cfunc)
 Helper to install a method in a Python class. More...
 
int GetBuffer (PyObject *pyobject, char tc, int size, void *&buf, Bool_t check)
 
PyObjectgetRootModule ()
 
PyObjectrootModule ()
 
TClass * objectIsA (PyObject *obj)
 
PyObjectgetSetOwnershipFunc ()
 
PyObjectsetOwnershipFunc ()
 
bool setOwnership (PyObject *obj, bool flag)
 

Typedef Documentation

◆ PyException

using RootUtils::PyException = typedef CPyCppyy::PyException

Definition at line 24 of file Utility.h.

Function Documentation

◆ _pythonize_read_root_file()

PyBytes RootUtils::_pythonize_read_root_file ( TFile *  f,
Int_t  len 
)

read len bytes from file f

Definition at line 60 of file PyROOTTFilePythonize.cxx.

61 {
62  if (!f) {
63  //err
64  return PyBytes(0);
65  }
66 
67  Long64_t totsz = f->GetSize();
68  Long64_t curpos = _pythonize_tell_root_file(f);
69  Long64_t remain = totsz - curpos;
70  remain = (remain>0) ? remain : 0;
71 
72  len = (len>remain) ? remain : len;
73  PyBytes buf(len);
74  if (f->ReadBuffer((char*)buf.buf.data(), buf.sz)) {
75  //err
76  return PyBytes(0);
77  }
78 
79  f->Seek(buf.sz + curpos);
80  return buf;
81 }

◆ _pythonize_tell_root_file()

Long64_t RootUtils::_pythonize_tell_root_file ( TFile *  f)

tell the current position in file f

Definition at line 49 of file PyROOTTFilePythonize.cxx.

50 {
51  if (f) {
52  return f->GetRelOffset();
53  }
54  fprintf (stderr,
55  "::RootUtils::_pythonize_tell_root_file got a NULL TFile ptr!\n");
56  return 0;
57 }

◆ branchSetAddress()

PyObject* RootUtils::branchSetAddress ( PyObject ,
PyObject args 
)

Pythonization of TBranch::SetAddress.

Parameters
argsThe Python arguments.

Definition at line 257 of file PyROOTTTreePatch.cxx.

258 {
259  // Decode arguments --- the branch and the buffer.
260  PyObject* self = 0;
261  PyObject* address = 0;
262  if ( ! PyArg_ParseTuple( args, const_cast< char* >( "OO:SetBranchAddress" ),
263  &self, &address ) )
264  return 0;
265 
266  // The branch as a Root object.
267  TBranch* branch = 0;
268  if (TPython::CPPInstance_Check (self)) {
269  branch = (TBranch*)objectIsA(self)->DynamicCast
270  ( TBranch::Class(),
271  TPython::CPPInstance_AsVoidPtr(self) );
272  }
273 
274  if ( ! branch ) {
275  PyErr_SetString( PyExc_TypeError,
276  "TBranch::SetAddress must be called with a "
277  "TBranch instance as first argument" );
278  return 0;
279  }
280 
281  // Convert the buffer argument to an address.
282  void* buf = 0;
283  if ( TPython::CPPInstance_Check( address ) ) {
284  if ( ((CPPInstance*)address)->fFlags & CPPInstance::kIsReference )
285  buf = (void*)((CPPInstance*)address)->fObject;
286  else
287  buf = (void*)&((CPPInstance*)address)->fObject;
288  } else
289  RootUtils::GetBuffer( address, '*', 1, buf, kFALSE );
290 
291  // Make the call and return.
292  if ( buf != 0 )
293  branch->SetAddress( buf );
294 
295  Py_INCREF( Py_None );
296  return Py_None;
297 }

◆ CPPInstanceExpand()

PyObject* RootUtils::CPPInstanceExpand ( PyObject ,
PyObject args 
)

Helper for (un)pickling of CPPInstance's.

Parameters
argsThe Python arguments.

Definition at line 86 of file PyROOTPickle.cxx.

87 {
88  // This method is a helper for (un)pickling of CPPInstance instances.
89  PyObject* pybuf = 0;
90  const char* clname = 0;
91  if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!s:__expand__" ),
92  &PyUnicode_Type, &pybuf, &clname ) )
93  return 0;
94 
95  // use the PyString macros to by-pass error checking; do not adopt the buffer,
96  // as the local TBufferFile can go out of scope (there is no copying)
97  TBufferFile buf( TBuffer::kRead,
98  PyUnicode_GET_LENGTH( pybuf ),
99  (char*)PyGetString( pybuf ).first.c_str(),
100  kFALSE );
101 
102  void* result = buf.ReadObjectAny( 0 );
103  return TPython::CPPInstance_FromVoidPtr( result, clname );
104 }

◆ CPPInstanceReduce()

PyObject* RootUtils::CPPInstanceReduce ( PyObject self,
PyObject  
)

PyROOT object proxy pickle support.

Parameters
selfobject proxy instance to be pickled

Definition at line 36 of file PyROOTPickle.cxx.

37 {
38  // Turn the object proxy instance into a character stream and return for
39  // pickle, together with the callable object that can restore the stream
40  // into the object proxy instance.
41 
42  void* vself = TPython::CPPInstance_AsVoidPtr( self ); // checks type
43  if ( ! vself ) {
44  PyErr_SetString( PyExc_TypeError,
45  "__reduce__ requires an object proxy instance as first argument" );
46  return 0;
47  }
48 
49  PyObject* nattr = PyObject_GetAttrString( (PyObject*)self->ob_type, (char*)"__name__" );
50  PyObject* pyname = PyObject_Str( nattr );
51  Py_DECREF( nattr );
52 
53  std::string klassname = PyGetString( pyname ).first;
54  TClass* klass = TClass::GetClass( klassname.c_str() );
55 
56  // no cast is needed, but WriteObject taking a TClass argument is protected,
57  // so use WriteObjectAny()
58  TBufferFile buf( TBuffer::kWrite );
59  if ( buf.WriteObjectAny( vself, klass ) != 1 ) {
60  PyErr_Format( PyExc_IOError,
61  "could not stream object of type %s", klassname.c_str() );
62  Py_DECREF( pyname );
63  return 0;
64  }
65 
66  // use a string for the serialized result, as a python buffer will not copy
67  // the buffer contents; use a string for the class name, used when casting
68  // on reading back in
69  PyObject* res2 = PyTuple_New( 2 );
70  PyTuple_SET_ITEM( res2, 0, PyUnicode_FromStringAndSize( buf.Buffer(), buf.Length() ) );
71  PyTuple_SET_ITEM( res2, 1, pyname );
72 
73  PyObject* result = PyTuple_New( 2 );
74  Py_INCREF( gExpand );
75  PyTuple_SET_ITEM( result, 0, gExpand );
76  PyTuple_SET_ITEM( result, 1, res2 );
77 
78  return result;
79 }

◆ GetBuffer()

int RootUtils::GetBuffer ( PyObject pyobject,
char  tc,
int  size,
void *&  buf,
Bool_t  check 
)

Definition at line 26 of file Utility.cxx.

27 {
28 // Retrieve a linear buffer pointer from the given pyobject.
29 
30 // special case: don't handle character strings here (yes, they're buffers, but not quite)
31  if ( PyBytes_Check( pyobject ) )
32  return 0;
33 
34 // attempt to retrieve pointer to buffer interface
35  PyBufferProcs* bufprocs = Py_TYPE(pyobject)->tp_as_buffer;
36 
37  PySequenceMethods* seqmeths = Py_TYPE(pyobject)->tp_as_sequence;
38  if ( seqmeths != 0 && bufprocs != 0
39  && bufprocs->bf_getbuffer != 0
40  ) {
41 
42  // get the buffer
43  Py_buffer bufinfo;
44  (*(bufprocs->bf_getbuffer))( pyobject, &bufinfo, PyBUF_WRITABLE );
45  buf = (char*)bufinfo.buf;
46  Py_ssize_t buflen = bufinfo.len;
47 
48  if ( buf && check == kTRUE ) {
49  // determine buffer compatibility (use "buf" as a status flag)
50  PyObject* pytc = PyObject_GetAttrString( pyobject, "typecode");
51  if ( pytc != 0 ) { // for array objects
52  const char* s = PyUnicode_AsUTF8AndSize( pytc, nullptr );
53  if ( s && s[0] != tc )
54  buf = 0; // no match
55  Py_DECREF( pytc );
56  } else if ( seqmeths->sq_length &&
57  (int)(buflen / (*(seqmeths->sq_length))( pyobject )) == size ) {
58  // this is a gamble ... may or may not be ok, but that's for the user
59  PyErr_Clear();
60  } else if ( buflen == size ) {
61  // also a gamble, but at least 1 item will fit into the buffer, so very likely ok ...
62  PyErr_Clear();
63  } else {
64  buf = 0; // not compatible
65 
66  // clarify error message
67  PyObject* pytype = 0, *pyvalue = 0, *pytrace = 0;
68  PyErr_Fetch( &pytype, &pyvalue, &pytrace );
69  const char* s = PyUnicode_AsUTF8AndSize( pyvalue, nullptr );
70  if (!s) s = "(null)";
71  PyObject* pyvalue2 = PyUnicode_FromFormat(
72  (char*)"%s and given element size (%ld) do not match needed (%d)",
73  s,
74  seqmeths->sq_length ? (Long_t)(buflen / (*(seqmeths->sq_length))( pyobject )) : (Long_t)buflen,
75  size );
76  Py_DECREF( pyvalue );
77  PyErr_Restore( pytype, pyvalue2, pytrace );
78  }
79  }
80 
81  return buflen;
82  }
83 
84  return 0;
85 }

◆ getRootModule()

PyObject* RootUtils::getRootModule ( )

Definition at line 89 of file Utility.cxx.

90 {
91  return PyImport_ImportModule ("ROOT");
92 }

◆ getSetOwnershipFunc()

PyObject* RootUtils::getSetOwnershipFunc ( )

Definition at line 126 of file Utility.cxx.

127 {
128  PyObject* root = rootModule();
129  PyObject* ret = PyObject_GetAttrString (root, "SetOwnership");
130  Py_DECREF (root);
131  return ret;
132 }

◆ installMethod()

void RootUtils::installMethod ( PyObject pyclass,
PyMethodDef &  pdef,
const char *  name,
PyCFunction  cfunc 
)

Helper to install a method in a Python class.

Parameters
pyclassThe Python class.
pdefA PyMethodDef object.
nameThe method name.
cfuncThe C function to install.

Definition at line 307 of file PyROOTTTreePatch.cxx.

311 {
312  pdef.ml_name = const_cast<char*> (name);
313  pdef.ml_meth = cfunc;
314  pdef.ml_flags = METH_VARARGS;
315  pdef.ml_doc = 0;
316 
317  PyObject* func = PyCFunction_New (&pdef, 0);
318  PyObject* method = PyInstanceMethod_New (func);
319  Bool_t isOK = PyObject_SetAttrString (pyclass, pdef.ml_name, method) == 0;
320 
321  if (PyErr_Occurred())
322  fprintf (stderr, "Py error");
323  else if (!isOK) {
324  fprintf (stderr, "Could not add method %s\n", name);
325  }
326 }

◆ objectIsA()

TClass * RootUtils::objectIsA ( PyObject obj)

Definition at line 103 of file Utility.cxx.

104 {
105  TClass* cls = nullptr;
106  PyObject* attr = PyObject_GetAttrString ((PyObject*)Py_TYPE(obj), "__cpp_name__");
107  if (attr) {
108  PyObject* buf = PyUnicode_AsASCIIString (attr);
109  if (buf) {
110  char* s = PyBytes_AsString (buf);
111  if (*s == '<') ++s;
112  if (strncmp (s, "ROOT.", 5) == 0)
113  s += 5;
114  if (strncmp (s, "cppyy.gbl.", 10) == 0)
115  s += 10;
116  cls = TClass::GetClass (s);
117  Py_DECREF(buf);
118  }
119  Py_DECREF(attr);
120  }
121  PyErr_Clear();
122  return cls;
123 }

◆ PyGetString()

std::pair<std::string, bool> RootUtils::PyGetString ( PyObject s)
inline

Convert python string -> C++ string for py2 and py3.

Returns a pair (string, bool); the second element is true of the conversion succeeded.

This should be kept as an inline function to avoid having to have direct dependencies on python where it's not really needed.

Definition at line 40 of file PyGetString.h.

41 {
42  const char* cstr = PyUnicode_AsUTF8AndSize (s, nullptr);
43  if (!cstr && PyBytes_Check (s)) {
44  PyErr_Clear();
45  cstr = PyBytes_AsString (s);
46  }
47  if (cstr) {
48  return std::make_pair (std::string (cstr), true);
49  }
50  return std::make_pair (std::string(), false);
51 }

◆ rootModule()

PyObject* RootUtils::rootModule ( )

Definition at line 95 of file Utility.cxx.

96 {
97  static PyObject* const rootModule = getRootModule();
98  Py_INCREF (rootModule);
99  return rootModule;
100 }

◆ setOwnership()

bool RootUtils::setOwnership ( PyObject obj,
bool  flag 
)

Definition at line 141 of file Utility.cxx.

142 {
143  PyObject* func = setOwnershipFunc();
144  PyObject* ret = PyObject_CallFunction (func, const_cast<char*>("OI"),
145  obj,
146  static_cast<unsigned int>(flag));
147  Py_DECREF (func);
148  if (ret) {
149  Py_DECREF (ret);
150  return true;
151  }
152  return false;
153 }

◆ setOwnershipFunc()

PyObject* RootUtils::setOwnershipFunc ( )

Definition at line 134 of file Utility.cxx.

135 {
136  static PyObject* const func = getSetOwnershipFunc();
137  Py_INCREF (func);
138  return func;
139 }

◆ treeGetNotify()

PyObject* RootUtils::treeGetNotify ( PyObject ,
PyObject args 
)

Implementation for pythonization of TTree::SetNotify.

Parameters
argsThe Python arguments.

Definition at line 230 of file PyROOTTTreePatch.cxx.

231 {
232  // Decode the objects --- the tree.
233  PyObject* self = 0;
234  if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O:SetNotify" ),
235  &self ) )
236  return 0;
237 
238  // Intern string if needed.
239  if (pynotify_str == 0)
240  pynotify_str = PyUnicode_InternFromString("__pynotify__");
241 
242  // Retrieve the notifier.
243  PyObject* ret = PyObject_GetAttr (self, pynotify_str);
244  if (!ret) {
245  PyErr_Clear();
246  Py_INCREF (Py_None);
247  ret = Py_None;
248  }
249  return ret;
250 }

◆ treeSetNotify()

PyObject* RootUtils::treeSetNotify ( PyObject ,
PyObject args 
)

Implementation for pythonization of TTree::SetNotify.

Parameters
argsThe Python arguments.

Definition at line 179 of file PyROOTTTreePatch.cxx.

180 {
181  // Decode the objects --- the tree and the notifier object.
182  PyObject* self = 0;
183  PyObject* obj = 0;
184  if ( ! PyArg_ParseTuple( args, const_cast< char* >( "OO:SetNotify" ),
185  &self, &obj ) )
186  return 0;
187 
188  // Intern strings if needed.
189  if (pynotify_str == 0) {
190  pynotify_str = PyUnicode_InternFromString("__pynotify__");
191  }
192  if (notifier_str == 0) {
193  notifier_str = PyUnicode_InternFromString("__notifier__");
194  }
195 
196  // Set up notifier.
197  if (!PyObject_HasAttr (self, notifier_str)) {
198  // get hold of actual tree
199  void* vp = TPython::CPPInstance_AsVoidPtr (self);
200  TTree* tree =
201  (TTree*)objectIsA(self)->DynamicCast ( TTree::Class(), vp );
202 
203  PyObject* treeobj_ref = PyWeakref_NewRef (self, 0);
204  if (!treeobj_ref)
205  return 0;
206  TObject* notifier = new TreeNotifier (tree, treeobj_ref);
207  PyObject* notobj = TPython::CPPInstance_FromVoidPtr (notifier, "TObject");
208  setOwnership (notobj, true);
209  int stat = PyObject_SetAttr (self, notifier_str, notobj);
210  Py_XDECREF (notobj);
211  if (stat < 0)
212  return 0;
213  tree->SetNotify (notifier);
214  }
215 
216  // Install the object.
217  int stat = PyObject_SetAttr (self, pynotify_str, obj);
218  if (stat < 0)
219  return 0;
220 
221  Py_INCREF (Py_None);
222  return Py_None;
223 }
RunTileTBRec.method
method
Definition: RunTileTBRec.py:73
python.CaloRecoConfig.f
f
Definition: CaloRecoConfig.py:127
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
get_generator_info.result
result
Definition: get_generator_info.py:21
tree
TChain * tree
Definition: tile_monitor.h:30
CaloClusterListBadChannel.cls
cls
Definition: CaloClusterListBadChannel.py:8
get_generator_info.stderr
stderr
Definition: get_generator_info.py:40
RootUtils::getSetOwnershipFunc
PyObject * getSetOwnershipFunc()
Definition: Utility.cxx:126
sendEI_SPB.root
root
Definition: sendEI_SPB.py:34
klass
This class describe the base functionalities of a HypoTool used by the ComboAlg.
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
python.DecayParser.buf
buf
print ("=> [%s]"cmd)
Definition: DecayParser.py:27
RootUtils::objectIsA
TClass * objectIsA(PyObject *obj)
Definition: Utility.cxx:103
ret
T ret(T t)
Definition: rootspy.cxx:260
master.flag
bool flag
Definition: master.py:29
RootUtils::rootModule
PyObject * rootModule()
Definition: Utility.cxx:95
beamspotman.stat
stat
Definition: beamspotman.py:266
RootUtils::setOwnershipFunc
PyObject * setOwnershipFunc()
Definition: Utility.cxx:134
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
RootUtils::getRootModule
PyObject * getRootModule()
Definition: Utility.cxx:89
RTTAlgmain.address
address
Definition: RTTAlgmain.py:55
LArNewCalib_Delay_OFC_Cali.check
check
Definition: LArNewCalib_Delay_OFC_Cali.py:208
RootUtils::PyGetString
std::pair< std::string, bool > PyGetString(PyObject *s)
Convert python string -> C++ string for py2 and py3.
Definition: PyGetString.h:40
RTTAlgmain.branch
branch
Definition: RTTAlgmain.py:61
DeMoScan.first
bool first
Definition: DeMoScan.py:534
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:569
PyROOT::CPPInstance
Definition: PyROOTTTreePatch.cxx:33
RootUtils::setOwnership
bool setOwnership(PyObject *obj, bool flag)
Definition: Utility.cxx:141
RootUtils::GetBuffer
int GetBuffer(PyObject *pyobject, char tc, int size, void *&buf, Bool_t check)
Definition: Utility.cxx:26
python.PyAthena.obj
obj
Definition: PyAthena.py:135
PyObject
_object PyObject
Definition: IPyComponent.h:26
python.CaloScaleNoiseConfig.args
args
Definition: CaloScaleNoiseConfig.py:80
RootUtils::_pythonize_tell_root_file
Long64_t _pythonize_tell_root_file(TFile *f)
tell the current position in file f
Definition: PyROOTTFilePythonize.cxx:49