source: sasview/src/sas/sasgui/perspectives/file_converter/meta_panels.py @ 6bd4235

magnetic_scattrelease-4.2.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249unittest-saveload
Last change on this file since 6bd4235 was ba65aff, checked in by lewis, 8 years ago

Add docstrings & comments, and rename old bsl_loader to otoko_loader

  • Property mode set to 100644
File size: 16.2 KB
Line 
1import wx
2import sys
3from sas.sasgui.perspectives.calculator import calculator_widgets as widget
4from sas.sasgui.perspectives.file_converter.converter_widgets import VectorInput
5from wx.lib.scrolledpanel import ScrolledPanel
6from sas.sasgui.guiframe.panel_base import PanelBase
7from sas.sascalc.dataloader.data_info import Detector
8from sas.sasgui.guiframe.events import StatusEvent
9from sas.sasgui.guiframe.utils import check_float
10
11if sys.platform.count("win32") > 0:
12    PANEL_TOP = 0
13    _STATICBOX_WIDTH = 350
14    PANEL_SIZE = 440
15    FONT_VARIANT = 0
16else:
17    PANEL_TOP = 60
18    _STATICBOX_WIDTH = 380
19    PANEL_SIZE = 470
20    FONT_VARIANT = 1
21
22class MetadataPanel(ScrolledPanel, PanelBase):
23    """
24    A common base class to be extended by panels that deal with metadata input.
25    Handles input validation and passing inputted data back to ConverterPanel.
26    """
27
28    def __init__(self, parent, metadata, base=None, *args, **kwargs):
29        ScrolledPanel.__init__(self, parent, *args, **kwargs)
30        PanelBase.__init__(self)
31        self.SetupScrolling()
32        self.SetWindowVariant(variant=FONT_VARIANT)
33
34        self.base = base
35        self.parent = parent
36        self._to_validate = [] # An list of inputs that should contain floats
37        self._vectors = [] # A list of VectorInputs to be validated
38        self.metadata = metadata
39
40    def get_property_string(self, name, is_float=False):
41        value = getattr(self.metadata, name)
42        if value is None or value == []:
43            value = ''
44            is_float = False
45        if isinstance(value, list):
46            value = value[0]
47        value = str(value)
48        if is_float and not '.' in value: value += '.0'
49        return value
50
51    def on_change(self, event):
52        ctrl = event.GetEventObject()
53        value = ctrl.GetValue()
54        name = ctrl.GetName()
55        old_value = getattr(self.metadata, name)
56        if value == '': value = None
57        if isinstance(old_value, list): value = [value]
58
59        setattr(self.metadata, name, value)
60
61    def on_close(self, event=None):
62        for ctrl in self._to_validate:
63            ctrl.SetBackgroundColour(wx.WHITE)
64            if ctrl.GetValue() == '': continue
65            if not check_float(ctrl):
66                msg = "{} must be a valid float".format(
67                    ctrl.GetName().replace("_", " "))
68                wx.PostEvent(self.parent.manager.parent.manager.parent,
69                    StatusEvent(status=msg, info='error'))
70                return False
71        for vector_in in self._vectors:
72            is_valid, invalid_ctrl = vector_in.Validate()
73            if not is_valid:
74                msg = "{} must be a valid float".format(
75                    invalid_ctrl.GetName().replace("_", " "))
76                wx.PostEvent(self.parent.manager.parent.manager.parent,
77                    StatusEvent(status=msg, info='error'))
78                return False
79            setattr(self.metadata, vector_in.GetName(), vector_in.GetValue())
80        return True
81
82class DetectorPanel(MetadataPanel):
83
84    def __init__(self, parent, detector, base=None, *args, **kwargs):
85        if detector.name is None:
86            detector.name = ''
87
88        MetadataPanel.__init__(self, parent, detector, base, *args, **kwargs)
89
90        self._do_layout()
91        self.SetAutoLayout(True)
92        self.Layout()
93
94    def on_close(self, event=None):
95        if not MetadataPanel.on_close(self, event):
96            return
97
98        self.parent.manager.detector = self.metadata
99        self.parent.on_close(event)
100
101    def _do_layout(self):
102        vbox = wx.BoxSizer(wx.VERTICAL)
103
104        section = wx.StaticBox(self, -1, "Detector")
105        section_sizer = wx.StaticBoxSizer(section, wx.VERTICAL)
106        section_sizer.SetMinSize((_STATICBOX_WIDTH, -1))
107
108        input_grid = wx.GridBagSizer(5, 5)
109
110        y = 0
111        name_label = wx.StaticText(self, -1, "Name: ")
112        input_grid.Add(name_label, (y,0), (1,1), wx.ALL, 5)
113        name_input = wx.TextCtrl(self, -1, name="name")
114        input_grid.Add(name_input, (y,1), (1,1))
115        name_input.Bind(wx.EVT_TEXT, self.on_change)
116        y += 1
117
118        distance_label = wx.StaticText(self, -1,
119            "Distance (mm): ")
120        input_grid.Add(distance_label, (y, 0), (1,1), wx.ALL, 5)
121        distance_input = wx.TextCtrl(self, -1,
122            name="distance", size=(50,-1))
123        input_grid.Add(distance_input, (y,1), (1,1))
124        distance_input.Bind(wx.EVT_TEXT, self.on_change)
125        self._to_validate.append(distance_input)
126        y += 1
127
128        offset_label = wx.StaticText(self, -1, "Offset (mm): ")
129        input_grid.Add(offset_label, (y,0), (1,1), wx.ALL, 5)
130        offset_input = VectorInput(self, "offset")
131        input_grid.Add(offset_input.GetSizer(), (y,1), (1,1))
132        self._vectors.append(offset_input)
133        y += 1
134
135        orientation_label = wx.StaticText(self, -1, "Orientation (\xb0): ")
136        input_grid.Add(orientation_label, (y,0), (1,1), wx.ALL, 5)
137        orientation_input = VectorInput(self, "orientation", z_enabled=True,
138            labels=["Roll: ", "Pitch: ", "Yaw: "])
139        input_grid.Add(orientation_input.GetSizer(), (y,1), (1,1))
140        self._vectors.append(orientation_input)
141        y += 1
142
143        pixel_label = wx.StaticText(self, -1, "Pixel Size (mm): ")
144        input_grid.Add(pixel_label, (y,0), (1,1), wx.ALL, 5)
145        pixel_input = VectorInput(self, "pixel_size")
146        input_grid.Add(pixel_input.GetSizer(), (y,1), (1,1))
147        self._vectors.append(pixel_input)
148        y += 1
149
150        beam_label = wx.StaticText(self, -1, "Beam Center (mm): ")
151        input_grid.Add(beam_label, (y,0), (1,1), wx.ALL, 5)
152        beam_input = VectorInput(self, "beam_center")
153        input_grid.Add(beam_input.GetSizer(), (y,1), (1,1))
154        self._vectors.append(beam_input)
155        y += 1
156
157        slit_label = wx.StaticText(self, -1, "Slit Length (mm): ")
158        input_grid.Add(slit_label, (y,0), (1,1), wx.ALL, 5)
159        slit_input = wx.TextCtrl(self, -1, name="slit_length", size=(50,-1))
160        input_grid.Add(slit_input, (y,1), (1,1))
161        slit_input.Bind(wx.EVT_TEXT, self.on_change)
162        self._to_validate.append(slit_input)
163        y += 1
164
165        done_btn = wx.Button(self, -1, "Done")
166        input_grid.Add(done_btn, (y,0), (1,1), wx.ALL, 5)
167        done_btn.Bind(wx.EVT_BUTTON, self.on_close)
168
169        section_sizer.Add(input_grid)
170        vbox.Add(section_sizer, flag=wx.ALL, border=10)
171
172        name_input.SetValue(self.metadata.name)
173        distance = self.get_property_string("distance", is_float=True)
174        distance_input.SetValue(distance)
175        offset_input.SetValue(self.metadata.offset)
176        orientation_input.SetValue(self.metadata.orientation)
177        pixel_input.SetValue(self.metadata.pixel_size)
178        beam_input.SetValue(self.metadata.beam_center)
179        slit_len = self.get_property_string("slit_length", is_float=True)
180        slit_input.SetValue(slit_len)
181
182        vbox.Fit(self)
183        self.SetSizer(vbox)
184
185class SamplePanel(MetadataPanel):
186
187    def __init__(self, parent, sample, base=None, *args, **kwargs):
188        MetadataPanel.__init__(self, parent, sample, base, *args, **kwargs)
189        if sample.name is None:
190            sample.name = ''
191
192        self._do_layout()
193        self.SetAutoLayout(True)
194        self.Layout()
195
196    def on_close(self, event=None):
197        if not MetadataPanel.on_close(self, event):
198            return
199
200        self.parent.manager.sample = self.metadata
201        self.parent.on_close(event)
202
203    def _do_layout(self):
204        vbox = wx.BoxSizer(wx.VERTICAL)
205
206        section = wx.StaticBox(self, -1, "Sample")
207        section_sizer = wx.StaticBoxSizer(section, wx.VERTICAL)
208        section_sizer.SetMinSize((_STATICBOX_WIDTH, -1))
209
210        input_grid = wx.GridBagSizer(5, 5)
211
212        y = 0
213        name_label = wx.StaticText(self, -1, "Name: ")
214        input_grid.Add(name_label, (y,0), (1,1), wx.ALL, 5)
215        name_input = wx.TextCtrl(self, -1, name="name")
216        input_grid.Add(name_input, (y,1), (1,1))
217        name_input.Bind(wx.EVT_TEXT, self.on_change)
218        y += 1
219
220        thickness_label = wx.StaticText(self, -1, "Thickness (mm): ")
221        input_grid.Add(thickness_label, (y,0), (1,1), wx.ALL, 5)
222        thickness_input = wx.TextCtrl(self, -1, name="thickness")
223        input_grid.Add(thickness_input, (y,1), (1,1))
224        thickness_input.Bind(wx.EVT_TEXT, self.on_change)
225        self._to_validate.append(thickness_input)
226        y += 1
227
228        transmission_label = wx.StaticText(self, -1, "Transmission: ")
229        input_grid.Add(transmission_label, (y,0), (1,1), wx.ALL, 5)
230        transmission_input = wx.TextCtrl(self, -1, name="transmission")
231        input_grid.Add(transmission_input, (y,1), (1,1))
232        transmission_input.Bind(wx.EVT_TEXT, self.on_change)
233        self._to_validate.append(transmission_input)
234        y += 1
235
236        temperature_label = wx.StaticText(self, -1, "Temperature: ")
237        input_grid.Add(temperature_label, (y,0), (1,1), wx.ALL, 5)
238        temperature_input = wx.TextCtrl(self, -1, name="temperature")
239        temperature_input.Bind(wx.EVT_TEXT, self.on_change)
240        self._to_validate.append(temperature_input)
241        input_grid.Add(temperature_input, (y,1), (1,1))
242        temp_unit_label = wx.StaticText(self, -1, "Unit: ")
243        input_grid.Add(temp_unit_label, (y,2), (1,1))
244        temp_unit_input = wx.TextCtrl(self, -1, name="temperature_unit",
245            size=(50,-1))
246        temp_unit_input.Bind(wx.EVT_TEXT, self.on_change)
247        input_grid.Add(temp_unit_input, (y,3), (1,1))
248        y += 1
249
250        position_label = wx.StaticText(self, -1, "Position (mm): ")
251        input_grid.Add(position_label, (y,0), (1,1), wx.ALL, 5)
252        position_input = VectorInput(self, "position")
253        self._vectors.append(position_input)
254        input_grid.Add(position_input.GetSizer(), (y,1), (1,2))
255        y += 1
256
257        orientation_label = wx.StaticText(self, -1, "Orientation (\xb0): ")
258        input_grid.Add(orientation_label, (y,0), (1,1), wx.ALL, 5)
259        orientation_input = VectorInput(self, "orientation",
260            labels=["Roll: ", "Pitch: ", "Yaw: "], z_enabled=True)
261        self._vectors.append(orientation_input)
262        input_grid.Add(orientation_input.GetSizer(), (y,1), (1,3))
263        y += 1
264
265        details_label = wx.StaticText(self, -1, "Details: ")
266        input_grid.Add(details_label, (y,0), (1,1), wx.ALL, 5)
267        details_input = wx.TextCtrl(self, -1, name="details",
268            style=wx.TE_MULTILINE)
269        input_grid.Add(details_input, (y,1), (3,3), wx.EXPAND)
270        y += 3
271
272        name_input.SetValue(self.metadata.name)
273        thickness_input.SetValue(
274            self.get_property_string("thickness", is_float=True))
275        transmission_input.SetValue(
276            self.get_property_string("transmission", is_float=True))
277        temperature_input.SetValue(
278            self.get_property_string("temperature", is_float=True))
279        temp_unit_input.SetValue(self.get_property_string("temperature_unit"))
280        position_input.SetValue(self.metadata.position)
281        orientation_input.SetValue(self.metadata.orientation)
282        details_input.SetValue(self.get_property_string("details"))
283        details_input.Bind(wx.EVT_TEXT, self.on_change)
284
285        done_btn = wx.Button(self, -1, "Done")
286        input_grid.Add(done_btn, (y,0), (1,1), wx.ALL, 5)
287        done_btn.Bind(wx.EVT_BUTTON, self.on_close)
288
289        section_sizer.Add(input_grid)
290        vbox.Add(section_sizer, flag=wx.ALL, border=10)
291
292        vbox.Fit(self)
293        self.SetSizer(vbox)
294
295class SourcePanel(MetadataPanel):
296
297    def __init__(self, parent, source, base=None, *args, **kwargs):
298        MetadataPanel.__init__(self, parent, source, base, *args, **kwargs)
299        if source.name is None:
300            source.name = ''
301        source.wavelength_unit = 'nm'
302
303        self._do_layout()
304        self.SetAutoLayout(True)
305        self.Layout()
306
307    def on_close(self, event=None):
308        if not MetadataPanel.on_close(self, event):
309            return
310
311        self.parent.manager.source = self.metadata
312        self.parent.on_close(event)
313
314    def _do_layout(self):
315        vbox = wx.BoxSizer(wx.VERTICAL)
316
317        section = wx.StaticBox(self, -1, "Source")
318        section_sizer = wx.StaticBoxSizer(section, wx.VERTICAL)
319        section_sizer.SetMinSize((_STATICBOX_WIDTH, -1))
320
321        input_grid = wx.GridBagSizer(5, 5)
322
323        y = 0
324        name_label = wx.StaticText(self, -1, "Name: ")
325        input_grid.Add(name_label, (y,0), (1,1), wx.ALL, 5)
326        name_input = wx.TextCtrl(self, -1, name="name")
327        input_grid.Add(name_input, (y,1), (1,1))
328        name_input.Bind(wx.EVT_TEXT, self.on_change)
329        y += 1
330
331        size_label = wx.StaticText(self, -1, "Beam Size (mm): ")
332        input_grid.Add(size_label, (y,0), (1,1), wx.ALL, 5)
333        size_input = VectorInput(self, "beam_size")
334        self._vectors.append(size_input)
335        input_grid.Add(size_input.GetSizer(), (y,1), (1,1))
336        y += 1
337
338        shape_label = wx.StaticText(self, -1, "Beam Shape: ")
339        input_grid.Add(shape_label, (y,0), (1,1), wx.ALL, 5)
340        shape_input = wx.TextCtrl(self, -1, name="beam_shape")
341        shape_input.Bind(wx.EVT_TEXT, self.on_change)
342        input_grid.Add(shape_input, (y,1), (1,1))
343        y += 1
344
345        wavelength_label = wx.StaticText(self, -1, "Wavelength (nm): ")
346        input_grid.Add(wavelength_label, (y,0), (1,1), wx.ALL, 5)
347        wavelength_input = wx.TextCtrl(self, -1, name="wavelength",
348            size=(50,-1))
349        wavelength_input.Bind(wx.EVT_TEXT, self.on_change)
350        self._to_validate.append(wavelength_input)
351        input_grid.Add(wavelength_input, (y,1), (1,1))
352        y += 1
353
354        min_wavelength_label = wx.StaticText(self, -1, "Min. Wavelength (nm): ")
355        input_grid.Add(min_wavelength_label, (y,0), (1,1), wx.ALL, 5)
356        min_wavelength_input = wx.TextCtrl(self, -1, name="wavelength_min",
357            size=(50,-1))
358        min_wavelength_input.Bind(wx.EVT_TEXT, self.on_change)
359        self._to_validate.append(min_wavelength_input)
360        input_grid.Add(min_wavelength_input, (y,1), (1,1))
361        y += 1
362
363        max_wavelength_label = wx.StaticText(self, -1, "Max. Wavelength (nm): ")
364        input_grid.Add(max_wavelength_label, (y,0), (1,1), wx.ALL, 5)
365        max_wavelength_input = wx.TextCtrl(self, -1, name="wavelength_max",
366            size=(50,-1))
367        max_wavelength_input.Bind(wx.EVT_TEXT, self.on_change)
368        self._to_validate.append(max_wavelength_input)
369        input_grid.Add(max_wavelength_input, (y,1), (1,1))
370        y += 1
371
372        wavelength_spread_label = wx.StaticText(self, -1,
373            "Wavelength Spread (%): ")
374        input_grid.Add(wavelength_spread_label, (y,0), (1,1), wx.ALL, 5)
375        wavelength_spread_input = wx.TextCtrl(self, -1,
376            name="wavelength_spread", size=(50,-1))
377        wavelength_spread_input.Bind(wx.EVT_TEXT, self.on_change)
378        self._to_validate.append(wavelength_spread_input)
379        input_grid.Add(wavelength_spread_input, (y,1), (1,1))
380        y += 1
381
382        name_input.SetValue(self.get_property_string("name"))
383        size_input.SetValue(self.metadata.beam_size)
384        shape_input.SetValue(self.get_property_string("beam_shape"))
385        wavelength_input.SetValue(
386            self.get_property_string("wavelength", is_float=True))
387        min_wavelength_input.SetValue(
388            self.get_property_string("wavelength_min", is_float=True))
389        max_wavelength_input.SetValue(
390            self.get_property_string("wavelength_max", is_float=True))
391
392        done_btn = wx.Button(self, -1, "Done")
393        input_grid.Add(done_btn, (y,0), (1,1), wx.ALL, 5)
394        done_btn.Bind(wx.EVT_BUTTON, self.on_close)
395
396        section_sizer.Add(input_grid)
397        vbox.Add(section_sizer, flag=wx.ALL, border=10)
398
399        vbox.Fit(self)
400        self.SetSizer(vbox)
401
402
403class MetadataWindow(widget.CHILD_FRAME):
404
405    def __init__(self, PanelClass, parent=None, title='', base=None,
406        manager=None, size=(PANEL_SIZE, PANEL_SIZE*0.8), metadata=None,
407         *args, **kwargs):
408        kwargs['title'] = title
409        kwargs['size'] = size
410        widget.CHILD_FRAME.__init__(self, parent, *args, **kwargs)
411
412        self.manager = manager
413        self.panel = PanelClass(self, metadata, base=None)
414        self.Bind(wx.EVT_CLOSE, self.on_close)
415
416    def on_close(self, event):
417        if self.manager is not None:
418            self.manager.meta_frames.remove(self)
419        self.Destroy()
Note: See TracBrowser for help on using the repository browser.