source: sasview/src/sas/qtgui/GuiUtils.py @ fed94a2

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since fed94a2 was fed94a2, checked in by Piotr Rozyczko <rozyczko@…>, 7 years ago

Improved label formatting in charts

  • Property mode set to 100644
File size: 23.7 KB
Line 
1"""
2Global defaults and various utility functions usable by the general GUI
3"""
4
5import os
6import sys
7import imp
8import warnings
9import webbrowser
10import urlparse
11import numpy
12
13warnings.simplefilter("ignore")
14import logging
15
16from PyQt4 import QtCore
17from PyQt4 import QtGui
18
19# Translate event handlers
20#from sas.sasgui.guiframe.events import EVT_CATEGORY
21#from sas.sasgui.guiframe.events import EVT_STATUS
22#from sas.sasgui.guiframe.events import EVT_APPEND_BOOKMARK
23#from sas.sasgui.guiframe.events import EVT_PANEL_ON_FOCUS
24#from sas.sasgui.guiframe.events import EVT_NEW_LOAD_DATA
25#from sas.sasgui.guiframe.events import EVT_NEW_COLOR
26#from sas.sasgui.guiframe.events import StatusEvent
27#from sas.sasgui.guiframe.events import NewPlotEvent
28
29from periodictable import formula as Formula
30
31from sas.sasgui.plottools import transform
32from sas.sasgui.plottools.convert_units import convert_unit
33from sas.sasgui.guiframe.dataFitting import Data1D
34from sas.sasgui.guiframe.dataFitting import Data2D
35from sas.sascalc.dataloader.loader import Loader
36
37
38def get_app_dir():
39    """
40        The application directory is the one where the default custom_config.py
41        file resides.
42
43        :returns: app_path - the path to the applicatin directory
44    """
45    # First, try the directory of the executable we are running
46    app_path = sys.path[0]
47    if os.path.isfile(app_path):
48        app_path = os.path.dirname(app_path)
49    if os.path.isfile(os.path.join(app_path, "custom_config.py")):
50        app_path = os.path.abspath(app_path)
51        #logging.info("Using application path: %s", app_path)
52        return app_path
53
54    # Next, try the current working directory
55    if os.path.isfile(os.path.join(os.getcwd(), "custom_config.py")):
56        #logging.info("Using application path: %s", os.getcwd())
57        return os.path.abspath(os.getcwd())
58
59    # Finally, try the directory of the sasview module
60    # TODO: gui_manager will have to know about sasview until we
61    # clean all these module variables and put them into a config class
62    # that can be passed by sasview.py.
63    #logging.info(sys.executable)
64    #logging.info(str(sys.argv))
65    from sas import sasview as sasview
66    app_path = os.path.dirname(sasview.__file__)
67    #logging.info("Using application path: %s", app_path)
68    return app_path
69
70def get_user_directory():
71    """
72        Returns the user's home directory
73    """
74    userdir = os.path.join(os.path.expanduser("~"), ".sasview")
75    if not os.path.isdir(userdir):
76        os.makedirs(userdir)
77    return userdir
78
79def _find_local_config(confg_file, path):
80    """
81        Find configuration file for the current application
82    """
83    config_module = None
84    fObj = None
85    try:
86        fObj, path_config, descr = imp.find_module(confg_file, [path])
87        config_module = imp.load_module(confg_file, fObj, path_config, descr)
88    except ImportError:
89        pass
90        #logging.error("Error loading %s/%s: %s" % (path, confg_file, sys.exc_value))
91    finally:
92        if fObj is not None:
93            fObj.close()
94    #logging.info("GuiManager loaded %s/%s" % (path, confg_file))
95    return config_module
96
97# Get APP folder
98PATH_APP = get_app_dir()
99DATAPATH = PATH_APP
100
101# GUI always starts from the App folder
102#os.chdir(PATH_APP)
103# Read in the local config, which can either be with the main
104# application or in the installation directory
105config = _find_local_config('local_config', PATH_APP)
106
107if config is None:
108    config = _find_local_config('local_config', os.getcwd())
109    if config is None:
110        # Didn't find local config, load the default
111        import sas.sasgui.guiframe.config as config
112        #logging.info("using default local_config")
113    else:
114        pass
115        #logging.info("found local_config in %s", os.getcwd())
116else:
117    pass
118    #logging.info("found local_config in %s", PATH_APP)
119
120
121from sas.sasgui.guiframe.customdir  import SetupCustom
122c_conf_dir = SetupCustom().setup_dir(PATH_APP)
123custom_config = _find_local_config('custom_config', c_conf_dir)
124if custom_config is None:
125    custom_config = _find_local_config('custom_config', os.getcwd())
126    if custom_config is None:
127        msgConfig = "Custom_config file was not imported"
128        #logging.info(msgConfig)
129    else:
130        pass
131        #logging.info("using custom_config in %s", os.getcwd())
132else:
133    pass
134    #logging.info("using custom_config from %s", c_conf_dir)
135
136#read some constants from config
137APPLICATION_STATE_EXTENSION = config.APPLICATION_STATE_EXTENSION
138APPLICATION_NAME = config.__appname__
139SPLASH_SCREEN_PATH = config.SPLASH_SCREEN_PATH
140WELCOME_PANEL_ON = config.WELCOME_PANEL_ON
141SPLASH_SCREEN_WIDTH = config.SPLASH_SCREEN_WIDTH
142SPLASH_SCREEN_HEIGHT = config.SPLASH_SCREEN_HEIGHT
143SS_MAX_DISPLAY_TIME = config.SS_MAX_DISPLAY_TIME
144if not WELCOME_PANEL_ON:
145    WELCOME_PANEL_SHOW = False
146else:
147    WELCOME_PANEL_SHOW = True
148try:
149    DATALOADER_SHOW = custom_config.DATALOADER_SHOW
150    TOOLBAR_SHOW = custom_config.TOOLBAR_SHOW
151    FIXED_PANEL = custom_config.FIXED_PANEL
152    if WELCOME_PANEL_ON:
153        WELCOME_PANEL_SHOW = custom_config.WELCOME_PANEL_SHOW
154    PLOPANEL_WIDTH = custom_config.PLOPANEL_WIDTH
155    DATAPANEL_WIDTH = custom_config.DATAPANEL_WIDTH
156    GUIFRAME_WIDTH = custom_config.GUIFRAME_WIDTH
157    GUIFRAME_HEIGHT = custom_config.GUIFRAME_HEIGHT
158    CONTROL_WIDTH = custom_config.CONTROL_WIDTH
159    CONTROL_HEIGHT = custom_config.CONTROL_HEIGHT
160    DEFAULT_PERSPECTIVE = custom_config.DEFAULT_PERSPECTIVE
161    CLEANUP_PLOT = custom_config.CLEANUP_PLOT
162    # custom open_path
163    open_folder = custom_config.DEFAULT_OPEN_FOLDER
164    if open_folder != None and os.path.isdir(open_folder):
165        DEFAULT_OPEN_FOLDER = os.path.abspath(open_folder)
166    else:
167        DEFAULT_OPEN_FOLDER = PATH_APP
168except AttributeError:
169    DATALOADER_SHOW = True
170    TOOLBAR_SHOW = True
171    FIXED_PANEL = True
172    WELCOME_PANEL_SHOW = False
173    PLOPANEL_WIDTH = config.PLOPANEL_WIDTH
174    DATAPANEL_WIDTH = config.DATAPANEL_WIDTH
175    GUIFRAME_WIDTH = config.GUIFRAME_WIDTH
176    GUIFRAME_HEIGHT = config.GUIFRAME_HEIGHT
177    CONTROL_WIDTH = -1
178    CONTROL_HEIGHT = -1
179    DEFAULT_PERSPECTIVE = None
180    CLEANUP_PLOT = False
181    DEFAULT_OPEN_FOLDER = PATH_APP
182
183DEFAULT_STYLE = config.DEFAULT_STYLE
184
185PLUGIN_STATE_EXTENSIONS = config.PLUGIN_STATE_EXTENSIONS
186OPEN_SAVE_MENU = config.OPEN_SAVE_PROJECT_MENU
187VIEW_MENU = config.VIEW_MENU
188EDIT_MENU = config.EDIT_MENU
189extension_list = []
190if APPLICATION_STATE_EXTENSION is not None:
191    extension_list.append(APPLICATION_STATE_EXTENSION)
192EXTENSIONS = PLUGIN_STATE_EXTENSIONS + extension_list
193try:
194    PLUGINS_WLIST = '|'.join(config.PLUGINS_WLIST)
195except AttributeError:
196    PLUGINS_WLIST = ''
197APPLICATION_WLIST = config.APPLICATION_WLIST
198IS_WIN = True
199IS_LINUX = False
200CLOSE_SHOW = True
201TIME_FACTOR = 2
202NOT_SO_GRAPH_LIST = ["BoxSum"]
203
204class Communicate(QtCore.QObject):
205    """
206    Utility class for tracking of the Qt signals
207    """
208    # File got successfully read
209    fileReadSignal = QtCore.pyqtSignal(list)
210
211    # Open File returns "list" of paths
212    fileDataReceivedSignal = QtCore.pyqtSignal(dict)
213
214    # Update Main window status bar with "str"
215    # Old "StatusEvent"
216    statusBarUpdateSignal = QtCore.pyqtSignal(str)
217
218    # Send data to the current perspective
219    updatePerspectiveWithDataSignal = QtCore.pyqtSignal(list)
220
221    # New data in current perspective
222    updateModelFromPerspectiveSignal = QtCore.pyqtSignal(QtGui.QStandardItem)
223
224    # New plot requested from the GUI manager
225    # Old "NewPlotEvent"
226    plotRequestedSignal = QtCore.pyqtSignal(str)
227
228    # Progress bar update value
229    progressBarUpdateSignal = QtCore.pyqtSignal(int)
230
231    # Workspace charts added/removed
232    activeGraphsSignal = QtCore.pyqtSignal(list)
233
234    # Current workspace chart's name changed
235    activeGraphName = QtCore.pyqtSignal(tuple)
236
237
238def updateModelItemWithPlot(item, update_data, name=""):
239    """
240    Adds a checkboxed row named "name" to QStandardItem
241    Adds QVariant 'update_data' to that row.
242    """
243    assert isinstance(item, QtGui.QStandardItem)
244    assert isinstance(update_data, QtCore.QVariant)
245
246    checkbox_item = QtGui.QStandardItem(True)
247    checkbox_item.setCheckable(True)
248    checkbox_item.setCheckState(QtCore.Qt.Checked)
249    checkbox_item.setText(name)
250
251    # Add "Info" item
252    py_update_data = update_data.toPyObject()
253    if isinstance(py_update_data, (Data1D or Data2D)):
254        # If Data1/2D added - extract Info from it
255        info_item = infoFromData(py_update_data)
256    else:
257        # otherwise just add a naked item
258        info_item = QtGui.QStandardItem("Info")
259
260    # Add the actual Data1D/Data2D object
261    object_item = QtGui.QStandardItem()
262    object_item.setData(update_data)
263
264    # Set the data object as the first child
265    checkbox_item.setChild(0, object_item)
266
267    # Set info_item as the second child
268    checkbox_item.setChild(1, info_item)
269
270    # Append the new row to the main item
271    item.appendRow(checkbox_item)
272
273def updateModelItem(item, update_data, name=""):
274    """
275    Adds a simple named child to QStandardItem
276    """
277    assert isinstance(item, QtGui.QStandardItem)
278    assert isinstance(update_data, list)
279
280    # Add the actual Data1D/Data2D object
281    object_item = QtGui.QStandardItem()
282    object_item.setText(name)
283    object_item.setData(QtCore.QVariant(update_data))
284
285    # Append the new row to the main item
286    item.appendRow(object_item)
287
288
289def plotsFromCheckedItems(model_item):
290    """
291    Returns the list of plots for items in the model which are checked
292    """
293    assert isinstance(model_item, QtGui.QStandardItemModel)
294
295    plot_data = []
296    # Iterate over model looking for items with checkboxes
297    for index in range(model_item.rowCount()):
298        item = model_item.item(index)
299        if item.isCheckable() and item.checkState() == QtCore.Qt.Checked:
300            # TODO: assure item type is correct (either data1/2D or Plotter)
301            plot_data.append(item.child(0).data().toPyObject())
302        # Going 1 level deeper only
303        for index_2 in range(item.rowCount()):
304            item_2 = item.child(index_2)
305            if item_2 and item_2.isCheckable() and item_2.checkState() == QtCore.Qt.Checked:
306                # TODO: assure item type is correct (either data1/2D or Plotter)
307                plot_data.append(item_2.child(0).data().toPyObject())
308
309    return plot_data
310
311def infoFromData(data):
312    """
313    Given Data1D/Data2D object, extract relevant Info elements
314    and add them to a model item
315    """
316    assert isinstance(data, (Data1D, Data2D))
317
318    info_item = QtGui.QStandardItem("Info")
319
320    title_item = QtGui.QStandardItem("Title: " + data.title)
321    info_item.appendRow(title_item)
322    run_item = QtGui.QStandardItem("Run: " + str(data.run))
323    info_item.appendRow(run_item)
324    type_item = QtGui.QStandardItem("Type: " + str(data.__class__.__name__))
325    info_item.appendRow(type_item)
326
327    if data.path:
328        path_item = QtGui.QStandardItem("Path: " + data.path)
329        info_item.appendRow(path_item)
330
331    if data.instrument:
332        instr_item = QtGui.QStandardItem("Instrument: " + data.instrument)
333        info_item.appendRow(instr_item)
334
335    process_item = QtGui.QStandardItem("Process")
336    if isinstance(data.process, list) and data.process:
337        for process in data.process:
338            process_date = process.date
339            process_date_item = QtGui.QStandardItem("Date: " + process_date)
340            process_item.appendRow(process_date_item)
341
342            process_descr = process.description
343            process_descr_item = QtGui.QStandardItem("Description: " + process_descr)
344            process_item.appendRow(process_descr_item)
345
346            process_name = process.name
347            process_name_item = QtGui.QStandardItem("Name: " + process_name)
348            process_item.appendRow(process_name_item)
349
350    info_item.appendRow(process_item)
351
352    return info_item
353
354def openLink(url):
355    """
356    Open a URL in an external browser.
357    Check the URL first, though.
358    """
359    parsed_url = urlparse.urlparse(url)
360    if parsed_url.scheme:
361        webbrowser.open(url)
362    else:
363        msg = "Attempt at opening an invalid URL"
364        raise AttributeError, msg
365
366def retrieveData1d(data):
367    """
368    Retrieve 1D data from file and construct its text
369    representation
370    """
371    if not isinstance(data, Data1D):
372        msg = "Incorrect type passed to retrieveData1d"
373        raise AttributeError, msg
374    try:
375        xmin = min(data.x)
376        ymin = min(data.y)
377    except:
378        msg = "Unable to find min/max of \n data named %s" % \
379                    data.filename
380        #logging.error(msg)
381        raise ValueError, msg
382
383    text = data.__str__()
384    text += 'Data Min Max:\n'
385    text += 'X_min = %s:  X_max = %s\n' % (xmin, max(data.x))
386    text += 'Y_min = %s:  Y_max = %s\n' % (ymin, max(data.y))
387    if data.dy != None:
388        text += 'dY_min = %s:  dY_max = %s\n' % (min(data.dy), max(data.dy))
389    text += '\nData Points:\n'
390    x_st = "X"
391    for index in range(len(data.x)):
392        if data.dy != None and len(data.dy) > index:
393            dy_val = data.dy[index]
394        else:
395            dy_val = 0.0
396        if data.dx != None and len(data.dx) > index:
397            dx_val = data.dx[index]
398        else:
399            dx_val = 0.0
400        if data.dxl != None and len(data.dxl) > index:
401            if index == 0:
402                x_st = "Xl"
403            dx_val = data.dxl[index]
404        elif data.dxw != None and len(data.dxw) > index:
405            if index == 0:
406                x_st = "Xw"
407            dx_val = data.dxw[index]
408
409        if index == 0:
410            text += "<index> \t<X> \t<Y> \t<dY> \t<d%s>\n" % x_st
411        text += "%s \t%s \t%s \t%s \t%s\n" % (index,
412                                                data.x[index],
413                                                data.y[index],
414                                                dy_val,
415                                                dx_val)
416    return text
417
418def retrieveData2d(data):
419    """
420    Retrieve 2D data from file and construct its text
421    representation
422    """
423    if not isinstance(data, Data2D):
424        msg = "Incorrect type passed to retrieveData2d"
425        raise AttributeError, msg
426
427    text = data.__str__()
428    text += 'Data Min Max:\n'
429    text += 'I_min = %s\n' % min(data.data)
430    text += 'I_max = %s\n\n' % max(data.data)
431    text += 'Data (First 2501) Points:\n'
432    text += 'Data columns include err(I).\n'
433    text += 'ASCII data starts here.\n'
434    text += "<index> \t<Qx> \t<Qy> \t<I> \t<dI> \t<dQparal> \t<dQperp>\n"
435    di_val = 0.0
436    dx_val = 0.0
437    dy_val = 0.0
438    len_data = len(data.qx_data)
439    for index in xrange(0, len_data):
440        x_val = data.qx_data[index]
441        y_val = data.qy_data[index]
442        i_val = data.data[index]
443        if data.err_data != None:
444            di_val = data.err_data[index]
445        if data.dqx_data != None:
446            dx_val = data.dqx_data[index]
447        if data.dqy_data != None:
448            dy_val = data.dqy_data[index]
449
450        text += "%s \t%s \t%s \t%s \t%s \t%s \t%s\n" % (index,
451                                                        x_val,
452                                                        y_val,
453                                                        i_val,
454                                                        di_val,
455                                                        dx_val,
456                                                        dy_val)
457        # Takes too long time for typical data2d: Break here
458        if index >= 2500:
459            text += ".............\n"
460            break
461
462    return text
463
464def onTXTSave(data, path):
465    """
466    Save file as formatted txt
467    """
468    with open(path,'w') as out:
469        has_errors = True
470        if data.dy == None or data.dy == []:
471            has_errors = False
472        # Sanity check
473        if has_errors:
474            try:
475                if len(data.y) != len(data.dy):
476                    has_errors = False
477            except:
478                has_errors = False
479        if has_errors:
480            if data.dx != None and data.dx != []:
481                out.write("<X>   <Y>   <dY>   <dX>\n")
482            else:
483                out.write("<X>   <Y>   <dY>\n")
484        else:
485            out.write("<X>   <Y>\n")
486
487        for i in range(len(data.x)):
488            if has_errors:
489                if data.dx != None and data.dx != []:
490                    if  data.dx[i] != None:
491                        out.write("%g  %g  %g  %g\n" % (data.x[i],
492                                                        data.y[i],
493                                                        data.dy[i],
494                                                        data.dx[i]))
495                    else:
496                        out.write("%g  %g  %g\n" % (data.x[i],
497                                                    data.y[i],
498                                                    data.dy[i]))
499                else:
500                    out.write("%g  %g  %g\n" % (data.x[i],
501                                                data.y[i],
502                                                data.dy[i]))
503            else:
504                out.write("%g  %g\n" % (data.x[i],
505                                        data.y[i]))
506
507def saveData1D(data):
508    """
509    Save 1D data points
510    """
511    default_name = os.path.basename(data.filename)
512    default_name, extension = os.path.splitext(default_name)
513    default_name += "_out" + extension
514
515    wildcard = "Text files (*.txt);;"\
516                "CanSAS 1D files(*.xml)"
517    kwargs = {
518        'caption'   : 'Save As',
519        'directory' : default_name,
520        'filter'    : wildcard,
521        'parent'    : None,
522    }
523    # Query user for filename.
524    filename = QtGui.QFileDialog.getSaveFileName(**kwargs)
525
526    # User cancelled.
527    if not filename:
528        return
529
530    filename = str(filename)
531
532    #Instantiate a loader
533    loader = Loader()
534    if os.path.splitext(filename)[1].lower() == ".txt":
535        onTXTSave(data, filename)
536    if os.path.splitext(filename)[1].lower() == ".xml":
537        loader.save(filename, data, ".xml")
538
539def saveData2D(data):
540    """
541    Save data2d dialog
542    """
543    default_name = os.path.basename(data.filename)
544    default_name, _ = os.path.splitext(default_name)
545    ext_format = ".dat"
546    default_name += "_out" + ext_format
547
548    wildcard = "IGOR/DAT 2D file in Q_map (*.dat)"
549    kwargs = {
550        'caption'   : 'Save As',
551        'directory' : default_name,
552        'filter'    : wildcard,
553        'parent'    : None,
554    }
555    # Query user for filename.
556    filename = QtGui.QFileDialog.getSaveFileName(**kwargs)
557
558    # User cancelled.
559    if not filename:
560        return
561    filename = str(filename)
562    #Instantiate a loader
563    loader = Loader()
564
565    if os.path.splitext(filename)[1].lower() == ext_format:
566        loader.save(filename, data, ext_format)
567
568class FormulaValidator(QtGui.QValidator):
569    def __init__(self, parent=None):
570        super(FormulaValidator, self).__init__(parent)
571 
572    def validate(self, input, pos):
573        try:
574            Formula(str(input))
575            self._setStyleSheet("")
576            return QtGui.QValidator.Acceptable, pos
577
578        except Exception as e:
579            self._setStyleSheet("background-color:pink;")
580            return QtGui.QValidator.Intermediate, pos
581
582    def _setStyleSheet(self, value):
583        try:
584            if self.parent():
585                self.parent().setStyleSheet(value)
586        except:
587            pass
588
589def xyTransform(data, xLabel="", yLabel=""):
590    """
591    Transforms x and y in View and set the scale
592    """
593    # Changing the scale might be incompatible with
594    # currently displayed data (for instance, going
595    # from ln to log when all plotted values have
596    # negative natural logs).
597    # Go linear and only change the scale at the end.
598    xscale = 'linear'
599    yscale = 'linear'
600    # Local data is either 1D or 2D
601    if data.id == 'fit':
602        return
603
604    # control axis labels from the panel itself
605    yname, yunits = data.get_yaxis()
606    xname, xunits = data.get_xaxis()
607
608    # Goes through all possible scales
609    # self.x_label is already wrapped with Latex "$", so using the argument
610
611    # X
612    if xLabel == "x":
613        data.transformX(transform.toX, transform.errToX)
614        xLabel = "%s(%s)" % (xname, xunits)
615    if xLabel == "x^(2)":
616        data.transformX(transform.toX2, transform.errToX2)
617        xunits = convert_unit(2, xunits)
618        xLabel = "%s^{2}(%s)" % (xname, xunits)
619    if xLabel == "x^(4)":
620        data.transformX(transform.toX4, transform.errToX4)
621        xunits = convert_unit(4, xunits)
622        xLabel = "%s^{4}(%s)" % (xname, xunits)
623    if xLabel == "ln(x)":
624        data.transformX(transform.toLogX, transform.errToLogX)
625        xLabel = "\ln{(%s)}(%s)" % (xname, xunits)
626    if xLabel == "log10(x)":
627        data.transformX(transform.toX_pos, transform.errToX_pos)
628        xscale = 'log'
629        xLabel = "%s(%s)" % (xname, xunits)
630    if xLabel == "log10(x^(4))":
631        data.transformX(transform.toX4, transform.errToX4)
632        xunits = convert_unit(4, xunits)
633        xLabel = "%s^{4}(%s)" % (xname, xunits)
634        xscale = 'log'
635
636    # Y
637    if yLabel == "ln(y)":
638        data.transformY(transform.toLogX, transform.errToLogX)
639        yLabel = "\ln{(%s)}(%s)" % (yname, yunits)
640    if yLabel == "y":
641        data.transformY(transform.toX, transform.errToX)
642        yLabel = "%s(%s)" % (yname, yunits)
643    if yLabel == "log10(y)":
644        data.transformY(transform.toX_pos, transform.errToX_pos)
645        yscale = 'log'
646        yLabel = "%s(%s)" % (yname, yunits)
647    if yLabel == "y^(2)":
648        data.transformY(transform.toX2, transform.errToX2)
649        yunits = convert_unit(2, yunits)
650        yLabel = "%s^{2}(%s)" % (yname, yunits)
651    if yLabel == "1/y":
652        data.transformY(transform.toOneOverX, transform.errOneOverX)
653        yunits = convert_unit(-1, yunits)
654        yLabel = "1/%s(%s)" % (yname, yunits)
655    if yLabel == "y*x^(2)":
656        data.transformY(transform.toYX2, transform.errToYX2)
657        xunits = convert_unit(2, xunits)
658        yLabel = "%s \ \ %s^{2}(%s%s)" % (yname, xname, yunits, xunits)
659    if yLabel == "y*x^(4)":
660        data.transformY(transform.toYX4, transform.errToYX4)
661        xunits = convert_unit(4, xunits)
662        yLabel = "%s \ \ %s^{4}(%s%s)" % (yname, xname, yunits, xunits)
663    if yLabel == "1/sqrt(y)":
664        data.transformY(transform.toOneOverSqrtX,
665                                transform.errOneOverSqrtX)
666        yunits = convert_unit(-0.5, yunits)
667        yLabel = "1/\sqrt{%s}(%s)" % (yname, yunits)
668    if yLabel == "ln(y*x)":
669        data.transformY(transform.toLogXY, transform.errToLogXY)
670        yLabel = "\ln{(%s \ \ %s)}(%s%s)" % (yname, xname, yunits, xunits)
671    if yLabel == "ln(y*x^(2))":
672        data.transformY(transform.toLogYX2, transform.errToLogYX2)
673        xunits = convert_unit(2, xunits)
674        yLabel = "\ln (%s \ \ %s^{2})(%s%s)" % (yname, xname, yunits, xunits)
675    if yLabel == "ln(y*x^(4))":
676        data.transformY(transform.toLogYX4, transform.errToLogYX4)
677        xunits = convert_unit(4, xunits)
678        yLabel = "\ln (%s \ \ %s^{4})(%s%s)" % (yname, xname, yunits, xunits)
679    if yLabel == "log10(y*x^(4))":
680        data.transformY(transform.toYX4, transform.errToYX4)
681        xunits = convert_unit(4, xunits)
682        yscale = 'log'
683        yLabel = "%s \ \ %s^{4}(%s%s)" % (yname, xname, yunits, xunits)
684
685    # Perform the transformation of data in data1d->View
686    data.transformView()
687
688    return (xLabel, yLabel, xscale, yscale)
689
690def dataFromItem(item):
691    """
692    Retrieve Data1D/2D component from QStandardItem.
693    The assumption - data stored in SasView standard, in child 0
694    """
695    return item.child(0).data().toPyObject()
696
697def formatNumber(value, high=False):
698    """
699    Return a float in a standardized, human-readable formatted string.
700    This is used to output readable (e.g. x.xxxe-y) values to the panel.
701    """
702    try:
703        value = float(value)
704    except:
705        output = "NaN"
706        return output.lstrip().rstrip()
707
708    if high:
709        output = "%-6.4g" % value
710
711    else:
712        output = "%-5.3g" % value
713    return output.lstrip().rstrip()
Note: See TracBrowser for help on using the repository browser.