2121__all__ = ["MonteCarlo" , "AnnealingSchedule" , "GlobalOptimType" ]
2222
2323import warnings
24+ from types import MethodType
25+
2426try :
2527 import ipywidgets as widgets
2628except ImportError :
2729 widgets = None
28- from pyobjcryst ._pyobjcryst import MonteCarlo as MonteCarlo_orig , AnnealingSchedule , GlobalOptimType
30+ from pyobjcryst ._pyobjcryst import MonteCarlo as MonteCarlo_orig , AnnealingSchedule , \
31+ GlobalOptimType , OptimizationObjRegistry
2932from .refinableobj import *
3033
3134
3235class MonteCarlo (MonteCarlo_orig ):
3336
3437 def Optimize (self , nb_step : int , final_cost = 0 , max_time = - 1 ):
3538 self ._fix_parameters_for_global_optim ()
36- super ().Optimize (int (nb_step ), True , final_cost , max_time )
39+ if type (self ) == MonteCarlo_orig :
40+ self ._Optimize (int (nb_step ), True , final_cost , max_time )
41+ else :
42+ super ().Optimize (int (nb_step ), True , final_cost , max_time )
3743
3844 def MultiRunOptimize (self , nb_run : int , nb_step : int , final_cost = 0 , max_time = - 1 ):
3945 self ._fix_parameters_for_global_optim ()
40- super ().MultiRunOptimize (int (nb_run ), int (nb_step ), True , final_cost , max_time )
46+ if type (self ) == MonteCarlo_orig :
47+ self ._MultiRunOptimize (int (nb_run ), int (nb_step ), True , final_cost , max_time )
48+ else :
49+ super ().MultiRunOptimize (int (nb_run ), int (nb_step ), True , final_cost , max_time )
4150
4251 def RunSimulatedAnnealing (self , nb_step : int , final_cost = 0 , max_time = - 1 ):
4352 self ._fix_parameters_for_global_optim ()
44- super ().RunSimulatedAnnealing (int (nb_step ), True , final_cost , max_time )
53+ if type (self ) == MonteCarlo_orig :
54+ self ._RunSimulatedAnnealing (int (nb_step ), True , final_cost , max_time )
55+ else :
56+ super ().RunSimulatedAnnealing (int (nb_step ), True , final_cost , max_time )
4557
4658 def RunParallelTempering (self , nb_step : int , final_cost = 0 , max_time = - 1 ):
4759 self ._fix_parameters_for_global_optim ()
48- super ().RunParallelTempering (int (nb_step ), True , final_cost , max_time )
60+ if type (self ) == MonteCarlo_orig :
61+ self ._RunParallelTempering (int (nb_step ), True , final_cost , max_time )
62+ else :
63+ super ().RunParallelTempering (int (nb_step ), True , final_cost , max_time )
4964
5065 def _fix_parameters_for_global_optim (self ):
5166 # Fix parameters that should not be optimised in a MonterCarlo run
@@ -58,7 +73,7 @@ def _fix_parameters_for_global_optim(self):
5873
5974 def widget (self ):
6075 """
61- Display a simple widget for this MonteCarloObj , which only updates the current
76+ Display a simple widget for this MonteCarlo , which only updates the current
6277 cost (log-likelihood). Requires ipywidgets
6378 """
6479 if widgets is None :
@@ -101,3 +116,49 @@ def _widget_update(self):
101116 else :
102117 self ._widget_llk .value = "LLK=%12.2f " % self .llk
103118 self ._widget_llk .layout .width = '%dem' % len (self ._widget_llk .value )
119+
120+
121+ def wrap_boost_montecarlo (c : MonteCarlo ):
122+ """
123+ This function is used to wrap a C++ Object by adding the python methods to it.
124+
125+ :param c: the C++ created object to which the python function must be added.
126+ """
127+ if 'widget' not in dir (c ):
128+ for func in ['Optimize' , 'MultiRunOptimize' , 'RunSimulatedAnnealing' , 'RunParallelTempering' ]:
129+ # We keep access to the original functions... Yes, it's a kludge...
130+ exec ("c._%s = c.%s" % (func , func ))
131+ for func in ['Optimize' , 'MultiRunOptimize' , 'RunSimulatedAnnealing' , 'RunParallelTempering' ,
132+ '_fix_parameters_for_global_optim' , 'widget' , 'UpdateDisplay' ,
133+ 'disable_display_update' , 'enable_display_update' , '_widget_update' ]:
134+ exec ("c.%s = MethodType(MonteCarlo.%s, c)" % (func , func ))
135+
136+
137+ class OptimizationObjRegistryWrapper (OptimizationObjRegistry ):
138+ """
139+ Wrapper class with a GetObj() method which can correctly wrap C++ objects with
140+ the python methods. This is only needed when the objects have been created
141+ from C++, e.g. when loading an XML file.
142+ """
143+
144+ def GetObj (self , i ):
145+ o = self ._GetObj (i )
146+ # TODO
147+ print ("Casting OptimizationObj to MonteCarlo and wrapping.." )
148+ # We get the object as an OptimizationObj, which prevents access to some functions
149+ # So we use this function to cast to a MonteCarloObj
150+ o = self ._getObjCastMonteCarlo (i )
151+ wrap_boost_montecarlo (o )
152+ return o
153+
154+
155+ def wrap_boost_optimizationobjregistry (o ):
156+ """
157+ This function is used to wrap a C++ Object by adding the python methods to it.
158+
159+ :param c: the C++ created object to which the python function must be added.
160+ """
161+ # TODO: moving the original function is not very pretty. Is there a better way ?
162+ if '_GetObj' not in dir (o ):
163+ o ._GetObj = o .GetObj
164+ o .GetObj = MethodType (OptimizationObjRegistryWrapper .GetObj , o )
0 commit comments