Changeset 303d8d6 in sasmodels for sasmodels/generate.py


Ignore:
Timestamp:
Mar 21, 2016 12:49:21 AM (8 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, core_shell_microgels, costrafo411, magnetic_model, release_v0.94, release_v0.95, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
Children:
4a72d1a, 3a45c2c
Parents:
03cac08
Message:

new calculator says hello before crashing

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/generate.py

    r03cac08 r303d8d6  
    354354    return [_search(search_path, f) for f in model_info['source']] 
    355355 
    356  
    357356def convert_type(source, dtype): 
    358357    """ 
     
    419418    if filename not in _template_cache or mtime > _template_cache[filename][0]: 
    420419        with open(path) as fid: 
    421             _template_cache[filename] = (mtime, fid.read()) 
     420            _template_cache[filename] = (mtime, fid.read(), path) 
    422421    return _template_cache[filename][1] 
     422 
     423def model_templates(): 
     424    # TODO: fails DRY; templates are listed in two places. 
     425    # should instead have model_info contain a list of paths 
     426    return [joinpath(TEMPLATE_ROOT, filename) 
     427            for filename in ('kernel_header.c', 'kernel_iq.c')] 
     428 
    423429 
    424430_FN_TEMPLATE = """\ 
     
    450456    """ 
    451457    prefix += "." 
    452     return [prefix+p.name for p in pars] 
     458    return [prefix+p for p in pars] 
    453459 
    454460_IQXY_PATTERN = re.compile("^((inline|static) )? *(double )? *Iqxy *([(]|$)", 
     
    513519    # Generate form_volume function, etc. from body only 
    514520    if model_info['form_volume'] is not None: 
    515         pnames = [p.name for p in vol_parameters] 
     521        pnames = [p for p in vol_parameters] 
    516522        source.append(_gen_fn('form_volume', pnames, model_info['form_volume'])) 
    517523    if model_info['Iq'] is not None: 
    518         pnames = ['q'] + [p.name for p in iq_parameters] 
     524        pnames = ['q'] + [p for p in iq_parameters] 
    519525        source.append(_gen_fn('Iq', pnames, model_info['Iq'])) 
    520526    if model_info['Iqxy'] is not None: 
    521         pnames = ['qx', 'qy'] + [p.name for p in iqxy_parameters] 
     527        pnames = ['qx', 'qy'] + [p for p in iqxy_parameters] 
    522528        source.append(_gen_fn('Iqxy', pnames, model_info['Iqxy'])) 
    523529 
     
    552558 
    553559    # Fill in definitions for numbers of parameters 
    554     source.append("#define MAX_PD %s"%MAX_PD) 
     560    source.append("#define MAX_PD %s"%model_info['max_pd']) 
    555561    source.append("#define NPARS %d"%(len(model_info['parameters'])-2)) 
    556562 
     
    584590    * *magnetic* set of parameters that are used to compute magnetic 
    585591      patterns (which includes all 1D and 2D parameters) 
    586     * *sesans* set of parameters that are used to compute sesans patterns 
    587      (which is just 1D without background) 
    588     * *pd-relative* is the set of parameters with relative distribution 
     592    * *pd_relative* is the set of parameters with relative distribution 
    589593      width (e.g., radius +/- 10%) rather than absolute distribution 
    590594      width (e.g., theta +/- 6 degrees). 
    591595    """ 
    592596    par_set = {} 
    593     par_set['1d'] = [p for p in pars if p.type not in ('orientation', 'magnetic')] 
    594     par_set['2d'] = [p for p in pars if p.type != 'magnetic'] 
    595     par_set['magnetic'] = [p for p in pars] 
    596     par_set['pd'] = [p for p in pars if p.type in ('volume', 'orientation')] 
    597     par_set['pd_relative'] = [p for p in pars if p.type == 'volume'] 
     597    par_set['1d'] = [p.name for p in pars if p.type not in ('orientation', 'magnetic')] 
     598    par_set['2d'] = [p.name for p in pars if p.type != 'magnetic'] 
     599    par_set['magnetic'] = [p.name for p in pars] 
     600    par_set['pd'] = [p.name for p in pars if p.type in ('volume', 'orientation')] 
     601    par_set['pd_relative'] = [p.name for p in pars if p.type == 'volume'] 
    598602    return par_set 
    599603 
     
    621625    } 
    622626    for p in pars: 
    623         par_type[p.type if p.type else 'other'].append(p) 
     627        par_type[p.type if p.type else 'other'].append(p.name) 
    624628    return  par_type 
    625629 
     
    641645    par_type.update(categorize_parameters(pars)) 
    642646    model_info['parameters'] = pars 
    643     model_info['limits'] = dict((p.name, p.limits) for p in pars) 
    644647    model_info['par_type'] = par_type 
    645     model_info['defaults'] = dict((p.name, p.default) for p in pars) 
    646648    if model_info.get('demo', None) is None: 
    647         model_info['demo'] = model_info['defaults'] 
     649        model_info['demo'] = dict((p.name, p.default) for p in pars) 
    648650    model_info['has_2d'] = par_type['orientation'] or par_type['magnetic'] 
     651 
     652def mono_details(max_pd, npars): 
     653    par_offset = 5*max_pd 
     654    const_offset = par_offset + 3*npars 
     655 
     656    mono = np.zeros(const_offset + 3, 'i') 
     657    mono[0] = 0                # pd_par: arbitrary order; use first 
     658    mono[1*max_pd] = 1         # pd_length: only one element 
     659    mono[2*max_pd] = 2         # pd_offset: skip scale and background 
     660    mono[3*max_pd] = 1         # pd_stride: vectors of length 1 
     661    mono[4*max_pd-1] = 1       # pd_stride[-1]: only one element in set 
     662    mono[4*max_pd] = 0         # pd_isvol: doens't matter if no norm 
     663    mono[par_offset:par_offset+npars] = np.arange(2, npars+2, dtype='i') 
     664    # par_offset: copied in order 
     665    mono[par_offset+npars:par_offset+2*npars] = 0 
     666    # par_coord: no coordinated parameters 
     667    mono[par_offset+npars] = 1 # par_coord[0]: except par 0 
     668    mono[par_offset+2*npars:par_offset+3*npars] = 0 
     669    # fast coord with 0 
     670    mono[const_offset] = 1     # fast_coord_count: one fast index 
     671    mono[const_offset+1] = -1  # theta_var: None 
     672    mono[const_offset+2] = 0   # fast_theta: False 
     673    return mono 
     674 
     675def poly_details(model_info, weights, pars, constraints=None): 
     676    if constraints is not None: 
     677        # Need to find the independently varying pars and sort them 
     678        # Need to build a coordination list for the dependent variables 
     679        # Need to generate a constraints function which takes values 
     680        # and weights, returning par blocks 
     681        raise ValueError("Can't handle constraints yet") 
     682 
     683    raise ValueError("polydispersity not supported") 
     684 
    649685 
    650686def create_default_functions(model_info): 
     
    688724      model variants (e.g., the list of cases) or is None if there are no 
    689725      model variants 
    690     * *defaults* is the *{parameter: value}* table built from the parameter 
    691       description table. 
    692     * *limits* is the *{parameter: [min, max]}* table built from the 
    693       parameter description table. 
    694     * *partypes* categorizes the model parameters. See 
     726    * *par_type* categorizes the model parameters. See 
    695727      :func:`categorize_parameters` for details. 
    696728    * *demo* contains the *{parameter: value}* map used in compare (and maybe 
     
    709741      *model_info* blocks for the composition objects.  This allows us to 
    710742      build complete product and mixture models from just the info. 
     743    * *max_pd* is the max polydispersity dimension.  This is constant and 
     744      should not be reset.  You may be able to change it when the program 
     745      starts by setting *sasmodels.generate.MAX_PD*. 
    711746 
    712747    """ 
     
    719754        name = " ".join(w.capitalize() for w in kernel_id.split('_')) 
    720755    model_info = dict( 
     756        max_pd=MAX_PD, 
    721757        id=kernel_id,  # string used to load the kernel 
    722758        filename=abspath(kernel_module.__file__), 
     
    736772        oldpars=getattr(kernel_module, 'oldpars', {}), 
    737773        tests=getattr(kernel_module, 'tests', []), 
     774        mono_details = mono_details(MAX_PD, len(kernel_module.parameters)) 
    738775        ) 
    739776    process_parameters(model_info) 
Note: See TracChangeset for help on using the changeset viewer.