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

Last change on this file since e29c798 was b699768, checked in by Piotr Rozyczko <piotr.rozyczko@…>, 9 years ago

Initial commit of the refactored SasCalc? module.

  • 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
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 = numpy.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 = numpy.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\
225                max(band) > self.max:
226            raise
227        self.band = band
228
229    def set_intensity(self, intensity=368428):
230        """
231        Sets the intensity in counts/sec
232        """
233        self.intensity = intensity
234        validate(intensity)
235
236    def set_wavelength(self, wavelength=_WAVE_LENGTH):
237        """
238        Sets the wavelength
239        """
240        # check if the wavelength is in range
241        if wavelength < min(self.band) or\
242                wavelength > max(self.band):
243            raise
244        self.wavelength = wavelength
245        validate(wavelength)
246        self.intensity = numpy.interp(self.wavelength,
247                                      self.spectrum[0],
248                                      self.spectrum[1],
249                                      0.0,
250                                      0.0)
251
252    def set_mass(self, mass=_MASS):
253        """
254        Sets the wavelength
255        """
256        self.mass = mass
257        validate(mass)
258
259    def set_wavelength_spread(self, spread=_WAVE_SPREAD):
260        """
261        Sets the wavelength spread
262        """
263        self.wavelength_spread = spread
264        if spread != 0.0:
265            validate(spread)
266
267    def get_intensity(self):
268        """
269        To get the value of intensity
270        """
271        return self.intensity
272
273    def get_wavelength(self):
274        """
275        To get the value of wavelength
276        """
277        return self.wavelength
278
279    def get_mass(self):
280        """
281        To get the neutron mass
282        """
283        return self.mass
284
285    def get_wavelength_spread(self):
286        """
287        To get the value of wavelength spread
288        """
289        return self.wavelength_spread
290
291    def get_ramdom_value(self):
292        """
293        To get the value of wave length
294        """
295        return self.wavelength
296
297    def get_spectrum(self):
298        """
299        To get the wavelength spectrum
300        """
301        return self.spectrum
302
303    def get_default_spectrum(self):
304        """
305        get default spectrum
306        """
307        return numpy.array(_LAMBDA_ARRAY)
308
309    def get_band(self):
310        """
311        To get the wavelength band
312        """
313        return self.band
314
315    def plot_spectrum(self):
316        """
317        To plot the wavelength spactrum
318        : requirment: matplotlib.pyplot
319        """
320        try:
321            import matplotlib.pyplot as plt
322            plt.plot(self.spectrum[0], self.spectrum[1], linewidth=2, color='r')
323            plt.legend(['Spectrum'], loc='best')
324            plt.show()
325        except:
326            raise RuntimeError, "Can't import matplotlib required to plot..."
327
328
329class TOF(Neutron):
330    """
331    TOF: make list of wavelength and wave length spreads
332    """
333    def __init__(self):
334        """
335        Init
336        """
337        Neutron.__init__(self)
338        #self.switch = switch
339        self.wavelength_list = [self.wavelength]
340        self.wavelength_spread_list = [self.wavelength_spread]
341        self.intensity_list = self.get_intensity_list()
342
343    def get_intensity_list(self):
344        """
345        get list of the intensity wrt wavelength_list
346        """
347        out = numpy.interp(self.wavelength_list,
348                           self.spectrum[0],
349                           self.spectrum[1],
350                           0.0,
351                           0.0)
352        return out
353
354    def get_wave_list(self):
355        """
356        Get wavelength and wavelength_spread list
357        """
358        return self.wavelength_list, self.wavelength_spread_list
359
360    def set_wave_list(self, wavelength=[]):
361        """
362        Set wavelength list
363
364        :param wavelength: list of wavelengths
365        """
366        self.wavelength_list = wavelength
367
368    def set_wave_spread_list(self, wavelength_spread=[]):
369        """
370        Set wavelength_spread list
371
372        :param wavelength_spread: list of wavelength spreads
373        """
374        self.wavelength_spread_list = wavelength_spread
375
376
377def validate(value=None):
378    """
379    Check if the value is folat > 0.0
380
381    :return value: True / False
382    """
383    try:
384        val = float(value)
385        if val >= 0:
386            val = True
387        else:
388            val = False
389    except:
390        val = False
Note: See TracBrowser for help on using the repository browser.