source: sasmodels/sasmodels/details.py @ a738209

core_shell_microgelscostrafo411magnetic_modelrelease_v0.94release_v0.95ticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since a738209 was a738209, checked in by Paul Kienzle <pkienzle@…>, 8 years ago

simplify kernels by remove coordination parameter logic

  • Property mode set to 100644
File size: 3.7 KB
Line 
1from __future__ import print_function
2
3import numpy as np  # type: ignore
4
5try:
6    from typing import List
7except ImportError:
8    pass
9else:
10    from .modelinfo import ModelInfo
11
12
13class CallDetails(object):
14    parts = None  # type: List["CallDetails"]
15    def __init__(self, model_info):
16        # type: (ModelInfo) -> None
17        parameters = model_info.parameters
18        max_pd = parameters.max_pd
19
20        # Structure of the call details buffer:
21        #   pd_par[max_pd]     pd params in order of length
22        #   pd_length[max_pd]  length of each pd param
23        #   pd_offset[max_pd]  offset of pd values in parameter array
24        #   pd_stride[max_pd]  index of pd value in loop = n//stride[k]
25        #   pd_prod            total length of pd loop
26        #   pd_sum             total length of the weight vector
27        #   num_active         number of pd params
28        #   theta_par          parameter number for theta parameter
29        self.buffer = np.zeros(4*max_pd + 4, 'i4')
30
31        # generate views on different parts of the array
32        self._pd_par     = self.buffer[0 * max_pd:1 * max_pd]
33        self._pd_length  = self.buffer[1 * max_pd:2 * max_pd]
34        self._pd_offset  = self.buffer[2 * max_pd:3 * max_pd]
35        self._pd_stride  = self.buffer[3 * max_pd:4 * max_pd]
36
37        # theta_par is fixed
38        self.theta_par = parameters.theta_offset
39
40    @property
41    def pd_par(self): return self._pd_par
42
43    @property
44    def pd_length(self): return self._pd_length
45
46    @property
47    def pd_offset(self): return self._pd_offset
48
49    @property
50    def pd_stride(self): return self._pd_stride
51
52    @property
53    def pd_prod(self): return self.buffer[-4]
54    @pd_prod.setter
55    def pd_prod(self, v): self.buffer[-4] = v
56
57    @property
58    def pd_sum(self): return self.buffer[-3]
59    @pd_sum.setter
60    def pd_sum(self, v): self.buffer[-3] = v
61
62    @property
63    def num_active(self): return self.buffer[-2]
64    @num_active.setter
65    def num_active(self, v): self.buffer[-2] = v
66
67    @property
68    def theta_par(self): return self.buffer[-1]
69    @theta_par.setter
70    def theta_par(self, v): self.buffer[-1] = v
71
72    def show(self):
73        print("num_active", self.num_active)
74        print("pd_prod", self.pd_prod)
75        print("pd_sum", self.pd_sum)
76        print("theta par", self.theta_par)
77        print("pd_par", self.pd_par)
78        print("pd_length", self.pd_length)
79        print("pd_offset", self.pd_offset)
80        print("pd_stride", self.pd_stride)
81
82def mono_details(model_info):
83    call_details = CallDetails(model_info)
84    call_details.pd_prod = 1
85    return call_details
86
87def poly_details(model_info, weights):
88    #print("weights",weights)
89    #weights = weights[2:] # Skip scale and background
90
91    # Decreasing list of polydispersity lengths
92    pd_length = np.array([len(w) for w in weights])
93    num_active = np.sum(pd_length>1)
94    if num_active > model_info.parameters.max_pd:
95        raise ValueError("Too many polydisperse parameters")
96
97    pd_offset = np.cumsum(np.hstack((0, pd_length)))
98    # Note: the reversing view, x[::-1], does not require a copy
99    idx = np.argsort(pd_length)[::-1][:num_active]
100    par_length = np.array([len(w) for w in weights])
101    pd_stride = np.cumprod(np.hstack((1, par_length[idx])))
102
103    call_details = CallDetails(model_info)
104    call_details.pd_par[:num_active] = idx - 2  # skip background & scale
105    call_details.pd_length[:num_active] = pd_length[idx]
106    call_details.pd_offset[:num_active] = pd_offset[idx]
107    call_details.pd_stride[:num_active] = pd_stride[:-1]
108    call_details.pd_prod = pd_stride[-1]
109    call_details.pd_sum = np.sum(par_length)
110    call_details.num_active = num_active
111    #call_details.show()
112    return call_details
Note: See TracBrowser for help on using the repository browser.