diff --git a/PyRDF/Operation.py b/PyRDF/Operation.py index 69068e8..357d80c 100644 --- a/PyRDF/Operation.py +++ b/PyRDF/Operation.py @@ -32,7 +32,7 @@ class Operation(object): print(PyRDF.current_backend.supported_operations) """ - Types = Enum("Types", "ACTION TRANSFORMATION INSTANT_ACTION") + Types = Enum("Types", "ACTION TRANSFORMATION INSTANT_ACTION INFO") def __init__(self, name, *args, **kwargs): """ @@ -80,7 +80,15 @@ def _classify_operation(self, name): 'Take': ops.ACTION, 'Graph': ops.ACTION, 'Snapshot': ops.INSTANT_ACTION, - 'Foreach': ops.INSTANT_ACTION + 'Foreach': ops.INSTANT_ACTION, + 'Alias': ops.INFO, + 'GetColumnNames': ops.INFO, + 'GetDefinedColumnNames': ops.INFO, + 'GetColumnType': ops.INFO, + 'GetColumnTypeNamesList': ops.INFO, + 'GetFilterNames': ops.INFO, + 'Display': ops.INFO, + 'SaveGraph': ops.INFO } op_type = operations_dict.get(name) @@ -107,3 +115,13 @@ def is_transformation(self): False otherwise. """ return self.op_type == Operation.Types.TRANSFORMATION + + def is_info(self): + """ + Checks if the current operation is an info. + + Returns: + bool: True if the current operation is an info, + False otherwise. + """ + return self.op_type == Operation.Types.INFO diff --git a/PyRDF/Proxy.py b/PyRDF/Proxy.py index a6aa7fb..12b6fcd 100644 --- a/PyRDF/Proxy.py +++ b/PyRDF/Proxy.py @@ -3,6 +3,7 @@ from abc import ABCMeta, abstractmethod from PyRDF.Operation import Operation from PyRDF.Node import Node +import ROOT # Abstract class declaration # This ensures compatibility between Python 2 and 3 versions, since in # Python 2 there is no ABC class @@ -89,6 +90,28 @@ def _call_action_result(self, *args, **kwargs): return getattr(self.GetValue(), self._cur_attr)(*args, **kwargs) +def _trigger_info_operation(node, op, *args, **kwargs): + """ + Function to retrieve the PyROOT node objects defined by the user + up to the point of calling an Info operation. This function triggers the + creation of PyROOT objects in order to call the ROOT function issued by the + user. + """ + generator = CallableGenerator(node.get_head()) + + mapper = generator.get_callable() # Get the callable + + # Create a PyROOT RDataFrame + pyroot_rdf = ROOT.ROOT.RDataFrame(*generator.head_node.args) + + # Execute the mapper function + mapper(pyroot_rdf) + + # Call the function on the PyROOT object with the arguments provided by + # the user. + return getattr(node.pyroot_node, op.name)(*args, **kwargs) + + class TransformationProxy(Proxy): """ A proxy object to an non-action node. It implements acces to attributes @@ -133,8 +156,15 @@ def _create_new_op(self, *args, **kwargs): # Add the new node as a child of the current node self.proxied_node.children.append(newNode) - # Return the appropriate proxy object for the node + # Behave accordingly to the type of the operation if op.is_action(): return ActionProxy(newNode) + elif op.is_info(): + return _trigger_info_operation( + self.proxied_node, + op, + *args, + **kwargs + ) else: return TransformationProxy(newNode) diff --git a/PyRDF/backend/Backend.py b/PyRDF/backend/Backend.py index 69ff786..90cb8e2 100644 --- a/PyRDF/backend/Backend.py +++ b/PyRDF/backend/Backend.py @@ -40,7 +40,15 @@ class Backend(ABC): 'Foreach', 'Reduce', 'Aggregate', - 'Graph' + 'Graph', + 'Alias', + 'GetColumnNames', + 'GetDefinedColumnNames', + 'GetColumnType', + 'GetColumnTypeNamesList', + 'GetFilterNames', + 'Display', + 'SaveGraph' ] initialization = staticmethod(lambda: None) diff --git a/PyRDF/backend/Local.py b/PyRDF/backend/Local.py index 04d0b58..e57258d 100644 --- a/PyRDF/backend/Local.py +++ b/PyRDF/backend/Local.py @@ -28,6 +28,14 @@ def __init__(self, config={}): 'Foreach', 'Reduce', 'Aggregate', + 'Alias', + 'GetColumnNames', + 'GetDefinedColumnNames', + # 'GetColumnType', + 'GetColumnTypeNamesList', + 'GetFilterNames', + 'Display', + 'SaveGraph' ] if ROOT.ROOT.IsImplicitMTEnabled(): # Add `Range` operation only if multi-threading