29 *******************************************************************************
30 * * 'Physisics do not like it, *
31 * * physisics do not need it, *
32 * * physisics do not use it' *
33 * * ****************************
35 * Helper module, which effectively 'imports' few useful C++ algorithmic *
36 * base classes into Python *
38 *******************************************************************************
39 * The major imported classes are : *
41 * (1) GaudiAlgo - analogue for GaudiAlgorithm C++ class from GaudiAlg package *
42 * (2) HistoAlgo - analogue for GaudiHistoAlg C++ class from GaudiAlg package *
43 * (3) TupleAlgo - analogue for GaudiTupleAlg C++ class from GaudiAlg package *
44 *******************************************************************************
46 from __future__
import print_function
48 __author__ =
'Vanya BELYAEV Ivan.Belyaev@lapp.in2p3.fr'
80 from GaudiKernel
import ROOT6WorkAroundEnabled
98 AlgDecorator = cpp.GaudiPython.AlgDecorator
99 HistoDecorator = cpp.GaudiPython.HistoDecorator
100 TupleAlgDecorator = cpp.GaudiPython.TupleAlgDecorator
101 TupleDecorator = cpp.GaudiPython.TupleDecorator
129 def _tool_(self, interface, typename, name=None, parent=None, create=True):
131 Useful method to locate the tool a certain
136 t1 = self.tool(ITrExtrapolator,'TrParabolicExtrapolator')
137 # locate private tool
138 t2 = self.tool(ITrExtrapolator,'TrParabolicExtrapolator',parent=self)
139 # locate public tool with defined name
140 t3 = self.tool(ITrExtrapolator,'TrParabolicExtrapolator/MyExt1')
141 # locate private tool with defined name
142 t4 = self.tool(ITrExtrapolator,'TrParabolicExtrapolator/MyExt2',parent=self)
143 # locate public tool with defined name
144 t5 = self.tool(ITrExtrapolator,'TrParabolicExtrapolator','MyExt3')
145 # locate private tool with defined name
146 t6 = self.tool(ITrExtrapolator,'TrParabolicExtrapolator','MyExt4',parent=self)
150 interface = cpp.IAlgTool
154 typename +=
'/' + name
155 _tool = AlgDecorator.tool_(self, typename, parent, create)
160 self.Warning(
'Invalid cast to interface %s' % interface)
182 Useful method to locate a service:
186 ntsvc = self.svc( INTupleSvc , 'NTUpleSvc' )
190 interface = cpp.IInterface
191 _svc = AlgDecorator.svc_(self, name, create)
196 self.Warning(
'Invalid cast to interface %s' % interface)
210 The constructor from unique algorithm instance name & parameters
212 self._Base.__init__(self, self, name)
214 algMgr = appMgr._algmgr
215 status = algMgr.addAlgorithm(self)
216 if status.isFailure():
217 raise RuntimeError(
'Unable to add Algorithm "' + name +
'"')
220 setattr(self, key, args[key])
222 if 'GaudiPythonAlgos' not in appMgr.__dict__:
223 appMgr.__dict__[
'GaudiPythonAlgos'] = []
224 appMgr.__dict__[
'GaudiPythonAlgos'].append(self)
236 The default initialization (initialization of base C++ class + data)
238 status = self._Base.initialize_(self)
239 if status.isFailure():
243 _e = self._Base.evtSvc(self)
247 _d = self._Base.detSvc(self)
263 The default initialization (initialization of base C++ class + data members)
266 if status.isFailure():
270 _h = self._Base.histoSvc(self)
286 The default initialization (initialization of base C++ class + data members)
289 if status.isFailure():
293 if self.produceNTuples():
294 _n = self._Base.ntupleSvc(self)
298 if self.produceEvtCols():
299 _n = self._Base.evtColSvc(self)
327 Trivial helper function to access Event Data and Event Data Service
331 # get event data service
335 hits = self.evtSvc('MC/Calo/Hits')
339 return self._evtSvc_[location]
363 Trivial helper function to access Detector Data and Event Data Service
366 # get detector data service
370 lhcb = self.detSvc('/dd/Structure/LHCb')
374 return self._detSvc_[location]
398 Trivial helper function to access Histogram Data and Histogram Data Service
402 # get histogram data service
403 svc = self.histoSvc()
406 histo = self.histoSvc('/stat/Calo/1')
409 return self._histoSvc_
410 return self._histoSvc_[address]
419 Trivial function to access the data in TES using the data service
421 return self._evtSvc_[location]
430 Trivial function to access the data in TDS using data service
432 return self._detSvc_[location]
439 def _get_(self, location, rootInTES=True):
441 Get the object from Transient Event Store using GaudiCommon machinery,
442 respecting RootInTES behaviour
444 return AlgDecorator.get_(self, location, rootInTES)
453 Check the object in Transient Event Store using GaudiCommon machinery,
454 respecting RootInTES behaviour
456 return AlgDecorator.exist_(self, location, rootInTES)
465 Trivial function to access N-Tuple Service
467 return self._ntupleSvc_
476 Trivial function to access Event Collection Service
478 return self._evtcolSvc_
485 The default finalization : finalize the base C++ class
487 status = self._Base.finalize_(self)
503 The trivial function which checks the existence of the property with given name
505 return cpp.Gaudi.Utils.hasProperty(self, pname)
514 Get the property by name
516 if not self.hasProperty(pname):
517 raise AttributeError(
'property %s does not exist' % pname)
518 return self._ialg.__getattr__(pname)
527 Set the property from the value
529 if not self.hasProperty(pname):
530 raise AttributeError(
'property %s does not exist' % pname)
531 return self._ialg.__setattr__(pname, pvalue)
540 Get the attribute (or property)
541 - if the attribute name corresponds to the property name, property value is returned
543 if self.hasProperty(pname):
544 return self._ialg.__getattr__(pname)
549 return getattr(self._ialg, pname)
550 except AttributeError:
552 raise AttributeError(
'attribute/property %s does not exist' % pname)
561 Set the attribute (or property) :
562 - if the attribute name corresponds to the property name, the property is updated
564 if not self.hasProperty(pname):
565 self.__dict__[pname] = pvalue
567 self._ialg.__setattr__(pname, pvalue)
570 _GaudiAlgorithm = cpp.GaudiPython.PyAlg(
'GaudiAlgorithm')
571 _GaudiHistoAlg = cpp.GaudiPython.PyAlg(
'GaudiHistoAlg')
572 _GaudiTupleAlg = cpp.GaudiPython.PyAlg(
'GaudiTupleAlg')
641 *******************************************************************************
642 * * 'Physisics do not like it, *
643 * * physisics do not need it, *
644 * * physisics do not use it' *
645 * * ****************************
648 * from GaudiPython.GaudiAlgs import GaudiAlgo, SUCCESS *
650 * class MyClass(GaudiAlgo) : *
651 * ' My specific Algorithm, derived from GaudiAlgo base class ' *
652 * def __init__( self , name , **args ) : *
653 * 'Constructor from algorithm instance name & parameters' *
654 * #invoke the constructor of base class *
655 * GaudiAlgo.__init__(self , name , **args ) *
657 * def initialize ( self ) : *
658 * 'Algorithm initialization' *
659 * # initialize the base class *
660 * status = GaudiAlgo.initialize( self ) *
661 * if status.isFailure() : return status *
663 * # locate the services and tools *
665 * # locate some tool: *
666 * extrapolator = self.tool(ITrExtrapolator,'TrExtrapolator') *
668 * # locate the service *
669 * rndmSvc = self.svc(IRndmGenSvc, 'RndmGenSvc') *
674 * def execute ( self ) : *
675 * 'Major method (from IAlgorithm interface)' *
677 * # get some data from Transient Event Store *
678 * tracks = self.get('/Event/Rec/Tracks') *
681 * c1 = self.counter('#Tracks') *
682 * c2 = self.counter('No Tracks') *
683 * if tracks.empty : *
685 * c1 += tracks->size() *
687 * if 1000 < tracks.size() : *
688 * return self.Error('The event is *VERY* busy') *
692 *******************************************************************************
770 *******************************************************************************
771 * * 'Physisics do not like it, *
772 * * physisics do not need it, *
773 * * physisics do not use it' *
774 * * ****************************
777 * from GaudiPython.GaudiAlgs import HistoAlgo, SUCCESS *
779 * class MyClass(HistoAlgo) : *
780 * ' My specific Algorithm, derived from GaudiAlgo base class ' *
781 * def __init__( self , name , **args ) : *
782 * 'Constructor from algorithm instance name' *
783 * #invoke the constructor of base class *
784 * HistoAlgo.__init__(self , name , **args ) *
786 * def execute ( self ) : *
787 * 'Major method (from IAlgorithm interface)' *
789 * # get some data from Transient Event Store *
790 * tracks = self.get('/Event/Rec/Tracks') *
792 * self.plot1D ( tracks->size() , '#tracks' , 0 , 100 ) *
796 * Alternatively the histogram could be booked in advance: *
798 * class MyClass(HistoAlgo) : *
799 * ' My specific Algorithm, derived from GaudiAlgo base class ' *
800 * def __init__( self , name ) : *
801 * 'Constructor from algorithm instance name' *
802 * #invoke the constructor of base class *
803 * HistoAlgo.__init__(self , name ) *
805 * def initialize ( self ) : *
806 * 'Algorithm initialization' *
807 * # initialize the base class *
808 * status = HistoAlgo.initialize( self ) *
809 * if status.isFailure() : return status *
811 * # book the histogram *
812 * self.h1 = selff.book1D ( '#tracks' , 0 , 100 ) *
817 * def execute ( self ) : *
818 * 'Major method (from IAlgorithm interface)' *
820 * # get some data from Transient Event Store *
821 * tracks = self.get('/Event/Rec/Tracks') *
823 * # fill the histogram *
824 * self.h1.fill ( tracks->size() ) *
828 *******************************************************************************
883 *******************************************************************************
884 * * 'Physisics do not like it, *
885 * * physisics do not need it, *
886 * * physisics do not use it' *
887 * * ****************************
890 * from GaudiPython.GaudiAlgs import TupleAlgo, SUCCESS *
892 * class MyClass(TupleAlgo) : *
893 * ' My specific Algorithm, derived from TupleAlgo base class ' *
894 * def __init__( self , name , **args ) : *
895 * 'Constructor from algorithm instance name & parameters' *
896 * #invoke the constructor of base class *
897 * TupleAlgo.__init__(self , name , **args ) *
899 * def execute ( self ) : *
900 * 'Major method (from IAlgorithm interface)' *
902 * # get some data from Transient Event Store *
903 * tracks = self.get('/Event/Rec/Tracks') *
905 * tup = self.nTuple('My N-Tuple') *
907 * for track in tracks : *
911 * chi2 = track.chi2 () *
914 * tup.column ( 'pt' , pt ) *
915 * tup.column ( 'p' , p ) *
916 * tup.column ( 'chi2' , chi2 ) *
922 *******************************************************************************
936 GaudiAlgo._Base = _GaudiAlgorithm
937 HistoAlgo._Base = _GaudiHistoAlg
938 TupleAlgo._Base = _GaudiTupleAlg
941 GaudiAlgo.initialize = _initialize_
942 HistoAlgo.initialize = _initialize_histo_
943 TupleAlgo.initialize = _initialize_tuple_
948 The stub 'start' method needed by the internal implementation of PyAlg<>.
954 GaudiAlgo.start = _start_
955 HistoAlgo.start = _start_
956 TupleAlgo.start = _start_
961 The fictive 'execute' method, which MUST be overwitten by user
964 'Execute method is not implemented for %s' % self.name())
967 GaudiAlgo.execute = _execute_
968 HistoAlgo.execute = _execute_
969 TupleAlgo.execute = _execute_
974 The stub 'stop' method needed by the internal implementation of PyAlg<>.
980 GaudiAlgo.stop = _stop_
981 HistoAlgo.stop = _stop_
982 TupleAlgo.stop = _stop_
989 The basic method to fill (book-on-demand) 1D-histogram
991 The histogram will be created/booked dautomatically according to the
994 - literal or numerical ID (optional)
998 - number of bins (default is 100)
1000 The reference to the histogram is returned and could be used for later manipulations
1003 return HistoDecorator.plot1D(s, *a)
1011 The basic method to fill (book-on-demand) 2D-histogram
1013 The histogram will be created/booked dautomatically according to the
1016 - literal or numerical ID (optional)
1022 - number of X-bins (default is 50)
1023 - number of Y-bins (default is 50)
1025 The reference to the histogram is returned and could be used for later manipulations
1028 return HistoDecorator.plot2D(s, *a)
1036 The basic method to fill (book-on-demand) 3D-histogram
1038 The histogram will be created/booked dautomatically according to the
1041 - literal or numerical ID (optional)
1049 - number of X-bins (default is 10)
1050 - number of Y-bins (default is 10)
1051 - number of Y-bins (default is 10)
1053 The reference to the histogram is returned and could be used for later manipulations
1056 return HistoDecorator.plot3D(s, *a)
1064 The basic method to fill (book-on-demand) 1D profile histogram
1066 The profile histogram will be created/booked dautomatically
1067 according to the specifications:
1069 - literal or numerical ID (optional)
1073 - number of X-bins (default is 100)
1075 The reference to the histogram is returned and could be used for later manipulations
1078 return HistoDecorator.profile1D(s, *a)
1086 The basic method to fill (book-on-demand) 2D profile histiogram
1088 The profile histogram will be created/booked automatically
1089 according to the specifications:
1091 - literal or numerical ID (optional)
1097 - number of X-bins (default is 50)
1098 - number of Y-bins (default is 50)
1100 The reference to the histogram is returned and could be used for later manipulations
1103 return HistoDecorator.profile2D(s, *a)
1108 _plot1D_.__doc__ +=
'\n' + HistoDecorator.plot1D.__doc__
1109 _plot2D_.__doc__ +=
'\n' + HistoDecorator.plot2D.__doc__
1110 _plot3D_.__doc__ +=
'\n' + HistoDecorator.plot3D.__doc__
1111 _profile1D_.__doc__ +=
'\n' + HistoDecorator.profile1D.__doc__
1112 _profile2D_.__doc__ +=
'\n' + HistoDecorator.profile2D.__doc__
1117 if not issubclass(t, list)
and \
1118 not issubclass(t, tuple):
1120 for klass
in klasses:
1121 klass.plot = _plot1D_
1122 klass.plot1D = _plot1D_
1123 klass.plot2D = _plot2D_
1124 klass.plot3D = _plot3D_
1125 klass.profile1D = _profile1D_
1126 klass.profile2D = _profile2D_
1136 Retrieve (book-on-demand) N-Tuple object
1138 return TupleAlgDecorator.nTuple(s, *a)
1146 Retrieve (book-on-demand) N-Tuple object for Event Tag Collections
1148 return TupleAlgDecorator.evtCol(s, *a)
1151 _nTuple_.__doc__ +=
'\n' + TupleAlgDecorator.nTuple.__doc__
1152 _evtCol_.__doc__ +=
'\n' + TupleAlgDecorator.evtCol.__doc__
1157 if not issubclass(t, list)
and \
1158 not issubclass(t, tuple):
1160 for klass
in klasses:
1161 klass.nTuple = _nTuple_
1162 klass.evtCol = _evtCol_
1163 klass.ntupleSvc = _ntupleSvc
1164 klass.tupleSvc = _ntupleSvc
1165 klass.ntupSvc = _ntupleSvc
1166 klass.tupSvc = _ntupleSvc
1167 klass.evtColSvc = _evtcolSvc
1168 klass.evtcolSvc = _evtcolSvc
1175 Tuple = cpp.Tuples.Tuple
1176 _Dec = TupleDecorator
1180 '''Helper decorator class to workaround ROOT-6697'''
1185 dispatcher = func.disp
if hasattr(func,
'disp')
else func.__overload__
1187 mapping = {int:
'int', bool:
'bool', float:
'double'}
1189 signature =
'const Tuples::Tuple& tuple, const string& name, const %s value' % (
1191 mapping[k] = dispatcher(signature)
1196 Explicitly call the explicit signature for the case with 3 arguments and
1197 the last one is 'int', 'bool' or 'float', for the other cases fall back
1198 on the default dispatcher.
1206 return self.
func(*a)
1210 _Dec.column,
"disp")
or hasattr(_Dec.column,
"__overload__")):
1216 Access to underlying INTuple object
1218 return _Dec.nTuple(s, *a)
1223 Access to underlying NTuple::Tuple object
1225 return _Dec.ntuple(s, *a)
1230 Valid NTuple::Tuple object?
1232 return _Dec.valid(s, *a)
1237 Commit the row/record to n-tuple
1239 return _Dec.write(s, *a)
1244 Fill the certain column to n-tuple
1246 return _Dec.column(s, *a)
1251 Fill the 'long long' column
1253 return _Dec.column_ll(s, *a)
1258 Fill the 'unsigned long long' column
1260 return _Dec.column_ull(s, *a)
1265 Fill the fixed-size array column
1267 return _Dec.array(s, *a)
1272 Fill the fixed-size matrix column
1274 return _Dec.matrix(s, *a)
1279 Fill the floating-size array column
1281 return _Dec.farray(s, *a)
1286 Fill the floating-size matrix column
1288 return _Dec.fmatrix(s, *a)
1291 _t_nTuple_.__doc__ +=
'\n' + _Dec.nTuple.__doc__
1292 _t_ntuple_.__doc__ +=
'\n' + _Dec.ntuple.__doc__
1293 _t_valid_.__doc__ +=
'\n' + _Dec.valid.__doc__
1294 _t_write_.__doc__ +=
'\n' + _Dec.write.__doc__
1295 _t_column_.__doc__ +=
'\n' + _Dec.column.__doc__
1296 _t_column_ll_.__doc__ +=
'\n' + _Dec.column_ll.__doc__
1297 _t_column_ull_.__doc__ +=
'\n' + _Dec.column_ull.__doc__
1298 _t_array_.__doc__ +=
'\n' + _Dec.array.__doc__
1299 _t_matrix_.__doc__ +=
'\n' + _Dec.matrix.__doc__
1300 _t_farray_.__doc__ +=
'\n' + _Dec.farray.__doc__
1301 _t_fmatrix_.__doc__ +=
'\n' + _Dec.fmatrix.__doc__
1303 Tuple.nTuple = _t_nTuple_
1304 Tuple.ntuple = _t_ntuple_
1305 Tuple.valid = _t_valid_
1306 Tuple.write = _t_write_
1307 Tuple.column = _t_column_
1308 Tuple.column_ll = _t_column_ll_
1309 Tuple.column_ull = _t_column_ull_
1310 Tuple.array = _t_array_
1311 Tuple.matrix = _t_matrix_
1312 Tuple.farray = _t_farray_
1313 Tuple.fmatrix = _t_fmatrix_
1320 'eventSvc': _evtSvc,
1322 'histoSvc': _histoSvc,
1323 'histSvc': _histoSvc,
1328 'finalize': _finalize_,
1332 'getProperty': _getProperty_,
1333 'setProperty': _setProperty_,
1334 '__setattr__': _set_attr_,
1335 '__getattr__': _get_attr_
1342 if not issubclass(t, list)
and \
1343 not issubclass(t, tuple):
1345 for _alg
in klasses:
1346 for key
in _alg_map_:
1347 setattr(_alg, key, _alg_map_[key])
1361 """ Helper function to fill histogram/ntuple using 'map'-operation """
1366 if hasattr(sequence,
'size'):
1367 vct.reserve(vct.size() + sequence.size())
1368 elif hasattr(sequence,
'__len__'):
1369 vct.reserve(vct.size() + len(sequence))
1370 for object
in sequence:
1371 vct.push_back(
func(object))
1387 _func = getattr(AlgDecorator, method)
1388 _num = _func(self, _tools)
1389 if _tools.size() != _num:
1390 raise RuntimeError(
'Unable to extract Tools')
1392 for _tool
in _tools:
1393 _res += [
iAlgTool(_tool.name(), _tool)]
1402 Retrieve the list of tools,
1403 aquired by component through GaudiCommon<TYPE> base:
1405 >>> alg = ... ## get the algorithm
1406 >>> tools = alg.Tools() ## get the tools
1407 >>> for tool in tools :
1411 _cmp = getattr(self,
'_ialg')
1413 self.retrieveInterface()
1414 _cmp = getattr(self,
'_ialg')
1423 Retrieve the list of tools,
1424 aquired by component through GaudiCommon<TYPE> base:
1426 >>> tool = ... ## get the tool
1427 >>> tools = tool.Tools() ## get the tools
1428 >>> for t in tools :
1432 _cmp = getattr(self,
'_itool')
1434 self.retrieveInterface()
1435 _cmp = getattr(self,
'_itool')
1448 _func = getattr(AlgDecorator, method)
1449 return _func(self, name)
1457 Retrieve the counter managed GaudiCommon<TYPE> base by name:
1459 >>> alg = ... ## get the algorithm
1460 >>> cnt = alg.Counter('#accept') ## get the counter
1464 _cmp = getattr(self,
'_ialg')
1466 self.retrieveInterface()
1467 _cmp = getattr(self,
'_ialg')
1476 Retrieve the counter managed GaudiCommon<TYPE> base by name:
1478 >>> tool = ... ## get the tool
1479 >>> cnt = tool.Counter('#accept') ## get the counter
1483 _cmp = getattr(self,
'_itool')
1485 self.retrieveInterface()
1486 _cmp = getattr(self,
'_itool')
1493 cpp.GaudiAlg.ID.__repr__ = cpp.GaudiAlg.ID.idAsString
1494 cpp.GaudiAlg.ID.__str__ = cpp.GaudiAlg.ID.idAsString
1495 cpp.StatEntity.__repr__ = cpp.StatEntity.toString
1496 cpp.StatEntity.__str__ = cpp.StatEntity.toString
1503 Get All histogram form the component
1506 for _his
in (
std.vector(
'AIDA::IProfile2D*'),
1513 _fun = getattr(HistoDecorator, method)
1514 _num = _fun(component, _ids, _his)
1515 if _ids.size() != _num
or _his.size() != _num:
1516 raise RuntimeError(
'Unable to extract Histos!')
1517 for _i
in range(0, _num):
1520 _id = _id.numericID()
1522 _id = _id.literalID()
1524 _id = _is.idAsString()
1525 _res[_id] = _his[_i]
1530 id = cpp.GaudiAlg.ID(name)
1531 for i
in (name, id.literalID(), id.numericID(), id.idAsString(), id):
1532 h = _res.get(i,
None)
1544 Retrieve all histograms & profiles, booked through GauydiHistos<TYPE> base:
1546 >>> alg = ... ## get the algorithm
1547 >>> histos = alg.Histos() ## get all histograms & profiles
1548 >>> for key in histos :
1549 ... print(key, histos[key])
1551 Retrive the histogram with the certain ID :
1553 >>> alg = ... ## get the algorithm
1554 >>> histo = alg.Histos('some histo ID') ## get the histo by ID
1558 _cmp = getattr(self,
'_ialg')
1560 self.retrieveInterface()
1561 _cmp = getattr(self,
'_ialg')
1570 Retrieve all histograms & profiles, booked through GauydiHistos<TYPE> base:
1572 >>> tool = ... ## get the tool
1573 >>> histos = tool.Histos() ## get all histograms & profiles
1574 >>> for key in histos :
1575 ... print(key, histos[key])
1577 Retrive the historgam with certain ID :
1579 >>> tool = ... ## get the tool
1580 >>> histo = tool.Histos('some histo ID') ## get the histo by ID
1584 _cmp = getattr(self,
'_itool')
1586 self.retrieveInterface()
1587 _cmp = getattr(self,
'_itool')
1593 _Tools_a_.__doc__ +=
'\n' + AlgDecorator._tools_a_.__doc__
1594 _Tools_t_.__doc__ +=
'\n' + AlgDecorator._tools_t_.__doc__
1595 _Counter_a_.__doc__ +=
'\n' + AlgDecorator._counter_a_.__doc__
1596 _Counter_t_.__doc__ +=
'\n' + AlgDecorator._counter_t_.__doc__
1597 _Histos_a_.__doc__ +=
'\n' + HistoDecorator._histos_a_.__doc__
1598 _Histos_t_.__doc__ +=
'\n' + HistoDecorator._histos_t_.__doc__
1600 iAlgorithm.Tools = _Tools_a_
1601 iAlgTool.Tools = _Tools_t_
1602 iAlgorithm.Counter = _Counter_a_
1603 iAlgTool.Counter = _Counter_t_
1604 iAlgorithm.Histos = _Histos_a_
1605 iAlgTool.Histos = _Histos_t_
1616 print(__doc__, __author__)
1617 print(
'\t\t\tDoc-string for class GaudiAlgo \n', GaudiAlgo.__doc__)
1618 print(
'\t\t\tDoc-string for class HistoAlgo \n', HistoAlgo.__doc__)
1619 print(
'\t\t\tDoc-string for class TupleAlgo \n', TupleAlgo.__doc__)
1625 if __name__ ==
'__main__':