Changeset ffc2a61 in sasmodels


Ignore:
Timestamp:
Jan 12, 2018 11:28:11 AM (7 years ago)
Author:
Adam Washington <adam.washington@…>
Branches:
master, core_shell_microgels, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
Children:
e68bae9
Parents:
71bf6de
Message:

Simplify model parser

The updated model parser uses only a single switch statement and most
parts contain only a single variable. Comparatively, the old version
was execeeding the PEP 8 recommendations for both conditional depth and
number of local variables.

The trade off is that the new parser is recursive. The maximum depth
is four, so we're not in any danger of blowing the stack, but
recussion can add its own kind of complexity.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/core.py

    r71bf6de rffc2a61  
    148148    used with functions in generate to build the docs or extract model info. 
    149149    """ 
    150     if '@' in model_string: 
    151         terms = model_string.split('+') 
    152         results = [] 
    153         for term in terms: 
    154             if '@' in term: 
    155                 p_info, q_info = [load_model_info(part) 
    156                                   for part in term.split("@")] 
    157                 results.append(product.make_product_info(p_info, q_info)) 
    158             else: 
    159                 results.append(load_model_info(term)) 
    160         return mixture.make_mixture_info(results, operation='+') 
    161         # parts = model_string.split('@') 
    162         # if len(parts) != 2: 
    163         #     raise ValueError("Use P@S to apply a structure factor S to model P") 
    164         # P_info, Q_info = [load_model_info(part) for part in parts] 
    165         # return product.make_product_info(P_info, Q_info) 
    166  
    167     product_parts = [] 
    168     addition_parts = [] 
    169  
    170     addition_parts_names = model_string.split('+') 
    171     if len(addition_parts_names) >= 2: 
    172         addition_parts = [load_model_info(part) for part in addition_parts_names] 
    173     elif len(addition_parts_names) == 1: 
    174         product_parts_names = model_string.split('*') 
    175         if len(product_parts_names) >= 2: 
    176             product_parts = [load_model_info(part) for part in product_parts_names] 
    177         elif len(product_parts_names) == 1: 
    178             if "custom." in product_parts_names[0]: 
    179                 # Extract ModelName from "custom.ModelName" 
    180                 pattern = "custom.([A-Za-z0-9_-]+)" 
    181                 result = re.match(pattern, product_parts_names[0]) 
    182                 if result is None: 
    183                     raise ValueError("Model name in invalid format: " + product_parts_names[0]) 
    184                 model_name = result.group(1) 
    185                 # Use ModelName to find the path to the custom model file 
    186                 model_path = joinpath(CUSTOM_MODEL_PATH, model_name + ".py") 
    187                 if not os.path.isfile(model_path): 
    188                     raise ValueError("The model file {} doesn't exist".format(model_path)) 
    189                 kernel_module = custom.load_custom_kernel_module(model_path) 
    190                 return modelinfo.make_model_info(kernel_module) 
    191             # Model is a core model 
    192             kernel_module = generate.load_kernel_module(product_parts_names[0]) 
    193             return modelinfo.make_model_info(kernel_module) 
    194  
    195     model = None 
    196     if len(product_parts) > 1: 
    197         model = mixture.make_mixture_info(product_parts, operation='*') 
    198     if len(addition_parts) > 1: 
    199         if model is not None: 
    200             addition_parts.append(model) 
    201         model = mixture.make_mixture_info(addition_parts, operation='+') 
    202     return model 
     150    if "+" in model_string: 
     151        parts = [load_model_info(part) 
     152                 for part in model_string.split("+")] 
     153        return mixture.make_mixture_info(parts, operation='+') 
     154    elif "@" in model_string: 
     155        p_info, q_info = [load_model_info(part) 
     156                          for part in model_string.split("@")] 
     157        return product.make_product_info(p_info, q_info) 
     158    elif "*" in model_string: 
     159        parts = [load_model_info(part) 
     160                 for part in model_string.split("*")] 
     161        return mixture.make_mixture_info(parts, operation='*') 
     162    # We are now dealing with a pure model 
     163    elif "custom." in model_string: 
     164        pattern = "custom.([A-Za-z0-9_-]+)" 
     165        result = re.match(pattern, model_string) 
     166        if result is None: 
     167            raise ValueError("Model name in invalid format: " + model_string) 
     168        model_name = result.group(1) 
     169        # Use ModelName to find the path to the custom model file 
     170        model_path = joinpath(CUSTOM_MODEL_PATH, model_name + ".py") 
     171        if not os.path.isfile(model_path): 
     172            raise ValueError("The model file {} doesn't exist".format(model_path)) 
     173        kernel_module = custom.load_custom_kernel_module(model_path) 
     174        return modelinfo.make_model_info(kernel_module) 
     175    kernel_module = generate.load_kernel_module(model_string) 
     176    return modelinfo.make_model_info(kernel_module) 
    203177 
    204178 
Note: See TracChangeset for help on using the changeset viewer.