Changes in / [6da1d76:0535624] in sasmodels


Ignore:
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • doc/guide/plugin.rst

    r2015f02 rf796469  
    423423calculations, but instead rely on numerical integration to compute the 
    424424appropriately smeared pattern. 
    425  
    426 Each .py file also contains a function:: 
    427  
    428         def random(): 
    429         ... 
    430          
    431 This function provides a model-specific random parameter set which shows model  
    432 features in the USANS to SANS range.  For example, core-shell sphere sets the  
    433 outer radius of the sphere logarithmically in `[20, 20,000]`, which sets the Q  
    434 value for the transition from flat to falling.  It then uses a beta distribution  
    435 to set the percentage of the shape which is shell, giving a preference for very  
    436 thin or very thick shells (but never 0% or 100%).  Using `-sets=10` in sascomp  
    437 should show a reasonable variety of curves over the default sascomp q range.   
    438 The parameter set is returned as a dictionary of `{parameter: value, ...}`.   
    439 Any model parameters not included in the dictionary will default according to  
    440 the code in the `_randomize_one()` function from sasmodels/compare.py. 
    441425 
    442426Python Models 
  • sasmodels/__init__.py

    ra1ec908 re65c3ba  
    1414defining new models. 
    1515""" 
    16 __version__ = "0.98" 
     16__version__ = "0.97" 
    1717 
    1818def data_files(): 
  • sasmodels/custom/__init__.py

    rd321747 r0f48f1e  
    1212import sys 
    1313import os 
    14 from os.path import basename, splitext, join as joinpath, exists, dirname 
     14from os.path import basename, splitext 
    1515 
    1616try: 
     
    1818    from importlib.util import spec_from_file_location, module_from_spec  # type: ignore 
    1919    def load_module_from_path(fullname, path): 
    20         # type: (str, str) -> "module" 
    2120        """load module from *path* as *fullname*""" 
    2221        spec = spec_from_file_location(fullname, os.path.expanduser(path)) 
     
    2827    import imp 
    2928    def load_module_from_path(fullname, path): 
    30         # type: (str, str) -> "module" 
    3129        """load module from *path* as *fullname*""" 
    3230        # Clear out old definitions, if any 
     
    3937        return module 
    4038 
    41 _MODULE_CACHE = {} # type: Dict[str, Tuple("module", int)] 
    42 _MODULE_DEPENDS = {} # type: Dict[str, List[str]] 
    43 _MODULE_DEPENDS_STACK = [] # type: List[str] 
    4439def load_custom_kernel_module(path): 
    45     # type: str -> "module" 
    4640    """load SAS kernel from *path* as *sasmodels.custom.modelname*""" 
    4741    # Pull off the last .ext if it exists; there may be others 
    4842    name = basename(splitext(path)[0]) 
    49     path = os.path.expanduser(path) 
    50  
    51     # Reload module if necessary. 
    52     if need_reload(path): 
    53         # Assume the module file is the only dependency 
    54         _MODULE_DEPENDS[path] = set([path]) 
    55  
    56         # Load the module while pushing it onto the dependency stack.  If 
    57         # this triggers any submodules, then they will add their dependencies 
    58         # to this module as the "working_on" parent.  Pop the stack when the 
    59         # module is loaded. 
    60         _MODULE_DEPENDS_STACK.append(path) 
    61         module = load_module_from_path('sasmodels.custom.'+name, path) 
    62         _MODULE_DEPENDS_STACK.pop() 
    63  
    64         # Include external C code in the dependencies.  We are looking 
    65         # for module.source and assuming that it is a list of C source files 
    66         # relative to the module itself.  Any files that do not exist, 
    67         # such as those in the standard libraries, will be ignored. 
    68         # TODO: look in builtin module path for standard c sources 
    69         # TODO: share code with generate.model_sources 
    70         c_sources = getattr(module, 'source', None) 
    71         if isinstance(c_sources, (list, tuple)): 
    72             _MODULE_DEPENDS[path].update(_find_sources(path, c_sources)) 
    73  
    74         # Cache the module, and tag it with the newest timestamp 
    75         timestamp = max(os.path.getmtime(f) for f in _MODULE_DEPENDS[path]) 
    76         _MODULE_CACHE[path] = module, timestamp 
    77  
    78         #print("loading", os.path.basename(path), _MODULE_CACHE[path][1], 
    79         #    [os.path.basename(p) for p in _MODULE_DEPENDS[path]]) 
    80  
    81     # Add path and all its dependence to the parent module, if there is one. 
    82     if _MODULE_DEPENDS_STACK: 
    83         working_on = _MODULE_DEPENDS_STACK[-1] 
    84         _MODULE_DEPENDS[working_on].update(_MODULE_DEPENDS[path]) 
    85  
    86     return _MODULE_CACHE[path][0] 
    87  
    88 def need_reload(path): 
    89     # type: str -> bool 
    90     """ 
    91     Return True if any path dependencies have a timestamp newer than the time 
    92     when the path was most recently loaded. 
    93     """ 
    94     # TODO: fails if a dependency has a modification time in the future 
    95     # If the newest dependency has a time stamp in the future, then this 
    96     # will be recorded as the cached time.  When a second dependency 
    97     # is updated to the current time stamp, it will still be considered 
    98     # older than the current build and the reload will not be triggered. 
    99     # Could instead treat all future times as 0 here and in the code above 
    100     # which records the newest timestamp.  This will force a reload when 
    101     # the future time is reached, but other than that should perform 
    102     # correctly.  Probably not worth the extra code... 
    103     _, cache_time = _MODULE_CACHE.get(path, (None, -1)) 
    104     depends = _MODULE_DEPENDS.get(path, [path]) 
    105     #print("reload", any(cache_time < os.path.getmtime(p) for p in depends)) 
    106     #for f in depends: print(">>>  ", f, os.path.getmtime(f)) 
    107     return any(cache_time < os.path.getmtime(p) for p in depends) 
    108  
    109 def _find_sources(path, source_list): 
    110     # type: (str, List[str]) -> List[str] 
    111     """ 
    112     Return a list of the sources relative to base file; ignore any that 
    113     are not found. 
    114     """ 
    115     root = dirname(path) 
    116     found = [] 
    117     for source_name in source_list: 
    118         source_path = joinpath(root, source_name) 
    119         if exists(source_path): 
    120             found.append(source_path) 
    121     return found 
     43    # Placing the model in the 'sasmodels.custom' name space. 
     44    kernel_module = load_module_from_path('sasmodels.custom.'+name, 
     45                                          os.path.expanduser(path)) 
     46    return kernel_module 
  • sasmodels/kernelpy.py

    r91bd550 r108e70e  
    3737        self.info = model_info 
    3838        self.dtype = np.dtype('d') 
     39        logger.info("load python model " + self.info.name) 
    3940 
    4041    def make_kernel(self, q_vectors): 
  • sasmodels/modelinfo.py

    rd321747 r0535624  
    824824    info.structure_factor = structure_factor 
    825825    info.profile_axes = getattr(kernel_module, 'profile_axes', ['x', 'y']) 
    826     # Note: custom.load_custom_kernel_module assumes the C sources are defined 
    827     # by this attribute. 
    828826    info.source = getattr(kernel_module, 'source', []) 
    829827    info.c_code = getattr(kernel_module, 'c_code', None) 
  • sasmodels/models/bcc_paracrystal.py

    rda7b26b r2d81cfe  
    11r""" 
    2 .. warning:: This model and this model description are under review following  
    3              concerns raised by SasView users. If you need to use this model,  
    4              please email help@sasview.org for the latest situation. *The  
    5              SasView Developers. September 2018.* 
    6  
    72Definition 
    83---------- 
     
    1813 
    1914    I(q) = \frac{\text{scale}}{V_p} V_\text{lattice} P(q) Z(q) 
     15 
    2016 
    2117where *scale* is the volume fraction of spheres, $V_p$ is the volume of the 
     
    10197 
    10298Authorship and Verification 
    103 --------------------------- 
     99---------------------------- 
    104100 
    105101* **Author:** NIST IGOR/DANSE **Date:** pre 2010 
  • sasmodels/models/be_polyelectrolyte.py

    rca77fc1 ref07e95  
    11r""" 
    2 .. note:: Please read the Validation section below. 
    3  
    42Definition 
    53---------- 
     
    1311 
    1412    I(q) = K\frac{q^2+k^2}{4\pi L_b\alpha ^2} 
    15     \frac{1}{1+r_{0}^4(q^2+k^2)(q^2-12hC_a/b^2)} + background 
     13    \frac{1}{1+r_{0}^2(q^2+k^2)(q^2-12hC_a/b^2)} + background 
    1614 
    1715    k^2 = 4\pi L_b(2C_s + \alpha C_a) 
    1816 
    19     r_{0}^2 = \frac{b}{\alpha \sqrt{C_a 48\pi L_b}} 
     17    r_{0}^2 = \frac{1}{\alpha \sqrt{C_a} \left( b/\sqrt{48\pi L_b}\right)} 
    2018 
    2119where 
    2220 
    2321$K$ is the contrast factor for the polymer which is defined differently than in 
    24 other models and is given in barns where 1 $barn = 10^{-24}$ $cm^2$.  $K$ is 
     22other models and is given in barns where $1 barn = 10^{-24} cm^2$.  $K$ is 
    2523defined as: 
    2624 
     
    3129    a = b_p - (v_p/v_s) b_s 
    3230 
    33 where: 
    34  
    35 - $b_p$ and $b_s$ are **sum of the scattering lengths of the atoms** 
    36   constituting the polymer monomer and the solvent molecules, respectively. 
    37  
    38 - $v_p$ and $v_s$ are the partial molar volume of the polymer and the  
    39   solvent, respectively. 
    40  
    41 - $L_b$ is the Bjerrum length (|Ang|) - **Note:** This parameter needs to be 
    42   kept constant for a given solvent and temperature! 
    43  
    44 - $h$ is the virial parameter (|Ang^3|) - **Note:** See [#Borue]_ for the 
    45   correct interpretation of this parameter.  It incorporates second and third 
    46   virial coefficients and can be *negative*. 
    47  
    48 - $b$ is the monomer length (|Ang|). 
    49  
    50 - $C_s$ is the concentration of monovalent salt(1/|Ang^3| - internally converted from mol/L). 
    51  
    52 - $\alpha$ is the degree of ionization (the ratio of charged monomers to the total  
    53   number of monomers) 
    54  
    55 - $C_a$ is the polymer molar concentration (1/|Ang^3| - internally converted from mol/L) 
    56  
    57 - $background$ is the incoherent background. 
     31where $b_p$ and $b_s$ are sum of the scattering lengths of the atoms 
     32constituting the monomer of the polymer and the sum of the scattering lengths 
     33of the atoms constituting the solvent molecules respectively, and $v_p$ and 
     34$v_s$ are the partial molar volume of the polymer and the solvent respectively 
     35 
     36$L_b$ is the Bjerrum length(|Ang|) - **Note:** This parameter needs to be 
     37kept constant for a given solvent and temperature! 
     38 
     39$h$ is the virial parameter (|Ang^3|/mol) - **Note:** See [#Borue]_ for the 
     40correct interpretation of this parameter.  It incorporates second and third 
     41virial coefficients and can be Negative. 
     42 
     43$b$ is the monomer length(|Ang|), $C_s$ is the concentration of monovalent 
     44salt(mol/L), $\alpha$ is the ionization degree (ionization degree : ratio of 
     45charged monomers  to total number of monomers), $C_a$ is the polymer molar 
     46concentration(mol/L), and $background$ is the incoherent background. 
    5847 
    5948For 2D data the scattering intensity is calculated in the same way as 1D, 
     
    6352 
    6453    q = \sqrt{q_x^2 + q_y^2} 
    65  
    66 Validation 
    67 ---------- 
    68  
    69 As of the last revision, this code is believed to be correct.  However it 
    70 needs further validation and should be used with caution at this time.  The 
    71 history of this code goes back to a 1998 implementation. It was recently noted 
    72 that in that implementation, while both the polymer concentration and salt 
    73 concentration were converted from experimental units of mol/L to more 
    74 dimensionally useful units of 1/|Ang^3|, only the converted version of the 
    75 polymer concentration was actually being used in the calculation while the 
    76 unconverted salt concentration (still in apparent units of mol/L) was being  
    77 used.  This was carried through to Sasmodels as used for SasView 4.1 (though  
    78 the line of code converting the salt concentration to the new units was removed  
    79 somewhere along the line). Simple dimensional analysis of the calculation shows  
    80 that the converted salt concentration should be used, which the original code  
    81 suggests was the intention, so this has now been corrected (for SasView 4.2).  
    82 Once better validation has been performed this note will be removed. 
    8354 
    8455References 
     
    9566 
    9667* **Author:** NIST IGOR/DANSE **Date:** pre 2010 
    97 * **Last Modified by:** Paul Butler **Date:** September 25, 2018 
    98 * **Last Reviewed by:** Paul Butler **Date:** September 25, 2018 
     68* **Last Modified by:** Paul Kienzle **Date:** July 24, 2016 
     69* **Last Reviewed by:** Paul Butler and Richard Heenan **Date:** October 07, 2016 
    9970""" 
    10071 
     
    12192    ["contrast_factor",       "barns",   10.0,  [-inf, inf], "", "Contrast factor of the polymer"], 
    12293    ["bjerrum_length",        "Ang",      7.1,  [0, inf],    "", "Bjerrum length"], 
    123     ["virial_param",          "Ang^3", 12.0,  [-inf, inf], "", "Virial parameter"], 
     94    ["virial_param",          "Ang^3/mol", 12.0,  [-inf, inf], "", "Virial parameter"], 
    12495    ["monomer_length",        "Ang",     10.0,  [0, inf],    "", "Monomer length"], 
    12596    ["salt_concentration",    "mol/L",    0.0,  [-inf, inf], "", "Concentration of monovalent salt"], 
     
    131102 
    132103def Iq(q, 
    133        contrast_factor, 
    134        bjerrum_length, 
    135        virial_param, 
    136        monomer_length, 
    137        salt_concentration, 
    138        ionization_degree, 
    139        polymer_concentration): 
     104       contrast_factor=10.0, 
     105       bjerrum_length=7.1, 
     106       virial_param=12.0, 
     107       monomer_length=10.0, 
     108       salt_concentration=0.0, 
     109       ionization_degree=0.05, 
     110       polymer_concentration=0.7): 
    140111    """ 
    141     :params: see parameter table 
    142     :return: 1-D form factor for polyelectrolytes in low salt 
    143      
    144     parameter names, units, default values, and behavior (volume, sld etc) are 
    145     defined in the parameter table.  The concentrations are converted from 
    146     experimental mol/L to dimensionaly useful 1/A3 in first two lines 
     112    :param q:                     Input q-value 
     113    :param contrast_factor:       Contrast factor of the polymer 
     114    :param bjerrum_length:        Bjerrum length 
     115    :param virial_param:          Virial parameter 
     116    :param monomer_length:        Monomer length 
     117    :param salt_concentration:    Concentration of monovalent salt 
     118    :param ionization_degree:     Degree of ionization 
     119    :param polymer_concentration: Polymer molar concentration 
     120    :return:                      1-D intensity 
    147121    """ 
    148122 
    149     concentration_pol = polymer_concentration * 6.022136e-4 
    150     concentration_salt = salt_concentration * 6.022136e-4 
    151  
    152     k_square = 4.0 * pi * bjerrum_length * (2*concentration_salt + 
    153                                             ionization_degree * concentration_pol) 
    154  
    155     r0_square = 1.0/ionization_degree/sqrt(concentration_pol) * \ 
     123    concentration = polymer_concentration * 6.022136e-4 
     124 
     125    k_square = 4.0 * pi * bjerrum_length * (2*salt_concentration + 
     126                                            ionization_degree * concentration) 
     127 
     128    r0_square = 1.0/ionization_degree/sqrt(concentration) * \ 
    156129                (monomer_length/sqrt((48.0*pi*bjerrum_length))) 
    157130 
     
    160133 
    161134    term2 = 1.0 + r0_square**2 * (q**2 + k_square) * \ 
    162         (q**2 - (12.0 * virial_param * concentration_pol/(monomer_length**2))) 
     135        (q**2 - (12.0 * virial_param * concentration/(monomer_length**2))) 
    163136 
    164137    return term1/term2 
     
    201174 
    202175    # Accuracy tests based on content in test/utest_other_models.py 
    203     # Note that these should some day be validated beyond this self validation 
    204     # (circular reasoning). -- i.e. the "good value," at least for those with 
    205     # non zero salt concentrations, were obtained by running the current 
    206     # model in SasView and copying the appropriate result here. 
    207     #    PDB -- Sep 26, 2018 
    208176    [{'contrast_factor':       10.0, 
    209177      'bjerrum_length':         7.1, 
     
    216184     }, 0.001, 0.0948379], 
    217185 
     186    # Additional tests with larger range of parameters 
    218187    [{'contrast_factor':       10.0, 
    219188      'bjerrum_length':       100.0, 
    220189      'virial_param':           3.0, 
    221       'monomer_length':         5.0, 
    222       'salt_concentration':     1.0, 
    223       'ionization_degree':      0.1, 
    224       'polymer_concentration':  1.0, 
     190      'monomer_length':         1.0, 
     191      'salt_concentration':    10.0, 
     192      'ionization_degree':      2.0, 
     193      'polymer_concentration': 10.0, 
    225194      'background':             0.0, 
    226      }, 0.1, 0.253469484], 
     195     }, 0.1, -3.75693800588], 
    227196 
    228197    [{'contrast_factor':       10.0, 
    229198      'bjerrum_length':       100.0, 
    230199      'virial_param':           3.0, 
    231       'monomer_length':         5.0, 
    232       'salt_concentration':     1.0, 
    233       'ionization_degree':      0.1, 
    234       'polymer_concentration':  1.0, 
    235       'background':             1.0, 
    236      }, 0.05, 1.738358122], 
     200      'monomer_length':         1.0, 
     201      'salt_concentration':    10.0, 
     202      'ionization_degree':      2.0, 
     203      'polymer_concentration': 10.0, 
     204      'background':           100.0 
     205     }, 5.0, 100.029142149], 
    237206 
    238207    [{'contrast_factor':     100.0, 
    239208      'bjerrum_length':       10.0, 
    240       'virial_param':         12.0, 
    241       'monomer_length':       10.0, 
     209      'virial_param':        180.0, 
     210      'monomer_length':        1.0, 
    242211      'salt_concentration':    0.1, 
    243212      'ionization_degree':     0.5, 
    244213      'polymer_concentration': 0.1, 
    245       'background':           0.01, 
    246      }, 0.5, 0.012881893], 
     214      'background':             0.0, 
     215     }, 200., 1.80664667511e-06], 
    247216    ] 
  • sasmodels/models/fcc_paracrystal.py

    rda7b26b r2d81cfe  
    33#note - calculation requires double precision 
    44r""" 
    5 .. warning:: This model and this model description are under review following  
    6              concerns raised by SasView users. If you need to use this model,  
    7              please email help@sasview.org for the latest situation. *The  
    8              SasView Developers. September 2018.* 
    9  
    10 Definition 
    11 ---------- 
    12  
    135Calculates the scattering from a **face-centered cubic lattice** with 
    146paracrystalline distortion. Thermal vibrations are considered to be 
     
    168Paracrystalline distortion is assumed to be isotropic and characterized by 
    179a Gaussian distribution. 
     10 
     11Definition 
     12---------- 
    1813 
    1914The scattering intensity $I(q)$ is calculated as 
     
    2823is the paracrystalline structure factor for a face-centered cubic structure. 
    2924 
    30 Equation (1) of the 1990 reference\ [#CIT1990]_ is used to calculate $Z(q)$, 
    31 using equations (23)-(25) from the 1987 paper\ [#CIT1987]_ for $Z1$, $Z2$, and 
    32 $Z3$. 
     25Equation (1) of the 1990 reference is used to calculate $Z(q)$, using 
     26equations (23)-(25) from the 1987 paper for $Z1$, $Z2$, and $Z3$. 
    3327 
    3428The lattice correction (the occupied volume of the lattice) for a 
     
    9488---------- 
    9589 
    96 .. [#CIT1987] Hideki Matsuoka et. al. *Physical Review B*, 36 (1987) 1754-1765 
    97    (Original Paper) 
    98 .. [#CIT1990] Hideki Matsuoka et. al. *Physical Review B*, 41 (1990) 3854 -3856 
    99    (Corrections to FCC and BCC lattice structure calculation) 
     90Hideki Matsuoka et. al. *Physical Review B*, 36 (1987) 1754-1765 
     91(Original Paper) 
    10092 
    101 Authorship and Verification 
    102 --------------------------- 
    103  
    104 * **Author:** NIST IGOR/DANSE **Date:** pre 2010 
    105 * **Last Modified by:** Paul Butler **Date:** September 29, 2016 
    106 * **Last Reviewed by:** Richard Heenan **Date:** March 21, 2016 
     93Hideki Matsuoka et. al. *Physical Review B*, 41 (1990) 3854 -3856 
     94(Corrections to FCC and BCC lattice structure calculation) 
    10795""" 
    10896 
  • sasmodels/models/sc_paracrystal.py

    rda7b26b r2d81cfe  
    11r""" 
    2 .. warning:: This model and this model description are under review following  
    3              concerns raised by SasView users. If you need to use this model,  
    4              please email help@sasview.org for the latest situation. *The  
    5              SasView Developers. September 2018.* 
    6               
    7 Definition 
    8 ---------- 
    9  
    102Calculates the scattering from a **simple cubic lattice** with 
    113paracrystalline distortion. Thermal vibrations are considered to be 
     
    135Paracrystalline distortion is assumed to be isotropic and characterized 
    146by a Gaussian distribution. 
     7 
     8Definition 
     9---------- 
    1510 
    1611The scattering intensity $I(q)$ is calculated as 
     
    2520$Z(q)$ is the paracrystalline structure factor for a simple cubic structure. 
    2621 
    27 Equation (16) of the 1987 reference\ [#CIT1987]_ is used to calculate $Z(q)$, 
    28 using equations (13)-(15) from the 1987 paper\ [#CIT1987]_ for $Z1$, $Z2$, and 
    29 $Z3$. 
     22Equation (16) of the 1987 reference is used to calculate $Z(q)$, using 
     23equations (13)-(15) from the 1987 paper for Z1, Z2, and Z3. 
    3024 
    3125The lattice correction (the occupied volume of the lattice) for a simple cubic 
     
    9791Reference 
    9892--------- 
     93Hideki Matsuoka et. al. *Physical Review B,* 36 (1987) 1754-1765 
     94(Original Paper) 
    9995 
    100 .. [#CIT1987] Hideki Matsuoka et. al. *Physical Review B*, 36 (1987) 1754-1765 
    101    (Original Paper) 
    102 .. [#CIT1990] Hideki Matsuoka et. al. *Physical Review B*, 41 (1990) 3854 -3856 
    103    (Corrections to FCC and BCC lattice structure calculation) 
    104  
    105 Authorship and Verification 
    106 --------------------------- 
    107  
    108 * **Author:** NIST IGOR/DANSE **Date:** pre 2010 
    109 * **Last Modified by:** Paul Butler **Date:** September 29, 2016 
    110 * **Last Reviewed by:** Richard Heenan **Date:** March 21, 2016 
     96Hideki Matsuoka et. al. *Physical Review B,* 41 (1990) 3854 -3856 
     97(Corrections to FCC and BCC lattice structure calculation) 
    11198""" 
    11299 
  • sasmodels/sasview_model.py

    rd321747 r0535624  
    6262#: set of defined models (standard and custom) 
    6363MODELS = {}  # type: Dict[str, SasviewModelType] 
    64 # TODO: remove unused MODEL_BY_PATH cache once sasview no longer references it 
    6564#: custom model {path: model} mapping so we can check timestamps 
    6665MODEL_BY_PATH = {}  # type: Dict[str, SasviewModelType] 
    67 #: Track modules that we have loaded so we can determine whether the model 
    68 #: has changed since we last reloaded. 
    69 _CACHED_MODULE = {}  # type: Dict[str, "module"] 
    7066 
    7167def find_model(modelname): 
     
    110106    Load a custom model given the model path. 
    111107    """ 
     108    model = MODEL_BY_PATH.get(path, None) 
     109    if model is not None and model.timestamp == getmtime(path): 
     110        #logger.info("Model already loaded %s", path) 
     111        return model 
     112 
    112113    #logger.info("Loading model %s", path) 
    113  
    114     # Load the kernel module.  This may already be cached by the loader, so 
    115     # only requires checking the timestamps of the dependents. 
    116114    kernel_module = custom.load_custom_kernel_module(path) 
    117  
    118     # Check if the module has changed since we last looked. 
    119     reloaded = kernel_module != _CACHED_MODULE.get(path, None) 
    120     _CACHED_MODULE[path] = kernel_module 
    121  
    122     # Turn the module into a model.  We need to do this in even if the 
    123     # model has already been loaded so that we can determine the model 
    124     # name and retrieve it from the MODELS cache. 
    125     model = getattr(kernel_module, 'Model', None) 
    126     if model is not None: 
     115    if hasattr(kernel_module, 'Model'): 
     116        model = kernel_module.Model 
    127117        # Old style models do not set the name in the class attributes, so 
    128118        # set it here; this name will be overridden when the object is created 
     
    137127        model_info = modelinfo.make_model_info(kernel_module) 
    138128        model = make_model_from_info(model_info) 
     129    model.timestamp = getmtime(path) 
    139130 
    140131    # If a model name already exists and we are loading a different model, 
     
    152143                    _previous_name, model.name, model.filename) 
    153144 
    154     # Only update the model if the module has changed 
    155     if reloaded or model.name not in MODELS: 
    156         MODELS[model.name] = model 
    157  
    158     return MODELS[model.name] 
     145    MODELS[model.name] = model 
     146    MODEL_BY_PATH[path] = model 
     147    return model 
    159148 
    160149 
Note: See TracChangeset for help on using the changeset viewer.