Changeset be3cce9 in sasmodels for sasmodels/core.py


Ignore:
Timestamp:
Sep 11, 2017 7:15:05 AM (7 years ago)
Author:
lewis
Branches:
master, core_shell_microgels, costrafo411, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
Children:
6726fb9
Parents:
a85a569 (diff), ab60822 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into ticket-767

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/core.py

    r142a8e2 ra85a569  
    1010 
    1111import os 
     12import re 
    1213from os.path import basename, dirname, join as joinpath 
    1314from glob import glob 
     
    2122from . import kernelpy 
    2223from . import kerneldll 
     24from . import custom 
    2325 
    2426if os.environ.get("SAS_OPENCL", "").lower() == "none": 
     
    3032    except Exception: 
    3133        HAVE_OPENCL = False 
     34 
     35CUSTOM_MODEL_PATH = os.environ.get('SAS_MODELPATH', "") 
     36if CUSTOM_MODEL_PATH == "": 
     37    path = joinpath(os.path.expanduser("~"), ".sasmodels", "custom_models") 
     38    if not os.path.isdir(path): 
     39        os.makedirs(path) 
     40    CUSTOM_MODEL_PATH = path 
    3241 
    3342try: 
     
    125134                       dtype=dtype, platform=platform) 
    126135 
    127  
    128 def load_model_info(model_name): 
     136def load_model_info(model_string): 
    129137    # type: (str) -> modelinfo.ModelInfo 
    130138    """ 
    131139    Load a model definition given the model name. 
    132140 
    133     *model_name* is the name of the model, or perhaps a model expression 
    134     such as sphere*hardsphere or sphere+cylinder. 
     141    *model_string* is the name of the model, or perhaps a model expression 
     142    such as sphere*cylinder or sphere+cylinder. Use '@' for a structure 
     143    factor product, e.g. sphere@hardsphere. Custom models can be specified by 
     144    prefixing the model name with 'custom.', e.g. 'custom.MyModel+sphere'. 
    135145 
    136146    This returns a handle to the module defining the model.  This can be 
    137147    used with functions in generate to build the docs or extract model info. 
    138148    """ 
    139     parts = model_name.split('+') 
    140     if len(parts) > 1: 
    141         model_info_list = [load_model_info(p) for p in parts] 
    142         return mixture.make_mixture_info(model_info_list) 
    143  
    144     parts = model_name.split('*') 
    145     if len(parts) > 1: 
    146         if len(parts) > 2: 
    147             raise ValueError("use P*S to apply structure factor S to model P") 
    148         P_info, Q_info = [load_model_info(p) for p in parts] 
     149    if '@' in model_string: 
     150        parts = model_string.split('@') 
     151        if len(parts) != 2: 
     152            raise ValueError("Use P@S to apply a structure factor S to model P") 
     153        P_info, Q_info = [load_model_info(part) for part in parts] 
    149154        return product.make_product_info(P_info, Q_info) 
    150155 
    151     kernel_module = generate.load_kernel_module(model_name) 
    152     return modelinfo.make_model_info(kernel_module) 
     156    product_parts = [] 
     157    addition_parts = [] 
     158 
     159    addition_parts_names = model_string.split('+') 
     160    if len(addition_parts_names) >= 2: 
     161        addition_parts = [load_model_info(part) for part in addition_parts_names] 
     162    elif len(addition_parts_names) == 1: 
     163        product_parts_names = model_string.split('*') 
     164        if len(product_parts_names) >= 2: 
     165            product_parts = [load_model_info(part) for part in product_parts_names] 
     166        elif len(product_parts_names) == 1: 
     167            if "custom." in product_parts_names[0]: 
     168                # Extract ModelName from "custom.ModelName" 
     169                pattern = "custom.([A-Za-z0-9_-]+)" 
     170                result = re.match(pattern, product_parts_names[0]) 
     171                if result is None: 
     172                    raise ValueError("Model name in invalid format: " + product_parts_names[0]) 
     173                model_name = result.group(1) 
     174                # Use ModelName to find the path to the custom model file 
     175                model_path = joinpath(CUSTOM_MODEL_PATH, model_name + ".py") 
     176                if not os.path.isfile(model_path): 
     177                    raise ValueError("The model file {} doesn't exist".format(model_path)) 
     178                kernel_module = custom.load_custom_kernel_module(model_path) 
     179                return modelinfo.make_model_info(kernel_module) 
     180            # Model is a core model 
     181            kernel_module = generate.load_kernel_module(product_parts_names[0]) 
     182            return modelinfo.make_model_info(kernel_module) 
     183 
     184    model = None 
     185    if len(product_parts) > 1: 
     186        model = mixture.make_mixture_info(product_parts, operation='*') 
     187    if len(addition_parts) > 1: 
     188        if model is not None: 
     189            addition_parts.append(model) 
     190        model = mixture.make_mixture_info(addition_parts, operation='+') 
     191    return model 
    153192 
    154193 
Note: See TracChangeset for help on using the changeset viewer.