Changeset 5399809 in sasmodels for sasmodels/kernelpy.py


Ignore:
Timestamp:
Aug 21, 2018 1:32:40 PM (6 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, core_shell_microgels, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
Children:
2a12351b
Parents:
c57ee9e
Message:

fix R_eff support infrastructure so more tests pass

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/kernelpy.py

    r6e7ba14 r5399809  
    182182        radius = ((lambda: 0.0) if effective_radius_type == 0 
    183183                  else (lambda: self._radius(effective_radius_type))) 
    184         res = _loops(self._parameter_vector, self._form, self._volume, radius, 
    185                      self.q_input.nq, call_details, values, cutoff) 
    186         return res 
     184        self.result = _loops( 
     185            self._parameter_vector, self._form, self._volume, radius, 
     186            self.q_input.nq, call_details, values, cutoff) 
    187187 
    188188    def release(self): 
     
    213213    #                                                              # 
    214214    ################################################################ 
     215 
     216    # WARNING: Trickery ahead 
     217    # The parameters[] vector is embedded in the closures for form(), 
     218    # form_volume() and form_radius().  We set the initial vector from 
     219    # the values for the model parameters. As we loop through the polydispesity 
     220    # mesh, we update the components with the polydispersity values before 
     221    # calling the respective functions. 
    215222    n_pars = len(parameters) 
    216223    parameters[:] = values[2:n_pars+2] 
     224 
    217225    if call_details.num_active == 0: 
    218         pd_norm = float(form_volume()) 
    219         scale = values[0]/(pd_norm if pd_norm != 0.0 else 1.0) 
    220         background = values[1] 
    221         return scale*form() + background 
    222  
    223     pd_value = values[2+n_pars:2+n_pars + call_details.num_weights] 
    224     pd_weight = values[2+n_pars + call_details.num_weights:] 
    225  
    226     weight_norm = 0.0 
    227     weighted_volume = 0.0 
    228     weighted_radius = 0.0 
    229     partial_weight = np.NaN 
    230     weight = np.NaN 
    231  
    232     p0_par = call_details.pd_par[0] 
    233     p0_length = call_details.pd_length[0] 
    234     p0_index = p0_length 
    235     p0_offset = call_details.pd_offset[0] 
    236  
    237     pd_par = call_details.pd_par[:call_details.num_active] 
    238     pd_offset = call_details.pd_offset[:call_details.num_active] 
    239     pd_stride = call_details.pd_stride[:call_details.num_active] 
    240     pd_length = call_details.pd_length[:call_details.num_active] 
    241  
    242     total = np.zeros(nq, 'd') 
    243     for loop_index in range(call_details.num_eval): 
    244         # update polydispersity parameter values 
    245         if p0_index == p0_length: 
    246             pd_index = (loop_index//pd_stride)%pd_length 
    247             parameters[pd_par] = pd_value[pd_offset+pd_index] 
    248             partial_weight = np.prod(pd_weight[pd_offset+pd_index][1:]) 
    249             p0_index = loop_index%p0_length 
    250  
    251         weight = partial_weight * pd_weight[p0_offset + p0_index] 
    252         parameters[p0_par] = pd_value[p0_offset + p0_index] 
    253         p0_index += 1 
    254         if weight > cutoff: 
    255             # Call the scattering function 
    256             # Assume that NaNs are only generated if the parameters are bad; 
    257             # exclude all q for that NaN.  Even better would be to have an 
    258             # INVALID expression like the C models, but that is too expensive. 
    259             Iq = np.asarray(form(), 'd') 
    260             if np.isnan(Iq).any(): 
    261                 continue 
    262  
    263             # update value and norm 
    264             total += weight * Iq 
    265             weight_norm += weight 
    266             weighted_volume += weight * form_volume() 
    267             weighted_radius += weight * form_radius() 
     226        total = form() 
     227        weight_norm = 1.0 
     228        weighted_volume = form_volume() 
     229        weighted_radius = form_radius() 
     230 
     231    else: 
     232        pd_value = values[2+n_pars:2+n_pars + call_details.num_weights] 
     233        pd_weight = values[2+n_pars + call_details.num_weights:] 
     234 
     235        weight_norm = 0.0 
     236        weighted_volume = 0.0 
     237        weighted_radius = 0.0 
     238        partial_weight = np.NaN 
     239        weight = np.NaN 
     240 
     241        p0_par = call_details.pd_par[0] 
     242        p0_length = call_details.pd_length[0] 
     243        p0_index = p0_length 
     244        p0_offset = call_details.pd_offset[0] 
     245 
     246        pd_par = call_details.pd_par[:call_details.num_active] 
     247        pd_offset = call_details.pd_offset[:call_details.num_active] 
     248        pd_stride = call_details.pd_stride[:call_details.num_active] 
     249        pd_length = call_details.pd_length[:call_details.num_active] 
     250 
     251        total = np.zeros(nq, 'd') 
     252        for loop_index in range(call_details.num_eval): 
     253            # update polydispersity parameter values 
     254            if p0_index == p0_length: 
     255                pd_index = (loop_index//pd_stride)%pd_length 
     256                parameters[pd_par] = pd_value[pd_offset+pd_index] 
     257                partial_weight = np.prod(pd_weight[pd_offset+pd_index][1:]) 
     258                p0_index = loop_index%p0_length 
     259 
     260            weight = partial_weight * pd_weight[p0_offset + p0_index] 
     261            parameters[p0_par] = pd_value[p0_offset + p0_index] 
     262            p0_index += 1 
     263            if weight > cutoff: 
     264                # Call the scattering function 
     265                # Assume that NaNs are only generated if the parameters are bad; 
     266                # exclude all q for that NaN.  Even better would be to have an 
     267                # INVALID expression like the C models, but that is expensive. 
     268                Iq = np.asarray(form(), 'd') 
     269                if np.isnan(Iq).any(): 
     270                    continue 
     271 
     272                # update value and norm 
     273                total += weight * Iq 
     274                weight_norm += weight 
     275                weighted_volume += weight * form_volume() 
     276                weighted_radius += weight * form_radius() 
    268277 
    269278    result = np.hstack((total, weight_norm, weighted_volume, weighted_radius)) 
Note: See TracChangeset for help on using the changeset viewer.