@@ -220,15 +220,6 @@ def make_product_info(p_info, s_info):
220220 #s_list[0] = copy(s_list[0])
221221 #s_list[0].polydisperse = False
222222
223- s_translate = {old .id : new .id for old , new in s_pairs }
224- def random ():
225- """Random set of model parameters for product model"""
226- combined_pars = p_info .random ()
227- combined_pars .update ((s_translate [k ], v )
228- for k , v in s_info .random ().items ()
229- if k in s_translate )
230- return combined_pars
231-
232223 model_info = ModelInfo ()
233224 model_info .id = '@' .join ((p_id , s_id ))
234225 model_info .name = '@' .join ((p_name , s_name ))
@@ -238,7 +229,7 @@ def random():
238229 model_info .docs = model_info .title
239230 model_info .category = "custom"
240231 model_info .parameters = parameters
241- model_info .random = random
232+ model_info .random = _ProductRandom ( p_info , s_info , s_pairs )
242233 #model_info.single = p_info.single and s_info.single
243234 model_info .structure_factor = False
244235 #model_info.tests = []
@@ -268,6 +259,19 @@ def profile(**kwargs):
268259 #print(parlist(model_info, values, is2d=True))
269260 return model_info
270261
262+ class _ProductRandom :
263+ """Random set of model parameters for product model"""
264+ def __init__ (self , p_info , s_info , s_pairs ):
265+ self .p_info = p_info
266+ self .s_info = s_info
267+ self .s_translate = {old .id : new .id for old , new in s_pairs }
268+ def __call__ (self ):
269+ combined_pars = self .p_info .random ()
270+ combined_pars .update ((self .s_translate [k ], v )
271+ for k , v in self .s_info .random ().items ()
272+ if k in self .s_translate )
273+ return combined_pars
274+
271275def _tag_parameter (par ):
272276 """
273277 Tag the parameter name with _S to indicate that the parameter comes from
@@ -284,26 +288,30 @@ def _tag_parameter(par):
284288 par .name = par .id + vector_length
285289 return par
286290
287- def _intermediates (Q , F , Fsq , S , scale , volume , volume_ratio , radius_effective ,
288- beta_mode , P_intermediate ):
289- # type: (np.ndarray, np.ndarray, np.ndarray, np.ndarray, float, float, float, float, bool, Optiona[Callable[[], Parts]]) -> Parts
291+ class _Intermediates :
290292 """
291293 Returns intermediate results for beta approximation-enabled product.
292294 The result may be an array or a float.
293295 """
294- parts = OrderedDict () # type: Parts
295- parts ["P(Q)" ] = (Q , scale * Fsq )
296- if P_intermediate is not None :
297- parts ["P(Q) parts" ] = P_intermediate ()
298- parts ["volume" ] = volume
299- parts ["volume_ratio" ] = volume_ratio
300- parts ["radius_effective" ] = radius_effective
301- parts ["S(Q)" ] = (Q , S )
302- if beta_mode :
303- parts ["beta(Q)" ] = (Q , F ** 2 / Fsq )
304- parts ["S_eff(Q)" ] = (Q , 1 + (F ** 2 / Fsq )* (S - 1 ))
305- #parts["I(Q)", scale*(Fsq + (F**2)*(S-1)) + bg
306- return parts
296+ def __init__ (self , * args ):
297+ # type: (np.ndarray, np.ndarray, np.ndarray, np.ndarray, float, float, float, float, bool, Optiona[Callable[[], Parts]]) -> Parts
298+ self .args = args
299+ def __call__ (self ):
300+ Q , F , Fsq , S , scale , volume , volume_ratio , radius_effective , \
301+ beta_mode , P_intermediate = self .args
302+ parts = OrderedDict () # type: Parts
303+ parts ["P(Q)" ] = (Q , scale * Fsq )
304+ if P_intermediate is not None :
305+ parts ["P(Q) parts" ] = P_intermediate ()
306+ parts ["volume" ] = volume
307+ parts ["volume_ratio" ] = volume_ratio
308+ parts ["radius_effective" ] = radius_effective
309+ parts ["S(Q)" ] = (Q , S )
310+ if beta_mode :
311+ parts ["beta(Q)" ] = (Q , F ** 2 / Fsq )
312+ parts ["S_eff(Q)" ] = (Q , 1 + (F ** 2 / Fsq )* (S - 1 ))
313+ #parts["I(Q)", scale*(Fsq + (F**2)*(S-1)) + bg
314+ return parts
307315
308316class ProductModel (KernelModel ):
309317 """
@@ -535,7 +543,9 @@ def Iq(self, call_details, values, cutoff, magnetic):
535543 # kernel calling interface. Could do this as an "optional"
536544 # return value in the caller, though in that case we could return
537545 # the results directly rather than through a lazy evaluator.
538- self .results = lambda : _intermediates (
546+ # TODO: why is pickle seeing self.results?
547+ # Note: turned into a callable class because pickle didn't like it.
548+ self .results = _Intermediates (
539549 self .q , F , Fsq , S , combined_scale , shell_volume , volume_ratio ,
540550 radius_effective , beta_mode , p_intermediate )
541551
0 commit comments