source: sasview/src/sas/sascalc/calculator/instrument.py @ e33fcd1

ESS_GUIESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_openclESS_GUI_sync_sascalc
Last change on this file since e33fcd1 was b8080e1, checked in by Piotr Rozyczko <rozyczko@…>, 6 years ago

cherry picking sascalc changes from master SASVIEW-996
minor unit test fixes

  • Property mode set to 100644
File size: 9.8 KB
Line 
1"""
2This module is a small tool to allow user to
3control instrumental parameters
4"""
5import numpy as np
6
7# defaults in cgs unit
8_SAMPLE_A_SIZE = [1.27]
9_SOURCE_A_SIZE = [3.81]
10_SAMPLE_DISTANCE = [1627, 0]
11_SAMPLE_OFFSET = [0, 0]
12_SAMPLE_SIZE = [2.54]
13_SAMPLE_THICKNESS = 0.2
14_D_DISTANCE = [1000, 0]
15_D_SIZE = [128, 128]
16_D_PIX_SIZE = [0.5, 0.5]
17
18_MIN = 0.0
19_MAX = 50.0
20_INTENSITY = 368428
21_WAVE_LENGTH = 6.0
22_WAVE_SPREAD = 0.125
23_MASS = 1.67492729E-24  # [gr]
24_LAMBDA_ARRAY = [[0, 1e+16], [_INTENSITY, _INTENSITY]]
25
26
27class Aperture(object):
28    """
29    An object class that defines the aperture variables
30    """
31    def __init__(self):
32
33        # assumes that all aligned at the centers
34        # aperture_size [diameter] for pinhole, [dx, dy] for rectangular
35        self.sample_size = _SAMPLE_A_SIZE
36        self.source_size = _SOURCE_A_SIZE
37        self.sample_distance = _SAMPLE_DISTANCE
38
39    def set_source_size(self, size=[]):
40        """
41        Set the source aperture size
42        """
43        if len(size) == 0:
44            self.source_size = 0.0
45        else:
46            self.source_size = size
47            validate(size[0])
48
49    def set_sample_size(self, size=[]):
50        """
51        Set the sample aperture size
52        """
53        if len(size) == 0:
54            self.sample_size = 0.0
55        else:
56            self.sample_size = size
57            validate(size[0])
58
59    def set_sample_distance(self, distance=[]):
60        """
61        Set the sample aperture distance
62        """
63        if len(distance) == 0:
64            self.sample_distance = 0.0
65        else:
66            self.sample_distance = distance
67            validate(distance[0])
68
69
70class Sample(object):
71    """
72    An object class that defines the sample variables
73    """
74    def __init__(self):
75
76        # assumes that all aligned at the centers
77        # source2sample or sample2detector distance
78        self.distance = _SAMPLE_OFFSET
79        self.size = _SAMPLE_SIZE
80        self.thickness = _SAMPLE_THICKNESS
81
82    def set_size(self, size=[]):
83        """
84        Set the sample size
85        """
86        if len(size) == 0:
87            self.size = 0.0
88        else:
89            self.size = size
90            validate(size[0])
91
92    def set_thickness(self, thickness=0.0):
93        """
94        Set the sample thickness
95        """
96        self.thickness = thickness
97        validate(thickness)
98
99    def set_distance(self, distance=[]):
100        """
101        Set the sample distance
102        """
103        if len(distance) == 0:
104            self.distance = 0.0
105        else:
106            self.distance = distance
107            if distance[0] != 0.0:
108                validate(distance[0])
109
110
111class Detector(object):
112    """
113    An object class that defines the detector variables
114    """
115    def __init__(self):
116
117        # assumes that all aligned at the centers
118        # source2sample or sample2detector distance
119        self.distance = _D_DISTANCE
120        self.size = _D_SIZE
121        self.pix_size = _D_PIX_SIZE
122
123    def set_size(self, size=[]):
124        """
125        Set the detector  size
126        """
127        if len(size) == 0:
128            self.size = 0
129        else:
130            self.size = size
131            validate(size[0])
132
133    def set_pix_size(self, size=[]):
134        """
135        Set the detector pix_size
136        """
137        if len(size) == 0:
138            self.pix_size = 0
139        else:
140            self.pix_size = size
141            validate(size[0])
142
143    def set_distance(self, distance=[]):
144        """
145        Set the detector distance
146        """
147        if len(distance) == 0:
148            self.distance = 0
149        else:
150            self.distance = distance
151            validate(distance[0])
152
153
154class Neutron(object):
155    """
156    An object that defines the wavelength variables
157    """
158    def __init__(self):
159
160        # neutron mass in cgs unit
161        self.mass = _MASS
162
163        # wavelength
164        self.wavelength = _WAVE_LENGTH
165        # wavelength spread (FWHM)
166        self.wavelength_spread = _WAVE_SPREAD
167        # wavelength spectrum
168        self.spectrum = self.get_default_spectrum()
169        # intensity in counts/sec
170        self.intensity = np.interp(self.wavelength,
171                                      self.spectrum[0],
172                                      self.spectrum[1],
173                                      0.0,
174                                      0.0)
175        # min max range of the spectrum
176        self.min = min(self.spectrum[0])
177        self.max = max(self.spectrum[0])
178        # wavelength band
179        self.band = [self.min, self.max]
180
181        # default unit of the thickness
182        self.wavelength_unit = 'A'
183
184    def set_full_band(self):
185        """
186        set band to default value
187        """
188        self.band = self.spectrum
189
190    def set_spectrum(self, spectrum):
191        """
192        Set spectrum
193
194        :param spectrum: numpy array
195        """
196        self.spectrum = spectrum
197        self.setup_spectrum()
198
199    def setup_spectrum(self):
200        """
201        To set the wavelength spectrum, and intensity, assumes
202        wavelength is already within the spectrum
203        """
204        spectrum = self.spectrum
205        intensity = np.interp(self.wavelength,
206                                 spectrum[0],
207                                 spectrum[1],
208                                 0.0,
209                                 0.0)
210        self.set_intensity(intensity)
211        # min max range of the spectrum
212        self.min = min(self.spectrum[0])
213        self.max = max(self.spectrum[0])
214        # set default band
215        self.set_band([self.min, self.max])
216
217    def set_band(self, band=[]):
218        """
219        To set the wavelength band
220
221        :param band: array of [min, max]
222        """
223        # check if the wavelength is in range
224        if min(band) < self.min or max(band) > self.max:
225            raise ValueError("band out of range")
226        self.band = band
227
228    def set_intensity(self, intensity=368428):
229        """
230        Sets the intensity in counts/sec
231        """
232        self.intensity = intensity
233        validate(intensity)
234
235    def set_wavelength(self, wavelength=_WAVE_LENGTH):
236        """
237        Sets the wavelength
238        """
239        # check if the wavelength is in range
240        if wavelength < min(self.band) or wavelength > max(self.band):
241            raise ValueError("wavelength out of range")
242        self.wavelength = wavelength
243        validate(wavelength)
244        self.intensity = np.interp(self.wavelength,
245                                      self.spectrum[0],
246                                      self.spectrum[1],
247                                      0.0,
248                                      0.0)
249
250    def set_mass(self, mass=_MASS):
251        """
252        Sets the wavelength
253        """
254        self.mass = mass
255        validate(mass)
256
257    def set_wavelength_spread(self, spread=_WAVE_SPREAD):
258        """
259        Sets the wavelength spread
260        """
261        self.wavelength_spread = spread
262        if spread != 0.0:
263            validate(spread)
264
265    def get_intensity(self):
266        """
267        To get the value of intensity
268        """
269        return self.intensity
270
271    def get_wavelength(self):
272        """
273        To get the value of wavelength
274        """
275        return self.wavelength
276
277    def get_mass(self):
278        """
279        To get the neutron mass
280        """
281        return self.mass
282
283    def get_wavelength_spread(self):
284        """
285        To get the value of wavelength spread
286        """
287        return self.wavelength_spread
288
289    def get_ramdom_value(self):
290        """
291        To get the value of wave length
292        """
293        return self.wavelength
294
295    def get_spectrum(self):
296        """
297        To get the wavelength spectrum
298        """
299        return self.spectrum
300
301    def get_default_spectrum(self):
302        """
303        get default spectrum
304        """
305        return np.array(_LAMBDA_ARRAY)
306
307    def get_band(self):
308        """
309        To get the wavelength band
310        """
311        return self.band
312
313    def plot_spectrum(self):
314        """
315        To plot the wavelength spactrum
316        : requirement: matplotlib.pyplot
317        """
318        try:
319            import matplotlib.pyplot as plt
320            plt.plot(self.spectrum[0], self.spectrum[1], linewidth=2, color='r')
321            plt.legend(['Spectrum'], loc='best')
322            plt.show()
323        except:
324            raise RuntimeError("Can't import matplotlib required to plot...")
325
326
327class TOF(Neutron):
328    """
329    TOF: make list of wavelength and wave length spreads
330    """
331    def __init__(self):
332        """
333        Init
334        """
335        Neutron.__init__(self)
336        #self.switch = switch
337        self.wavelength_list = [self.wavelength]
338        self.wavelength_spread_list = [self.wavelength_spread]
339        self.intensity_list = self.get_intensity_list()
340
341    def get_intensity_list(self):
342        """
343        get list of the intensity wrt wavelength_list
344        """
345        out = np.interp(self.wavelength_list,
346                           self.spectrum[0],
347                           self.spectrum[1],
348                           0.0,
349                           0.0)
350        return out
351
352    def get_wave_list(self):
353        """
354        Get wavelength and wavelength_spread list
355        """
356        return self.wavelength_list, self.wavelength_spread_list
357
358    def set_wave_list(self, wavelength=[]):
359        """
360        Set wavelength list
361
362        :param wavelength: list of wavelengths
363        """
364        self.wavelength_list = wavelength
365
366    def set_wave_spread_list(self, wavelength_spread=[]):
367        """
368        Set wavelength_spread list
369
370        :param wavelength_spread: list of wavelength spreads
371        """
372        self.wavelength_spread_list = wavelength_spread
373
374
375def validate(value=None):
376    """
377    Check if the value is folat > 0.0
378
379    :return value: True / False
380    """
381    try:
382        val = float(value)
383        if val >= 0:
384            val = True
385        else:
386            val = False
387    except:
388        val = False
Note: See TracBrowser for help on using the repository browser.