From b993fe3aa538ae673fec8e97fb417d25c969af08 Mon Sep 17 00:00:00 2001 From: Yusuf Ameri cianaki Date: Wed, 16 Jul 2014 10:16:21 -0400 Subject: [PATCH 1/3] The majority of "additions" were added in the model_view module. A new feature that enables the user to insert, edit, and remove layers in the stack has been added in the popup menu of the profile interactor. The user may not insert layers before the first layer. The user may not remove layers when there are only two layers in the stack. Another feature that was added was the experiment dialog that allows the user to edit the current experiment. The user has the option to enable or disable step interfaces, edit the dA, the dz, and the roughness limit. When the user presses "Ok" on the experiment dialog, the profile is updated with the data. --- refl1d/experiment.py | 25 +- refl1d/fitplugin.py | 4 +- refl1d/model.py | 10 +- refl1d/probe.py | 2 +- refl1d/profile.py | 8 + refl1d/view/interface.py | 3 +- refl1d/view/model_view.py | 484 ++++++++++++++++++++++++++++++++++---- refl1d/view/thickness.py | 4 +- run.py | 2 +- 9 files changed, 481 insertions(+), 61 deletions(-) diff --git a/refl1d/experiment.py b/refl1d/experiment.py index 41906223..88a91213 100644 --- a/refl1d/experiment.py +++ b/refl1d/experiment.py @@ -286,19 +286,36 @@ def __init__(self, sample=None, probe=None, name=None, self.sample = sample self._substrate=self.sample[0].material self._surface=self.sample[-1].material - self.probe = probe self.roughness_limit = roughness_limit if dz is None: dz = nice((2*pi/probe.Q.max())/10) if dz > 5: dz = 5 - self.dz = dz + # TODO: probe and dz are mutually dependent + self._slabs = profile.Microslabs(1, dz=dz) + self.probe = probe self.dA = dA self.step_interfaces = step_interfaces - self._slabs = profile.Microslabs(len(probe.unique_L) if probe.unique_L is not None else 1, dz=dz) - self._probe_cache = material.ProbeCache(probe) self._cache = {} # Cache calculated profiles/reflectivities self._name = name + @property + def probe(self): + return self._probe + + @probe.setter + def probe(self, probe): + self._probe = probe + self._probe_cache = material.ProbeCache(probe) + self._slabs.nprobe = len(probe.unique_L) if probe.unique_L is not None else 1 + + @property + def dz(self): + return self._slabs.dz + + @dz.setter + def dz(self, value): + self._slabs.dz = value + @property def ismagnetic(self): slabs = self._render_slabs() diff --git a/refl1d/fitplugin.py b/refl1d/fitplugin.py index 9ed8d81d..faf3625d 100644 --- a/refl1d/fitplugin.py +++ b/refl1d/fitplugin.py @@ -38,7 +38,9 @@ def load_model(filename): return None def new_model(): - stack = refl.silicon(0,10) | refl.air + silicon = refl.SLD('Si', 2.07) + air = refl.SLD('air', 0) + stack = silicon(0, 10) | air instrument = refl.NCNR.NG1() probe = instrument.probe(T=numpy.linspace(0,5,200), Tlo=0.2, slits_at_Tlo=2) diff --git a/refl1d/model.py b/refl1d/model.py index 1aba1e96..3e4ac5bc 100644 --- a/refl1d/model.py +++ b/refl1d/model.py @@ -21,6 +21,7 @@ # => smaller roughness # => thickness depends on where the beam spot hits the sample # Xray thickness variance = neutron roughness - xray roughness +from refl1d.material import SLD __all__ = ['Repeat','Slab','Stack','Layer'] @@ -34,6 +35,7 @@ import periodictable.nsf as nsf from bumps.parameter import Parameter as Par, IntegerParameter as IntPar, Function +from bumps.gui import signal from . import material @@ -455,7 +457,12 @@ def __setitem__(self, idx, other): def __delitem__(self, idx): stack,idx = self._lookup(idx) # works the same for slices and individual indices - del stack._layers[idx] + if(len(stack)>2 and (idx>=0 and idx < len(stack))): + del stack._layers[idx] + else: + import logging;logging.error("You cannot remove this layer. You need at least 2 layers!") + signal.log_message("You cannot remove this layer. You need at least 2 layers!") + def insert(self, idx, other): """ @@ -463,6 +470,7 @@ def insert(self, idx, other): another stack, the stack will be expanded to accommodate. You cannot make nested stacks. """ + stack,idx = self._lookup(idx) if isinstance(other,Stack): for i,L in enumerate(other._layers): diff --git a/refl1d/probe.py b/refl1d/probe.py index 2ed79477..8ad8c6e0 100644 --- a/refl1d/probe.py +++ b/refl1d/probe.py @@ -1027,7 +1027,7 @@ def __init__(self, Q, dQ, data=None, name=None, self.back_absorption = Parameter.default(back_absorption, name="back_absorption"+qualifier, limits=[0,1]) - self.theta_offset = Constant(0,name="theta_offset"+qualifier) + self.theta_offset = Constant(0, name="theta_offset"+qualifier) self.back_reflectivity = back_reflectivity diff --git a/refl1d/profile.py b/refl1d/profile.py index 4b94c103..05c88d56 100644 --- a/refl1d/profile.py +++ b/refl1d/profile.py @@ -93,6 +93,14 @@ def __init__(self, nprobe, dz=1): self._z_offset = 0 self._magnetic_sections = [] + @property + def nprobe(self): + return self._slabs_rho.shape[1] + @nprobe.setter + def nprobe(self, n): + if self.nprobe != n: + self._slabs_rho = numpy.empty(shape=(0,nprobe,2)) + def microslabs(self, thickness=0): """ Return a set of microslabs for a layer of the given *thickness*. diff --git a/refl1d/view/interface.py b/refl1d/view/interface.py index b34a3865..5625c141 100644 --- a/refl1d/view/interface.py +++ b/refl1d/view/interface.py @@ -5,6 +5,7 @@ from .config import interface_color, pick_radius from .interactor import BaseInteractor from .util import clip, setpar +import numpy MAX_ROUGH=3 @@ -24,7 +25,7 @@ def __init__(self, profile): color = interface_color, alpha = 0.6, pickradius = pick_radius, - zorder = 8, #Prefer this to other lines + zorder = numpy.inf, #Prefer this to other lines visible = False, ) self.markers=[ax.plot([0],[0.05], label=label, **style)[0] diff --git a/refl1d/view/model_view.py b/refl1d/view/model_view.py index 9df27f67..a7bc370f 100644 --- a/refl1d/view/model_view.py +++ b/refl1d/view/model_view.py @@ -5,11 +5,11 @@ import os import wx -IS_MAC = (wx.Platform == '__WXMAC__') +import wx.lib.filebrowsebutton as filebrowse import numpy from matplotlib.figure import Figure -from matplotlib.axes import Subplot +from matplotlib.axes import Subplot from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas from matplotlib.backends.backend_wxagg import FigureManager from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg @@ -18,41 +18,45 @@ from bumps.gui import signal from refl1d.experiment import MixedExperiment +from refl1d.material import SLD +from refl1d.model import Slab -#from .binder import pixel_to_data +# from .binder import pixel_to_data from .util import CopyImage from .profilei import ProfileInteractor from .interactor import BaseInteractor +IS_MAC = (wx.Platform == '__WXMAC__') + # ------------------------------------------------------------------------ class ModelView(wx.Panel): title = 'Profile' - default_size = (600,400) - def __init__( self, *args, **kw): + default_size = (600, 400) + def __init__(self, *args, **kw): wx.Panel.__init__(self, *args, **kw) # Fig - self.fig = Figure( figsize = (1,1), - dpi = 75, - facecolor = 'white', - edgecolor = 'white', - ) + self.fig = Figure(figsize=(1, 1), + dpi=75, + facecolor='white', + edgecolor='white', + ) # Canvas self.canvas = FigureCanvas(self, -1, self.fig) self.fig.set_canvas(self.canvas) # Axes - self.axes = self.fig.add_axes( Subplot(self.fig, 111)) + self.axes = self.fig.add_axes(Subplot(self.fig, 111)) self.axes.set_autoscale_on(False) self.theta_axes = self.axes.twinx() self.theta_axes.set_autoscale_on(False) # Show toolbar or not? - self.toolbar = NavigationToolbar2WxAgg( self.canvas ) + self.toolbar = NavigationToolbar2WxAgg(self.canvas) self.toolbar.Show(True) # Create a figure manager to manage things - self.figmgr = FigureManager( self.canvas, 1, self ) + self.figmgr = FigureManager(self.canvas, 1, self) # Panel layout self.profile_selector_label = wx.StaticText(self, label="Sample") @@ -61,10 +65,10 @@ def __init__( self, *args, **kw): self.profile_selector_label.Hide() self.Bind(wx.EVT_CHOICE, self.OnProfileSelect) - self.sizer = wx.BoxSizer( wx.VERTICAL ) + self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.Add( self.canvas,1, border=2, flag= wx.LEFT|wx.TOP|wx.GROW) self.tbsizer = wx.BoxSizer(wx.HORIZONTAL) - self.tbsizer.Add(self.toolbar,0,wx.ALIGN_CENTER_VERTICAL) + self.tbsizer.Add(self.toolbar, 0, wx.ALIGN_CENTER_VERTICAL) self.tbsizer.AddSpacer(20) self.tbsizer.Add(self.profile_selector_label, 0, wx.ALIGN_CENTER_VERTICAL) @@ -73,7 +77,7 @@ def __init__( self, *args, **kw): 0, wx.ALIGN_CENTER_VERTICAL) self.sizer.Add(self.tbsizer) - self.SetSizer( self.sizer) + self.SetSizer(self.sizer) self.sizer.Fit(self) # Status bar @@ -84,7 +88,7 @@ def __init__( self, *args, **kw): status_update = lambda msg: self.statusbar.SetStatusText(msg) # Set the profile interactor - self.profile = ProfileInteractor(self.axes,self.theta_axes, + self.profile = ProfileInteractor(self.axes, self.theta_axes, status_update=status_update) # Add context menu and keyboard support to canvas @@ -95,24 +99,66 @@ def __init__( self, *args, **kw): self._need_set_model = self._need_redraw = False self.Bind(wx.EVT_SHOW, self.OnShow) - def OnContextMenu(self,event): + def OnContextMenu(self, event): """ Forward the context menu invocation to profile, if profile exists. """ - sx,sy = event.GetX(), event.GetY() + sx, sy = event.GetX(), event.GetY() #transform = self.axes.transData #data_x,data_y = pixel_to_data(transform, sx, self.fig.bbox.height-sy) - + #print "data_x: %s \rdata_y: %s " %(data_x,data_y) popup = wx.Menu() - item = popup.Append(wx.ID_ANY,'&Grid on/off', 'Toggle grid lines') + item = popup.Append(wx.ID_ANY, '&Grid on/off', 'Toggle grid lines') wx.EVT_MENU(self, item.GetId(), - lambda _: (self.axes.grid(),self.fig.canvas.draw_idle())) - item = popup.Append(wx.ID_ANY,'&Rescale', 'Show entire profile') + lambda _: (self.axes.grid(), self.fig.canvas.draw_idle())) + item = popup.Append(wx.ID_ANY, '&Rescale', 'Show entire profile') wx.EVT_MENU(self, item.GetId(), - lambda _: (self.profile.reset_limits(),self.profile.draw_idle())) - self.PopupMenu(popup, (sx,sy)) + lambda _: (self.profile.reset_limits(), self.profile.draw_idle())) + submenu = wx.Menu() + item = submenu.Append(wx.ID_ANY, "&Insert Layer") + wx.EVT_MENU(self, item.GetId(), self.OnInsert) + item = submenu.Append(wx.ID_ANY, "&Remove Layer") + wx.EVT_MENU(self, item.GetId(), self.OnRemove) + item = submenu.Append(wx.ID_ANY, "&Edit Layer") + wx.EVT_MENU(self, item.GetId(), self.OnEdit) + popup.AppendMenu(wx.ID_ANY, "Layer", submenu) + item = popup.Append(wx.ID_ANY, "&Experiment") + wx.EVT_MENU(self, item.GetId(), self.OnExperiment) + self.PopupMenu(popup, (sx, sy)) return False + def OnInsert(self, event): + # Will not attempt to insert Layer + # before the current first layer + if self.profile.layer_num != 0: + ld = LayerDialog(self, profile=self.profile, insert=True) + ld.ShowModal() + else: + print "You cannot insert a layer before the first layer!" + signal.log_message("You cannot insert a layer before the first, current layer!") + + def OnRemove(self, event): + a = LayerDialog(self, profile=self.profile) + a.OnDelLayer(event) + + def OnEdit(self, event): + self.layerobject = self.profile.experiment.sample[self.profile.layer_num] + if type(self.layerobject) == Slab: #Only edit slabs + a = LayerDialog(self, + profile=self.profile, + material=self.layerobject.material, + thickness=self.layerobject.thickness, + interface=self.layerobject.interface, + insert=False) + else: + a = LayerDialog(self, profile=self.profile) + a.ShowModal() + + def OnExperiment(self, event): + self.experimentLayerObject = ExperimentDialog(experiment=self.profile.experiment, profile=self.profile) + if self.experimentLayerObject.ShowModal() == wx.ID_OK: + self.profile.signal_update() + def OnProfileSelect(self, event): self.set_profile(*self.profiles[event.GetInt()]) @@ -165,23 +211,23 @@ def _set_model(self): """Initialize model by profile.""" self.profiles = [] def add_profiles(name, exp, idx): - if isinstance(exp,MixedExperiment): - for i,p in enumerate(exp.parts): - self.profiles.append( (name+chr(ord("a")+i), p, idx) ) + if isinstance(exp, MixedExperiment): + for i, p in enumerate(exp.parts): + self.profiles.append((name + chr(ord("a") + i), p, idx)) else: - self.profiles.append( (name, exp, idx) ) - if isinstance(self.model,MultiFitProblem): - for i,p in enumerate(self.model.models): - if hasattr(p.fitness,"reflectivity"): + self.profiles.append((name, exp, idx)) + if isinstance(self.model, MultiFitProblem): + for i, p in enumerate(self.model.models): + if hasattr(p.fitness, "reflectivity"): name = p.fitness.name - if not name: name = "M%d"%(i+1) + if not name: name = "M%d" % (i + 1) add_profiles(name, p.fitness, i) else: add_profiles("", self.model.fitness, -1) self.profile_selector.Clear() if len(self.profiles) > 1: - self.profile_selector.AppendItems([k for k,_,_ in self.profiles]) + self.profile_selector.AppendItems([k for k, _, _ in self.profiles]) self.profile_selector_label.Show() self.profile_selector.Show() self.profile_selector.SetSelection(0) @@ -210,47 +256,47 @@ def signal_update(): signal.update_parameters(model=self.model) def force_recalc(): self.model.model_update() - if isinstance(self.model,MultiFitProblem): + if isinstance(self.model, MultiFitProblem): self.model.set_active_model(idx) self.profile.set_experiment(experiment, force_recalc=force_recalc, signal_update=signal_update) - def onPrinterSetup(self,event=None): + def onPrinterSetup(self, event=None): self.canvas.Printer_Setup(event=event) - def onPrinterPreview(self,event=None): + def onPrinterPreview(self, event=None): self.canvas.Printer_Preview(event=event) - def onPrint(self,event=None): + def onPrint(self, event=None): self.canvas.Printer_Print(event=event) - def OnSaveFigureMenu(self, evt ): + def OnSaveFigureMenu(self, evt): """ Save the current figure as an image file """ dlg = wx.FileDialog(self, - message="Save Figure As ...", - defaultDir=os.getcwd(), - defaultFile="", - wildcard="PNG files (*.png)|*.png|BMP files (*.bmp)|*.bmp|All files (*.*)|*.*", - style=wx.SAVE - ) + message="Save Figure As ...", + defaultDir=os.getcwd(), + defaultFile="", + wildcard="PNG files (*.png)|*.png|BMP files (*.bmp)|*.bmp|All files (*.*)|*.*", + style=wx.SAVE + ) _val = dlg.ShowModal() - if _val == wx.ID_CANCEL: return #Do nothing - if _val == wx.ID_OK: + if _val == wx.ID_CANCEL: return #Do nothing + if _val == wx.ID_OK: outfile = dlg.GetPath() dlg.Destroy() # Save - self.fig.savefig( outfile ) + self.fig.savefig(outfile) def GetToolBar(self): """ backend_wx call this function. KEEP it """ - return None + return self.toolbar def OnPanelFrameClose(self, evt): """ @@ -259,7 +305,7 @@ def OnPanelFrameClose(self, evt): self.Destroy() evt.Skip() - def OnCopyFigureMenu(self, evt ): + def OnCopyFigureMenu(self, evt): """ Copy the current figure """ @@ -272,3 +318,341 @@ def quit_on_error(self): numpy.seterr(all='raise') ProfileInteractor._debug = True BaseInteractor._debug = True + +##===============================Validator class===============================## +''' +ALPHA_ONLY = 1 +DIGIT_ONLY = 2 + +class MyValidator(wx.PyValidator): + def __init__(self, flag=None, pyVar=None): + wx.PyValidator.__init__(self) + self.flag = flag + self.Bind(wx.EVT_CHAR, self.OnChar) + + def Clone(self): + return MyValidator(self.flag) + + def Validate(self, win): + tc = self.GetWindow() + val = tc.GetValue() + + if self.flag == ALPHA_ONLY: + for x in val: + if x not in string.letters: + return False + + elif self.flag == DIGIT_ONLY: + for x in val: + if x not in string.digits: + return False + + return True + + + def OnChar(self, event): + key = event.GetKeyCode() + + if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255: + event.Skip() + return + + if self.flag == ALPHA_ONLY and chr(key) in string.letters: + event.Skip() + return + + if self.flag == DIGIT_ONLY and chr(key) in string.digits: + event.Skip() + return + + if not wx.Validator_IsSilent(): + wx.Bell() + + # Returning without calling even.Skip eats the event before it + # gets to the text control + return +''' +##===============================Validator class===============================## + + +class LayerDialog(wx.Dialog): + ''' + This is a class in which the user can enter, edit, and remove layers from the profile. + ''' + def __init__(self, + parent=None, + id=wx.ID_ANY, + title="Layer", + pos=wx.DefaultPosition, + size=wx.DefaultSize, + style=wx.DEFAULT_DIALOG_STYLE, + profile=None, + material=None, + thickness=0.0, + interface=0.0, + insert=False): # if this is true, the dialog will 'insert' on OK. If false, OK will cause an edit + wx.Dialog.__init__(self, parent, id, title, pos, size, style) + self.profile = profile + + if material != None: + materialName = material.name + try: + rho = material.rho.value + except AttributeError: + rho = 0. + try: + irho = material.irho.value + except AttributeError: + irho = 0. + try: + thickness = thickness.value + except AttributeError: + thickness = 0. + try: + interface = interface.value + except AtributeError: + interface = 0. + else: + materialName = "*name*" + rho = 0 + irho = 0 + thickness = 0 + interface = 0 + + # Sizers + self.wholeSizer = wx.BoxSizer(wx.VERTICAL) + self.contentSizer = wx.GridBagSizer(3, 4) + self.buttonSizer = wx.StdDialogButtonSizer() + + # Content + self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, "Name:"), (1, 0), (1, 1)) + self.materialName = wx.TextCtrl(self, -1, str(materialName)) + self.contentSizer.Add(self.materialName, (1, 1), (1, 1)) + self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, "rho:"), (2, 0), (1, 1)) + self.rho = wx.TextCtrl(self, -1, str(rho)) + self.contentSizer.Add(self.rho, (2, 1), (1, 1)) + self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, "irho:"), (3, 0), (1, 1)) + self.irho = wx.TextCtrl(self, -1, str(irho)) + self.contentSizer.Add(self.irho, (3, 1), (1, 1)) + self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, "Thickness:"), (1, 3), (1, 1)) + self.thickness = wx.TextCtrl(self, -1, str(thickness)) + self.contentSizer.Add(self.thickness, (1, 4), (1, 1)) + self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, "Interface:"), (2, 3), (1, 1)) + self.interface = wx.TextCtrl(self, -1, str(interface)) + self.contentSizer.Add(self.interface, (2, 4), (1, 1)) + + #Buttons + ok_btn = wx.Button(self, wx.ID_OK, "Ok") + ok_btn.SetDefault() + cancel_btn = wx.Button(self, wx.ID_CANCEL, "Cancel") + + #Bind: check to see whether or not this is a insert dialog or an edit dialog. + if insert: + self.Bind(wx.EVT_BUTTON, self.OnInsertLayer, ok_btn) + else: + self.Bind(wx.EVT_BUTTON, self.OnEditLayer, ok_btn) + + self.Bind(wx.EVT_BUTTON, self.OnCancel, cancel_btn) + + self.buttonSizer.AddButton(ok_btn) + self.buttonSizer.AddButton(cancel_btn) + self.buttonSizer.Realize() + + #Size it all in the wholeSizer + self.wholeSizer.Add(self.contentSizer, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL,5) + self.wholeSizer.Add(self.buttonSizer, 0, wx.ALIGN_BOTTOM|wx.ALIGN_RIGHT|wx.ALL, 5) + self.SetSizer(self.wholeSizer) + self.Fit() + + def __GetSlabObject(self): + # Strings values of the parameters + namestr = str(self.materialName.GetValue()) + rhoft = float(self.rho.GetValue()) + irhoft = float(self.irho.GetValue()) + thicknessft = float(self.thickness.GetValue()) + interfaceft = float(self.interface.GetValue()) + # make an SLD object + sldObject = SLD(name=namestr, rho=rhoft, irho=irhoft) + #make a slab object + slabObject = Slab(material=sldObject, + thickness=thicknessft, + interface=interfaceft, + name=None, + magnetism=None) + return slabObject + + # Events for the buttons + def OnDelLayer(self, event): #TODO debug: Sometimes you get an index out of bounds error + del self.profile.experiment.sample[self.profile.layer_num] + #if we are on the last layer, decrement layer_num + if self.profile.layer_num == len(self.profile.experiment.sample): + self.profile.layer_num -= 1 + self.ResetView() + + def OnInsertLayer(self, event): + slabObject = self.__GetSlabObject() + self.profile.experiment.sample.insert(self.profile.layer_num, slabObject) + self.ResetView() + self.Destroy() + + def OnCancel(self, event): + self.Destroy() + + def OnEditLayer(self, event): + slabObject = self.__GetSlabObject() + self.profile.experiment.sample[self.profile.layer_num] = slabObject + self.ResetView() + + def ResetView(self): + self.profile._find_layer_boundaries() + self.profile.thickness_interactor.reset_markers() + self.profile.update() + self.Destroy() + +''' +How to access paul's code for messing with layers: +examples: +slabObject = self.profile.experiment.sample[self.profile.layer_num] #__getitem__ +del self.profile.experiment.sample[self.profile.layer_num] #__delitem__ +self.profile.experiment.sample[self.profile.layer_num] = slabObject#__setitem__ +''' + +REFL_FILES = "Refl files (*.refl)|*.refl" + + +class ExperimentDialog(wx.Dialog): + def __init__(self, + parent=None, + id=wx.ID_ANY, + title="Experiment...", + pos=wx.DefaultPosition, + size=wx.DefaultSize, + style=wx.DEFAULT_DIALOG_STYLE, + experiment=None, + profile=None): + + # Defualt Values + self.experiment = experiment + self.profile = profile + roughness_limit = self.experiment.roughness_limit + dz = self.experiment.dz + dA = self.experiment.dA + step_interfaces = "Yes" if self.experiment.step_interfaces else "No" + currentFile = os.getcwd() + + # Create a dialog + wx.Dialog.__init__(self, parent, id, title, pos, size, style) + + #sizers + self.wholeSizer = wx.BoxSizer(wx.VERTICAL) + self.contentSizer = wx.GridBagSizer(4, 2) + self.buttonSizer = wx.StdDialogButtonSizer() + + self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " File Entry: "), (0, 0), (1, 1)) + self.fileText = wx.TextCtrl(self, wx.ID_ANY, currentFile, size=(299, -1)) + self.contentSizer.Add(self.fileText, (0, 1), (1, 1)) + open_btn = wx.Button(self, wx.ID_OPEN, "Open", size=(-1, -1)) + self.contentSizer.Add(open_btn, (0, 2), (1, 1)) + self.Bind(wx.EVT_BUTTON, self.OnExperimentOpen, open_btn) + + self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " Use Step Interface: "), (1, 0), (1, 1)) + self.step_interfaces = wx.ComboBox(self, wx.ID_ANY, value=step_interfaces, pos=wx.DefaultPosition, + size=wx.DefaultSize, + choices=['Yes', 'No'], style=wx.CB_DROPDOWN, name=wx.ComboBoxNameStr) + self.contentSizer.Add(self.step_interfaces, (1, 1), (1, 1)) + + self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " Roughness Limit: "), (2, 0), (1, 1)) + self.roughness_limit = wx.TextCtrl(self, -1, str(roughness_limit)) + self.contentSizer.Add(self.roughness_limit, (2, 1), (1, 1)) + + self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " dA: "), (3, 0), (1, 1)) + self.dA = wx.TextCtrl(self, -1, str(dA)) + self.contentSizer.Add(self.dA, (3, 1), (1, 1)) + + self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " dz: "), (4, 0), (1, 1)) + self.dz = wx.TextCtrl(self, -1, str(dz)) + self.contentSizer.Add(self.dz, (4, 1), (1, 1)) + + ok_btn = wx.Button(self, wx.ID_OK, "Ok") + ok_btn.SetDefault() + cancel_btn = wx.Button(self, wx.ID_CANCEL, "Cancel") + + #Binding + self.Bind(wx.EVT_BUTTON, self.OnOk, ok_btn) + self.Bind(wx.EVT_BUTTON, self.OnCancel, cancel_btn) + + self.buttonSizer.AddButton(ok_btn) + self.buttonSizer.AddButton(cancel_btn) + self.buttonSizer.Realize() + + #Size it all in the wholeSizer + self.wholeSizer.Add(self.contentSizer, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5) + self.wholeSizer.Add(self.buttonSizer, 0, wx.ALIGN_BOTTOM | wx.ALIGN_RIGHT | wx.ALL, 5) + self.SetSizer(self.wholeSizer) + self.Fit() + + def OnOk(self, event): + # Get the values from the user input + step_interfaces = (str(self.step_interfaces.GetValue()) == "Yes") + roughness_limit = float(self.roughness_limit.GetValue()) + dA = float(self.dA.GetValue()) + dz = float(self.dz.GetValue()) + + # Set the current experiment with the new values based on the users input + self.experiment.step_interfaces = step_interfaces + self.experiment.roughness_limit = roughness_limit + self.experiment.dA = dA + self.experiment.dz = dz + self.experiment.probe = self.probe + self.ResetView() + + ''' + if step_interfaces == True: + print "True" + # approximate the interface using microslabs with step size *dz* + else: + print "False" + # use the Nevot-Croce analytic expression for the interface between slabs. + ''' + + + def OnCancel(self, event): + self.Destroy() + + def OnExperimentOpen(self, evt): + dlg = wx.FileDialog(self, + message="Select File", + # defaultDir=os.getcwd(), + #defaultFile="", + wildcard=(REFL_FILES), + style=wx.OPEN | wx.CHANGE_DIR) + status = dlg.ShowModal() + path = dlg.GetPath() + + if status == wx.ID_OK: + # print 'FileBrowseButton: %s\n' % (path) + D = numpy.loadtxt(path) + Q = D[:, 0] + R = D[:, 1] + if D.shape[1] < 3: + dRoR = 1 + dR = R * dRoR / 100. + else: + dR = D[:, 2] + if D.shape[1] < 4: + dQoQ = 1 + dQ = Q * dQoQ / 100. + else: + dQ = D[:, 3] + from refl1d.probe import QProbe + self.probe = QProbe(Q, dQ, data=(R, dR)) + print type(self.fileText) + self.fileText.SetValue(path) + + dlg.Destroy() + + def ResetView(self): + self.profile._find_layer_boundaries() + self.profile.thickness_interactor.reset_markers() + self.profile.update() + self.Destroy() \ No newline at end of file diff --git a/refl1d/view/thickness.py b/refl1d/view/thickness.py index 0d42dbf1..c2943d01 100644 --- a/refl1d/view/thickness.py +++ b/refl1d/view/thickness.py @@ -36,8 +36,8 @@ def reset_markers(self): pickradius=pick_radius, visible=self._show_boundaries, ) - self.markers = [ax.axvline(x=z, **style) - for z in self.profile.boundary[1:-1]] + self.markers = [ax.axvline(x=z, zorder=i, **style) + for i, z in enumerate(self.profile.boundary[1:-1])] fittable = [self.profile.sample_layer(idx).thickness.fittable for idx,_ in enumerate(self.markers)] diff --git a/run.py b/run.py index 8345f5ce..6f8b3545 100755 --- a/run.py +++ b/run.py @@ -48,7 +48,7 @@ def prepare_environment(): from distutils.util import get_platform platform = '.%s-%s'%(get_platform(),sys.version[:3]) - sys.dont_write_bytecode = True + #sys.dont_write_bytecode = True # Make sure that we have a private version of mplconfig mplconfig = os.path.join(os.getcwd(), '.mplconfig') From e089f67f363d867e8adaa3dd0ab028dd9a28cb85 Mon Sep 17 00:00:00 2001 From: Yusuf Ameri cianaki Date: Fri, 18 Jul 2014 16:54:32 -0400 Subject: [PATCH 2/3] Added documentation --- refl1d/probe.py | 1 - refl1d/view/model_view.py | 111 +++++++++++++++++++++++++++++++------- 2 files changed, 93 insertions(+), 19 deletions(-) diff --git a/refl1d/probe.py b/refl1d/probe.py index 8ad8c6e0..de5dbd56 100644 --- a/refl1d/probe.py +++ b/refl1d/probe.py @@ -1045,7 +1045,6 @@ def __init__(self, Q, dQ, data=None, name=None, self.calc_Qo = self.Qo self.name = name - def measurement_union(xs): """ Determine the unique (T,dT,L,dL) across all datasets. diff --git a/refl1d/view/model_view.py b/refl1d/view/model_view.py index a7bc370f..7298bf9e 100644 --- a/refl1d/view/model_view.py +++ b/refl1d/view/model_view.py @@ -377,7 +377,7 @@ def OnChar(self, event): class LayerDialog(wx.Dialog): ''' - This is a class in which the user can enter, edit, and remove layers from the profile. + Creates a dialog in which the user can edit or insert a layer into the current stack. ''' def __init__(self, parent=None, @@ -465,6 +465,10 @@ def __init__(self, self.Fit() def __GetSlabObject(self): + """ + :returns the Slab Object that the should be edited or inserted into the layer. + + """ # Strings values of the parameters namestr = str(self.materialName.GetValue()) rhoft = float(self.rho.GetValue()) @@ -483,6 +487,12 @@ def __GetSlabObject(self): # Events for the buttons def OnDelLayer(self, event): #TODO debug: Sometimes you get an index out of bounds error + """ + Deletes the layer the user clicked on. + Cannot delete layer when there are only two inside of the stack. + :param event: + :return: + """ del self.profile.experiment.sample[self.profile.layer_num] #if we are on the last layer, decrement layer_num if self.profile.layer_num == len(self.profile.experiment.sample): @@ -490,20 +500,42 @@ def OnDelLayer(self, event): #TODO debug: Sometimes you get an index out of boun self.ResetView() def OnInsertLayer(self, event): + """ + Inserts a layer at the index before the mouse click in the stack. + Cannot insert a layer before the substrate (first layer) + :param event: + :return: + """ slabObject = self.__GetSlabObject() self.profile.experiment.sample.insert(self.profile.layer_num, slabObject) self.ResetView() self.Destroy() def OnCancel(self, event): + """ + Exit the Layer Dialog. + Dont do anything. + :param event: + :return: + """ self.Destroy() def OnEditLayer(self, event): + """ + Get the values of the current Slab object and place them into the parameters + :param event: + :return: + """ slabObject = self.__GetSlabObject() self.profile.experiment.sample[self.profile.layer_num] = slabObject self.ResetView() def ResetView(self): + """ + Reset the profile view so that changes take effect + immediately after an event (i.e. delete, insert, or edit layer) + :return: + """ self.profile._find_layer_boundaries() self.profile.thickness_interactor.reset_markers() self.profile.update() @@ -521,6 +553,12 @@ def ResetView(self): class ExperimentDialog(wx.Dialog): + """ + Create a Dialog for editing the current experiment and adding data. + The user can edit the roughness limit for layers, the dz, the dA, and enable/disable + step interfaces. + The user can also edit the dRoR and the dQoQ + """ def __init__(self, parent=None, id=wx.ID_ANY, @@ -530,7 +568,6 @@ def __init__(self, style=wx.DEFAULT_DIALOG_STYLE, experiment=None, profile=None): - # Defualt Values self.experiment = experiment self.profile = profile @@ -538,40 +575,56 @@ def __init__(self, dz = self.experiment.dz dA = self.experiment.dA step_interfaces = "Yes" if self.experiment.step_interfaces else "No" - currentFile = os.getcwd() + try: + dRoR = self.experiment.probe.dRoR + except AttributeError: + dRoR = 0. + try: + dQoQ = self.experiment.probe.dQoQ + except AttributeError: + dQoQ = 0. + self.currentFile = os.getcwd() # Create a dialog wx.Dialog.__init__(self, parent, id, title, pos, size, style) #sizers self.wholeSizer = wx.BoxSizer(wx.VERTICAL) - self.contentSizer = wx.GridBagSizer(4, 2) + self.contentSizer = wx.GridBagSizer(6, 2) self.buttonSizer = wx.StdDialogButtonSizer() self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " File Entry: "), (0, 0), (1, 1)) - self.fileText = wx.TextCtrl(self, wx.ID_ANY, currentFile, size=(299, -1)) + self.fileText = wx.TextCtrl(self, wx.ID_ANY, self.currentFile, size=(299, -1)) self.contentSizer.Add(self.fileText, (0, 1), (1, 1)) open_btn = wx.Button(self, wx.ID_OPEN, "Open", size=(-1, -1)) self.contentSizer.Add(open_btn, (0, 2), (1, 1)) self.Bind(wx.EVT_BUTTON, self.OnExperimentOpen, open_btn) - self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " Use Step Interface: "), (1, 0), (1, 1)) + self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " dRoR: "), (1, 0), (1, 1)) + self.dRoR = wx.TextCtrl(self, -1, str(dRoR)) + self.contentSizer.Add(self.dRoR, (1, 1), (1, 1)) + + self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " dQoQ: "), (2, 0), (1, 1)) + self.dQoQ = wx.TextCtrl(self, -1, str(dQoQ)) + self.contentSizer.Add(self.dQoQ, (2, 1), (1, 1)) + + self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " Use Step Interface: "), (3, 0), (1, 1)) self.step_interfaces = wx.ComboBox(self, wx.ID_ANY, value=step_interfaces, pos=wx.DefaultPosition, size=wx.DefaultSize, choices=['Yes', 'No'], style=wx.CB_DROPDOWN, name=wx.ComboBoxNameStr) - self.contentSizer.Add(self.step_interfaces, (1, 1), (1, 1)) + self.contentSizer.Add(self.step_interfaces, (3, 1), (1, 1)) - self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " Roughness Limit: "), (2, 0), (1, 1)) + self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " Roughness Limit: "), (4, 0), (1, 1)) self.roughness_limit = wx.TextCtrl(self, -1, str(roughness_limit)) - self.contentSizer.Add(self.roughness_limit, (2, 1), (1, 1)) + self.contentSizer.Add(self.roughness_limit, (4, 1), (1, 1)) - self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " dA: "), (3, 0), (1, 1)) + self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " dA: "), (5, 0), (1, 1)) self.dA = wx.TextCtrl(self, -1, str(dA)) - self.contentSizer.Add(self.dA, (3, 1), (1, 1)) + self.contentSizer.Add(self.dA, (5, 1), (1, 1)) - self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " dz: "), (4, 0), (1, 1)) + self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " dz: "), (6, 0), (1, 1)) self.dz = wx.TextCtrl(self, -1, str(dz)) - self.contentSizer.Add(self.dz, (4, 1), (1, 1)) + self.contentSizer.Add(self.dz, (6, 1), (1, 1)) ok_btn = wx.Button(self, wx.ID_OK, "Ok") ok_btn.SetDefault() @@ -592,6 +645,11 @@ def __init__(self, self.Fit() def OnOk(self, event): + """ + Get user changes (input) and reset the experiment to accomodate the changes. + :param event: + :return: + """ # Get the values from the user input step_interfaces = (str(self.step_interfaces.GetValue()) == "Yes") roughness_limit = float(self.roughness_limit.GetValue()) @@ -603,7 +661,8 @@ def OnOk(self, event): self.experiment.roughness_limit = roughness_limit self.experiment.dA = dA self.experiment.dz = dz - self.experiment.probe = self.probe + if self.currentFile != os.getcwd(): + self.experiment.probe = self.probe self.ResetView() ''' @@ -617,9 +676,20 @@ def OnOk(self, event): def OnCancel(self, event): + """ + Exit the Layer Dialog. + Dont do anything. + :param event: + :return: + """ self.Destroy() def OnExperimentOpen(self, evt): + """ + Open a FileDialog and load data to be processed in the experiment. + :param evt: + :return: + """ dlg = wx.FileDialog(self, message="Select File", # defaultDir=os.getcwd(), @@ -635,13 +705,13 @@ def OnExperimentOpen(self, evt): Q = D[:, 0] R = D[:, 1] if D.shape[1] < 3: - dRoR = 1 - dR = R * dRoR / 100. + self.dRoR = float(self.dRoR.GetValue()) + dR = R * self.dRoR / 100. else: dR = D[:, 2] if D.shape[1] < 4: - dQoQ = 1 - dQ = Q * dQoQ / 100. + self.dQoQ = float(self.dQoQ.GetValue()) + dQ = Q * self.dQoQ / 100. else: dQ = D[:, 3] from refl1d.probe import QProbe @@ -652,6 +722,11 @@ def OnExperimentOpen(self, evt): dlg.Destroy() def ResetView(self): + """ + Reset the profile view so that changes take effect + immediately after an event (i.e. delete, insert, or edit layer) + :return: + """ self.profile._find_layer_boundaries() self.profile.thickness_interactor.reset_markers() self.profile.update() From 76c68f2a670ef4f1040e8325292d9fa19266357a Mon Sep 17 00:00:00 2001 From: Yusuf Ameri cianaki Date: Fri, 8 Aug 2014 16:15:54 -0400 Subject: [PATCH 3/3] Added a Layer and Experiment Dialog --- doc/_examples/step/tethered.py | 1 + refl1d/model.py | 3 +- refl1d/probe.py | 1 + refl1d/view/model_view.py | 238 +++++++++++---------------------- setup.py | 4 +- 5 files changed, 84 insertions(+), 163 deletions(-) diff --git a/doc/_examples/step/tethered.py b/doc/_examples/step/tethered.py index 409924d6..38d64e25 100644 --- a/doc/_examples/step/tethered.py +++ b/doc/_examples/step/tethered.py @@ -35,6 +35,7 @@ S2 = Experiment(sample=sample, probe=probe, dz=1, dA=10, step_interfaces=True, name="dz=1; dA=10; step interfaces") + models=[M0,M1,M2,S0,S1,S2] #models=[S1] problem = MultiFitProblem(models=models) diff --git a/refl1d/model.py b/refl1d/model.py index 3e4ac5bc..c0f0f60a 100644 --- a/refl1d/model.py +++ b/refl1d/model.py @@ -460,8 +460,7 @@ def __delitem__(self, idx): if(len(stack)>2 and (idx>=0 and idx < len(stack))): del stack._layers[idx] else: - import logging;logging.error("You cannot remove this layer. You need at least 2 layers!") - signal.log_message("You cannot remove this layer. You need at least 2 layers!") + raise ValueError("You cannot remove this layer. You need at least 2 layers!") def insert(self, idx, other): diff --git a/refl1d/probe.py b/refl1d/probe.py index de5dbd56..04e4d8dd 100644 --- a/refl1d/probe.py +++ b/refl1d/probe.py @@ -1174,6 +1174,7 @@ def oversample(self, n=6, seed=1): T = T.flatten() L = L.flatten() self._set_calc(T,L) + oversample.__doc__ = Probe.oversample.__doc__ @property diff --git a/refl1d/view/model_view.py b/refl1d/view/model_view.py index 7298bf9e..857ce597 100644 --- a/refl1d/view/model_view.py +++ b/refl1d/view/model_view.py @@ -114,27 +114,24 @@ def OnContextMenu(self, event): item = popup.Append(wx.ID_ANY, '&Rescale', 'Show entire profile') wx.EVT_MENU(self, item.GetId(), lambda _: (self.profile.reset_limits(), self.profile.draw_idle())) - submenu = wx.Menu() - item = submenu.Append(wx.ID_ANY, "&Insert Layer") + + item = popup.Append(wx.ID_ANY, "&Insert Layer") wx.EVT_MENU(self, item.GetId(), self.OnInsert) - item = submenu.Append(wx.ID_ANY, "&Remove Layer") + item = popup.Append(wx.ID_ANY, "&Remove Layer") wx.EVT_MENU(self, item.GetId(), self.OnRemove) - item = submenu.Append(wx.ID_ANY, "&Edit Layer") + item = popup.Append(wx.ID_ANY, "&Edit Layer") wx.EVT_MENU(self, item.GetId(), self.OnEdit) - popup.AppendMenu(wx.ID_ANY, "Layer", submenu) item = popup.Append(wx.ID_ANY, "&Experiment") wx.EVT_MENU(self, item.GetId(), self.OnExperiment) self.PopupMenu(popup, (sx, sy)) return False def OnInsert(self, event): - # Will not attempt to insert Layer - # before the current first layer + # Will not attempt to insert Layer before the current first layer if self.profile.layer_num != 0: - ld = LayerDialog(self, profile=self.profile, insert=True) - ld.ShowModal() + a = LayerDialog(self, profile=self.profile, insert=True) + a.ShowModal() else: - print "You cannot insert a layer before the first layer!" signal.log_message("You cannot insert a layer before the first, current layer!") def OnRemove(self, event): @@ -150,6 +147,8 @@ def OnEdit(self, event): thickness=self.layerobject.thickness, interface=self.layerobject.interface, insert=False) + elif type(self,layerobject) == 1: + print else: a = LayerDialog(self, profile=self.profile) a.ShowModal() @@ -286,7 +285,6 @@ def OnSaveFigureMenu(self, evt): if _val == wx.ID_CANCEL: return #Do nothing if _val == wx.ID_OK: outfile = dlg.GetPath() - dlg.Destroy() # Save @@ -319,60 +317,9 @@ def quit_on_error(self): ProfileInteractor._debug = True BaseInteractor._debug = True -##===============================Validator class===============================## -''' -ALPHA_ONLY = 1 -DIGIT_ONLY = 2 - -class MyValidator(wx.PyValidator): - def __init__(self, flag=None, pyVar=None): - wx.PyValidator.__init__(self) - self.flag = flag - self.Bind(wx.EVT_CHAR, self.OnChar) - - def Clone(self): - return MyValidator(self.flag) - - def Validate(self, win): - tc = self.GetWindow() - val = tc.GetValue() - - if self.flag == ALPHA_ONLY: - for x in val: - if x not in string.letters: - return False - - elif self.flag == DIGIT_ONLY: - for x in val: - if x not in string.digits: - return False - - return True - - - def OnChar(self, event): - key = event.GetKeyCode() - - if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255: - event.Skip() - return - - if self.flag == ALPHA_ONLY and chr(key) in string.letters: - event.Skip() - return - - if self.flag == DIGIT_ONLY and chr(key) in string.digits: - event.Skip() - return - - if not wx.Validator_IsSilent(): - wx.Bell() - - # Returning without calling even.Skip eats the event before it - # gets to the text control - return -''' -##===============================Validator class===============================## +##===============================Validator class========================================### +#TODO: Add a validator to make sure that the user does not input unexpected/illegal values# +##===============================Validator class========================================### class LayerDialog(wx.Dialog): @@ -388,14 +335,14 @@ def __init__(self, style=wx.DEFAULT_DIALOG_STYLE, profile=None, material=None, - thickness=0.0, + thickness=10.0, interface=0.0, insert=False): # if this is true, the dialog will 'insert' on OK. If false, OK will cause an edit wx.Dialog.__init__(self, parent, id, title, pos, size, style) self.profile = profile if material != None: - materialName = material.name + material_name = material.name try: rho = material.rho.value except AttributeError: @@ -413,33 +360,33 @@ def __init__(self, except AtributeError: interface = 0. else: - materialName = "*name*" - rho = 0 - irho = 0 - thickness = 0 - interface = 0 + material_name = "Default Name" + rho = 0.0 + irho = 0.0 + thickness = 10.0 + interface = 0.0 # Sizers - self.wholeSizer = wx.BoxSizer(wx.VERTICAL) - self.contentSizer = wx.GridBagSizer(3, 4) - self.buttonSizer = wx.StdDialogButtonSizer() + whole_sizer = wx.BoxSizer(wx.VERTICAL) + content_sizer = wx.GridBagSizer(3, 4) + button_sizer = wx.StdDialogButtonSizer() # Content - self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, "Name:"), (1, 0), (1, 1)) - self.materialName = wx.TextCtrl(self, -1, str(materialName)) - self.contentSizer.Add(self.materialName, (1, 1), (1, 1)) - self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, "rho:"), (2, 0), (1, 1)) + content_sizer.Add(wx.StaticText(self, wx.ID_ANY, "Material Name:"), (1, 0), (1, 1)) + self.material_name = wx.TextCtrl(self, -1, str(material_name)) + content_sizer.Add(self.material_name, (1, 1), (1, 1)) + content_sizer.Add(wx.StaticText(self, wx.ID_ANY, "rho:"), (2, 0), (1, 1)) self.rho = wx.TextCtrl(self, -1, str(rho)) - self.contentSizer.Add(self.rho, (2, 1), (1, 1)) - self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, "irho:"), (3, 0), (1, 1)) + content_sizer.Add(self.rho, (2, 1), (1, 1)) + content_sizer.Add(wx.StaticText(self, wx.ID_ANY, "irho:"), (3, 0), (1, 1)) self.irho = wx.TextCtrl(self, -1, str(irho)) - self.contentSizer.Add(self.irho, (3, 1), (1, 1)) - self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, "Thickness:"), (1, 3), (1, 1)) + content_sizer.Add(self.irho, (3, 1), (1, 1)) + content_sizer.Add(wx.StaticText(self, wx.ID_ANY, "Thickness:"), (1, 3), (1, 1)) self.thickness = wx.TextCtrl(self, -1, str(thickness)) - self.contentSizer.Add(self.thickness, (1, 4), (1, 1)) - self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, "Interface:"), (2, 3), (1, 1)) + content_sizer.Add(self.thickness, (1, 4), (1, 1)) + content_sizer.Add(wx.StaticText(self, wx.ID_ANY, "Interface:"), (2, 3), (1, 1)) self.interface = wx.TextCtrl(self, -1, str(interface)) - self.contentSizer.Add(self.interface, (2, 4), (1, 1)) + content_sizer.Add(self.interface, (2, 4), (1, 1)) #Buttons ok_btn = wx.Button(self, wx.ID_OK, "Ok") @@ -454,23 +401,22 @@ def __init__(self, self.Bind(wx.EVT_BUTTON, self.OnCancel, cancel_btn) - self.buttonSizer.AddButton(ok_btn) - self.buttonSizer.AddButton(cancel_btn) - self.buttonSizer.Realize() + button_sizer.AddButton(ok_btn) + button_sizer.AddButton(cancel_btn) + button_sizer.Realize() - #Size it all in the wholeSizer - self.wholeSizer.Add(self.contentSizer, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL,5) - self.wholeSizer.Add(self.buttonSizer, 0, wx.ALIGN_BOTTOM|wx.ALIGN_RIGHT|wx.ALL, 5) - self.SetSizer(self.wholeSizer) + #Size it all in the whole_sizer + whole_sizer.Add(content_sizer, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL,5) + whole_sizer.Add(button_sizer, 0, wx.ALIGN_BOTTOM|wx.ALIGN_RIGHT|wx.ALL, 5) + self.SetSizer(whole_sizer) self.Fit() def __GetSlabObject(self): """ :returns the Slab Object that the should be edited or inserted into the layer. - """ # Strings values of the parameters - namestr = str(self.materialName.GetValue()) + namestr = str(self.material_name.GetValue()) rhoft = float(self.rho.GetValue()) irhoft = float(self.irho.GetValue()) thicknessft = float(self.thickness.GetValue()) @@ -485,13 +431,16 @@ def __GetSlabObject(self): magnetism=None) return slabObject + def __GetMagneticObject(self): + """ + :return: the magnetic Object that should be edited or inserted into the layer + """ + # Events for the buttons def OnDelLayer(self, event): #TODO debug: Sometimes you get an index out of bounds error """ Deletes the layer the user clicked on. Cannot delete layer when there are only two inside of the stack. - :param event: - :return: """ del self.profile.experiment.sample[self.profile.layer_num] #if we are on the last layer, decrement layer_num @@ -503,8 +452,6 @@ def OnInsertLayer(self, event): """ Inserts a layer at the index before the mouse click in the stack. Cannot insert a layer before the substrate (first layer) - :param event: - :return: """ slabObject = self.__GetSlabObject() self.profile.experiment.sample.insert(self.profile.layer_num, slabObject) @@ -515,16 +462,12 @@ def OnCancel(self, event): """ Exit the Layer Dialog. Dont do anything. - :param event: - :return: """ self.Destroy() def OnEditLayer(self, event): """ Get the values of the current Slab object and place them into the parameters - :param event: - :return: """ slabObject = self.__GetSlabObject() self.profile.experiment.sample[self.profile.layer_num] = slabObject @@ -534,27 +477,19 @@ def ResetView(self): """ Reset the profile view so that changes take effect immediately after an event (i.e. delete, insert, or edit layer) - :return: """ self.profile._find_layer_boundaries() self.profile.thickness_interactor.reset_markers() self.profile.update() self.Destroy() -''' -How to access paul's code for messing with layers: -examples: -slabObject = self.profile.experiment.sample[self.profile.layer_num] #__getitem__ -del self.profile.experiment.sample[self.profile.layer_num] #__delitem__ -self.profile.experiment.sample[self.profile.layer_num] = slabObject#__setitem__ -''' REFL_FILES = "Refl files (*.refl)|*.refl" class ExperimentDialog(wx.Dialog): """ - Create a Dialog for editing the current experiment and adding data. + Create a Dialog for editing the current experiment and adding data. The user can edit the roughness limit for layers, the dz, the dA, and enable/disable step interfaces. The user can also edit the dRoR and the dQoQ @@ -573,7 +508,8 @@ def __init__(self, self.profile = profile roughness_limit = self.experiment.roughness_limit dz = self.experiment.dz - dA = self.experiment.dA + dA = 0 if self.experiment.dA == None else self.experiment.dA + step_interfaces = "Yes" if self.experiment.step_interfaces else "No" try: dRoR = self.experiment.probe.dRoR @@ -583,48 +519,48 @@ def __init__(self, dQoQ = self.experiment.probe.dQoQ except AttributeError: dQoQ = 0. - self.currentFile = os.getcwd() + self.current_file = os.getcwd() # Create a dialog wx.Dialog.__init__(self, parent, id, title, pos, size, style) #sizers - self.wholeSizer = wx.BoxSizer(wx.VERTICAL) - self.contentSizer = wx.GridBagSizer(6, 2) - self.buttonSizer = wx.StdDialogButtonSizer() + whole_sizer = wx.BoxSizer(wx.VERTICAL) + content_sizer = wx.GridBagSizer(6, 2) + button_sizer = wx.StdDialogButtonSizer() - self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " File Entry: "), (0, 0), (1, 1)) - self.fileText = wx.TextCtrl(self, wx.ID_ANY, self.currentFile, size=(299, -1)) - self.contentSizer.Add(self.fileText, (0, 1), (1, 1)) + content_sizer.Add(wx.StaticText(self, wx.ID_ANY, " File Entry: "), (0, 0), (1, 1)) + self.file_text = wx.TextCtrl(self, wx.ID_ANY, self.current_file, size=(299, -1)) + content_sizer.Add(self.file_text, (0, 1), (1, 1)) open_btn = wx.Button(self, wx.ID_OPEN, "Open", size=(-1, -1)) - self.contentSizer.Add(open_btn, (0, 2), (1, 1)) + content_sizer.Add(open_btn, (0, 2), (1, 1)) self.Bind(wx.EVT_BUTTON, self.OnExperimentOpen, open_btn) - self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " dRoR: "), (1, 0), (1, 1)) + content_sizer.Add(wx.StaticText(self, wx.ID_ANY, " dRoR: "), (1, 0), (1, 1)) self.dRoR = wx.TextCtrl(self, -1, str(dRoR)) - self.contentSizer.Add(self.dRoR, (1, 1), (1, 1)) + content_sizer.Add(self.dRoR, (1, 1), (1, 1)) - self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " dQoQ: "), (2, 0), (1, 1)) + content_sizer.Add(wx.StaticText(self, wx.ID_ANY, " dQoQ: "), (2, 0), (1, 1)) self.dQoQ = wx.TextCtrl(self, -1, str(dQoQ)) - self.contentSizer.Add(self.dQoQ, (2, 1), (1, 1)) + content_sizer.Add(self.dQoQ, (2, 1), (1, 1)) - self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " Use Step Interface: "), (3, 0), (1, 1)) + content_sizer.Add(wx.StaticText(self, wx.ID_ANY, " Use Step Interface: "), (3, 0), (1, 1)) self.step_interfaces = wx.ComboBox(self, wx.ID_ANY, value=step_interfaces, pos=wx.DefaultPosition, size=wx.DefaultSize, choices=['Yes', 'No'], style=wx.CB_DROPDOWN, name=wx.ComboBoxNameStr) - self.contentSizer.Add(self.step_interfaces, (3, 1), (1, 1)) + content_sizer.Add(self.step_interfaces, (3, 1), (1, 1)) - self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " Roughness Limit: "), (4, 0), (1, 1)) + content_sizer.Add(wx.StaticText(self, wx.ID_ANY, " Roughness Limit: "), (4, 0), (1, 1)) self.roughness_limit = wx.TextCtrl(self, -1, str(roughness_limit)) - self.contentSizer.Add(self.roughness_limit, (4, 1), (1, 1)) + content_sizer.Add(self.roughness_limit, (4, 1), (1, 1)) - self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " dA: "), (5, 0), (1, 1)) + content_sizer.Add(wx.StaticText(self, wx.ID_ANY, " dA: "), (5, 0), (1, 1)) self.dA = wx.TextCtrl(self, -1, str(dA)) - self.contentSizer.Add(self.dA, (5, 1), (1, 1)) + content_sizer.Add(self.dA, (5, 1), (1, 1)) - self.contentSizer.Add(wx.StaticText(self, wx.ID_ANY, " dz: "), (6, 0), (1, 1)) + content_sizer.Add(wx.StaticText(self, wx.ID_ANY, " dz: "), (6, 0), (1, 1)) self.dz = wx.TextCtrl(self, -1, str(dz)) - self.contentSizer.Add(self.dz, (6, 1), (1, 1)) + content_sizer.Add(self.dz, (6, 1), (1, 1)) ok_btn = wx.Button(self, wx.ID_OK, "Ok") ok_btn.SetDefault() @@ -634,14 +570,14 @@ def __init__(self, self.Bind(wx.EVT_BUTTON, self.OnOk, ok_btn) self.Bind(wx.EVT_BUTTON, self.OnCancel, cancel_btn) - self.buttonSizer.AddButton(ok_btn) - self.buttonSizer.AddButton(cancel_btn) - self.buttonSizer.Realize() + button_sizer.AddButton(ok_btn) + button_sizer.AddButton(cancel_btn) + button_sizer.Realize() - #Size it all in the wholeSizer - self.wholeSizer.Add(self.contentSizer, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5) - self.wholeSizer.Add(self.buttonSizer, 0, wx.ALIGN_BOTTOM | wx.ALIGN_RIGHT | wx.ALL, 5) - self.SetSizer(self.wholeSizer) + #Size it all in the whole_sizer + whole_sizer.Add(content_sizer, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5) + whole_sizer.Add(button_sizer, 0, wx.ALIGN_BOTTOM | wx.ALIGN_RIGHT | wx.ALL, 5) + self.SetSizer(whole_sizer) self.Fit() def OnOk(self, event): @@ -661,34 +597,20 @@ def OnOk(self, event): self.experiment.roughness_limit = roughness_limit self.experiment.dA = dA self.experiment.dz = dz - if self.currentFile != os.getcwd(): + if self.current_file != os.getcwd(): self.experiment.probe = self.probe self.ResetView() - ''' - if step_interfaces == True: - print "True" - # approximate the interface using microslabs with step size *dz* - else: - print "False" - # use the Nevot-Croce analytic expression for the interface between slabs. - ''' - - def OnCancel(self, event): """ Exit the Layer Dialog. Dont do anything. - :param event: - :return: """ self.Destroy() def OnExperimentOpen(self, evt): """ Open a FileDialog and load data to be processed in the experiment. - :param evt: - :return: """ dlg = wx.FileDialog(self, message="Select File", @@ -716,16 +638,14 @@ def OnExperimentOpen(self, evt): dQ = D[:, 3] from refl1d.probe import QProbe self.probe = QProbe(Q, dQ, data=(R, dR)) - print type(self.fileText) - self.fileText.SetValue(path) - + print type(self.file_text) + self.file_text.SetValue(path) dlg.Destroy() def ResetView(self): """ Reset the profile view so that changes take effect immediately after an event (i.e. delete, insert, or edit layer) - :return: """ self.profile._find_layer_boundaries() self.profile.thickness_interactor.reset_markers() diff --git a/setup.py b/setup.py index 41c908cc..ff31440a 100755 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ from os.path import dirname, abspath, join as joinpath bumps_path = joinpath(dirname(dirname(abspath(__file__))),'bumps') sys.path.insert(0, bumps_path) -from bumps.openmp_ext import openmp_ext +#from bumps.openmp_ext import openmp_ext import refl1d @@ -66,7 +66,7 @@ def reflmodule_config(): scripts = ['bin/refl1d_cli.py','bin/refl1d_gui.py'], ext_modules = [reflmodule_config()], requires = [], # ['bumps>=0.9'], - cmdclass = {'build_ext': openmp_ext(default=False)}, + #cmdclass = {'build_ext': openmp_ext(default=False)}, ) # End of file