Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/direct_model.py

    r5024a56 r2c4a190  
    3232from .details import make_kernel_args, dispersion_mesh 
    3333from .modelinfo import DEFAULT_BACKGROUND 
    34 from .product import RADIUS_MODE_ID 
    3534 
    3635# pylint: disable=unused-import 
     
    6564    return calculator(call_details, values, cutoff, is_magnetic) 
    6665 
    67 def call_Fq(calculator, pars, cutoff=0., mono=False): 
    68     # type: (Kernel, ParameterSet, float, bool) -> np.ndarray 
    69     """ 
    70     Like :func:`call_kernel`, but returning F, F^2, R_eff, V_shell, V_form/V_shell. 
    71  
    72     For solid objects V_shell is equal to V_form and the volume ratio is 1. 
    73  
    74     Use parameter *radius_effective_mode* to select the effective radius 
    75     calculation. 
    76     """ 
    77     R_eff_type = int(pars.pop(RADIUS_MODE_ID, 1.0)) 
    78     mesh = get_mesh(calculator.info, pars, dim=calculator.dim, mono=mono) 
    79     #print("pars", list(zip(*mesh))[0]) 
    80     call_details, values, is_magnetic = make_kernel_args(calculator, mesh) 
    81     #print("values:", values) 
    82     return calculator.Fq(call_details, values, cutoff, is_magnetic, R_eff_type) 
    83  
    84 def call_profile(model_info, pars=None): 
    85     # type: (ModelInfo, ParameterSet) -> Tuple[np.ndarray, np.ndarray, Tuple[str, str]] 
     66def call_ER(model_info, pars): 
     67    # type: (ModelInfo, ParameterSet) -> float 
     68    """ 
     69    Call the model ER function using *values*. 
     70 
     71    *model_info* is either *model.info* if you have a loaded model, 
     72    or *kernel.info* if you have a model kernel prepared for evaluation. 
     73    """ 
     74    if model_info.ER is None: 
     75        return 1.0 
     76    elif not model_info.parameters.form_volume_parameters: 
     77        # handle the case where ER is provided but model is not polydisperse 
     78        return model_info.ER() 
     79    else: 
     80        value, weight = _vol_pars(model_info, pars) 
     81        individual_radii = model_info.ER(*value) 
     82        return np.sum(weight*individual_radii) / np.sum(weight) 
     83 
     84 
     85def call_VR(model_info, pars): 
     86    # type: (ModelInfo, ParameterSet) -> float 
     87    """ 
     88    Call the model VR function using *pars*. 
     89 
     90    *model_info* is either *model.info* if you have a loaded model, 
     91    or *kernel.info* if you have a model kernel prepared for evaluation. 
     92    """ 
     93    if model_info.VR is None: 
     94        return 1.0 
     95    elif not model_info.parameters.form_volume_parameters: 
     96        # handle the case where ER is provided but model is not polydisperse 
     97        return model_info.VR() 
     98    else: 
     99        value, weight = _vol_pars(model_info, pars) 
     100        whole, part = model_info.VR(*value) 
     101        return np.sum(weight*part)/np.sum(weight*whole) 
     102 
     103 
     104def call_profile(model_info, **pars): 
     105    # type: (ModelInfo, ...) -> Tuple[np.ndarray, np.ndarray, Tuple[str, str]] 
    86106    """ 
    87107    Returns the profile *x, y, (xlabel, ylabel)* representing the model. 
    88108    """ 
    89     if pars is None: 
    90         pars = {} 
    91109    args = {} 
    92110    for p in model_info.parameters.kernel_parameters: 
     
    224242            else: 
    225243                Iq, dIq = None, None 
    226             #self._theory = np.zeros_like(q) 
    227             q_vectors = [res.q_calc] 
    228244        elif self.data_type == 'Iqxy': 
    229245            #if not model.info.parameters.has_2d: 
     
    242258            res = resolution2d.Pinhole2D(data=data, index=index, 
    243259                                         nsigma=3.0, accuracy=accuracy) 
    244             #self._theory = np.zeros_like(self.Iq) 
    245             q_vectors = res.q_calc 
    246260        elif self.data_type == 'Iq': 
    247261            index = (data.x >= data.qmin) & (data.x <= data.qmax) 
     
    268282            else: 
    269283                res = resolution.Perfect1D(data.x[index]) 
    270  
    271             #self._theory = np.zeros_like(self.Iq) 
    272             q_vectors = [res.q_calc] 
    273284        elif self.data_type == 'Iq-oriented': 
    274285            index = (data.x >= data.qmin) & (data.x <= data.qmax) 
     
    286297                                      qx_width=data.dxw[index], 
    287298                                      qy_width=data.dxl[index]) 
    288             q_vectors = res.q_calc 
    289299        else: 
    290300            raise ValueError("Unknown data type") # never gets here 
     
    292302        # Remember function inputs so we can delay loading the function and 
    293303        # so we can save/restore state 
    294         self._kernel_inputs = q_vectors 
    295304        self._kernel = None 
    296305        self.Iq, self.dIq, self.index = Iq, dIq, index 
     
    329338        # type: (ParameterSet, float) -> np.ndarray 
    330339        if self._kernel is None: 
    331             self._kernel = self._model.make_kernel(self._kernel_inputs) 
     340            # TODO: change interfaces so that resolution returns kernel inputs 
     341            # Maybe have resolution always return a tuple, or maybe have 
     342            # make_kernel accept either an ndarray or a pair of ndarrays. 
     343            kernel_inputs = self.resolution.q_calc 
     344            if isinstance(kernel_inputs, np.ndarray): 
     345                kernel_inputs = (kernel_inputs,) 
     346            self._kernel = self._model.make_kernel(kernel_inputs) 
    332347 
    333348        # Need to pull background out of resolution for multiple scattering 
     
    385400        Generate a plottable profile. 
    386401        """ 
    387         return call_profile(self.model.info, pars) 
     402        return call_profile(self.model.info, **pars) 
    388403 
    389404def main(): 
     
    401416    model_name = sys.argv[1] 
    402417    call = sys.argv[2].upper() 
    403     try: 
    404         values = [float(v) for v in call.split(',')] 
    405     except ValueError: 
    406         values = [] 
    407     if len(values) == 1: 
    408         q, = values 
    409         data = empty_data1D([q]) 
    410     elif len(values) == 2: 
    411         qx, qy = values 
    412         data = empty_data2D([qx], [qy]) 
    413     else: 
    414         print("use q or qx,qy") 
    415         sys.exit(1) 
     418    if call != "ER_VR": 
     419        try: 
     420            values = [float(v) for v in call.split(',')] 
     421        except ValueError: 
     422            values = [] 
     423        if len(values) == 1: 
     424            q, = values 
     425            data = empty_data1D([q]) 
     426        elif len(values) == 2: 
     427            qx, qy = values 
     428            data = empty_data2D([qx], [qy]) 
     429        else: 
     430            print("use q or qx,qy or ER or VR") 
     431            sys.exit(1) 
     432    else: 
     433        data = empty_data1D([0.001])  # Data not used in ER/VR 
    416434 
    417435    model_info = load_model_info(model_name) 
     
    421439                for pair in sys.argv[3:] 
    422440                for k, v in [pair.split('=')]) 
    423     Iq = calculator(**pars) 
    424     print(Iq[0]) 
     441    if call == "ER_VR": 
     442        ER = call_ER(model_info, pars) 
     443        VR = call_VR(model_info, pars) 
     444        print(ER, VR) 
     445    else: 
     446        Iq = calculator(**pars) 
     447        print(Iq[0]) 
    425448 
    426449if __name__ == "__main__": 
Note: See TracChangeset for help on using the changeset viewer.