From c93857459328845a14c3ea537516e3bfa0a0e00c Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Fri, 19 Sep 2014 13:51:44 +0100 Subject: [PATCH 001/275] Add first cut at integrating S. Millers' system monitor. At the moment it requires psutil to work. Refs #9843 --- Code/Mantid/MantidPlot/CMakeLists.txt | 22 +- Code/Mantid/MantidPlot/SysMon/README.md | 25 + Code/Mantid/MantidPlot/SysMon/SysMon.pyw | 106 +++ Code/Mantid/MantidPlot/SysMon/__init__.py | 0 Code/Mantid/MantidPlot/SysMon/config.py | 16 + Code/Mantid/MantidPlot/SysMon/sysmon.py | 224 ++++++ Code/Mantid/MantidPlot/SysMon/sysmon_tools.py | 391 ++++++++++ Code/Mantid/MantidPlot/SysMon/ui_sysmon.py | 377 ++++++++++ Code/Mantid/MantidPlot/SysMon/ui_sysmon.ui | 670 ++++++++++++++++++ .../MantidPlot/SysMon/ui_sysmonMainWindow.py | 69 ++ .../MantidPlot/SysMon/ui_sysmonMainWindow.ui | 81 +++ .../MantidPlot/src/ApplicationWindow.cpp | 44 +- .../Mantid/MantidPlot/src/ApplicationWindow.h | 23 +- .../MantidPlot/src/Mantid/MantidDock.cpp | 51 +- Code/Mantid/MantidPlot/src/Mantid/MantidUI.h | 28 +- Code/Mantid/MantidPlot/src/qti.sip | 10 +- 16 files changed, 2076 insertions(+), 61 deletions(-) create mode 100644 Code/Mantid/MantidPlot/SysMon/README.md create mode 100755 Code/Mantid/MantidPlot/SysMon/SysMon.pyw create mode 100644 Code/Mantid/MantidPlot/SysMon/__init__.py create mode 100644 Code/Mantid/MantidPlot/SysMon/config.py create mode 100644 Code/Mantid/MantidPlot/SysMon/sysmon.py create mode 100644 Code/Mantid/MantidPlot/SysMon/sysmon_tools.py create mode 100644 Code/Mantid/MantidPlot/SysMon/ui_sysmon.py create mode 100644 Code/Mantid/MantidPlot/SysMon/ui_sysmon.ui create mode 100644 Code/Mantid/MantidPlot/SysMon/ui_sysmonMainWindow.py create mode 100644 Code/Mantid/MantidPlot/SysMon/ui_sysmonMainWindow.ui diff --git a/Code/Mantid/MantidPlot/CMakeLists.txt b/Code/Mantid/MantidPlot/CMakeLists.txt index 8a3b45f4a3d0..20ffa62bc0a5 100644 --- a/Code/Mantid/MantidPlot/CMakeLists.txt +++ b/Code/Mantid/MantidPlot/CMakeLists.txt @@ -847,6 +847,20 @@ copy_python_files_to_dir ( "${IPY_FILES}" ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/ipython_widget IPYTHON_INSTALL_FILES ) +# IPython scripts +set( SYSMON_FILES + __init__.py + config.py + sysmon.py + sysmon_tools.py + ui_sysmon.py + ui_sysmon.ui +) +copy_python_files_to_dir ( "${SYSMON_FILES}" + ${CMAKE_CURRENT_SOURCE_DIR}/SysMon + ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/SysMon + SYSMON_INSTALL_FILES ) + ########################################################################### # MantidPlot executable ########################################################################### @@ -854,7 +868,7 @@ copy_python_files_to_dir ( "${IPY_FILES}" add_executable ( MantidPlot ${WIN_CONSOLE} MACOSX_BUNDLE ${ALL_SRC} src/main.cpp ${INC_FILES} ${QTIPLOT_C_SRC} ${UI_HDRS} ${RES_FILES} ${MANTID_RC_FILE} - ${PYTHON_INSTALL_FILES} ${MTDPLOT_INSTALL_FILES} ${IPYTHON_INSTALL_FILES} + ${PYTHON_INSTALL_FILES} ${MTDPLOT_INSTALL_FILES} ${IPYTHON_INSTALL_FILES} ${SYSMON_INSTALL_FILES} ) # Library dependencies @@ -923,9 +937,9 @@ set ( MANTIDPLOT_TEST_PY_FILES MantidPlot2DPlotTest.py MantidPlotProxiesTest.py MantidPlotPythonImportTest.py - MantidPlotFoldersTest.py - MantidPlotMdiSubWindowTest.py - MantidPlotTiledWindowTest.py + MantidPlotFoldersTest.py + MantidPlotMdiSubWindowTest.py + MantidPlotTiledWindowTest.py ) if ( 0 ) diff --git a/Code/Mantid/MantidPlot/SysMon/README.md b/Code/Mantid/MantidPlot/SysMon/README.md new file mode 100644 index 000000000000..8ef2ab770d04 --- /dev/null +++ b/Code/Mantid/MantidPlot/SysMon/README.md @@ -0,0 +1,25 @@ +SysMon +====== + +Python qt system monitor which utilizes the Python psutil and platform modules to provide system information for display. + +This application has been adapted to work with psutil version 1 and version 2 modules as there are some command syntax changes between these two versions. + +The SysMon user interface has been divided into a main window which imports the tabs to make a standalone application, or the tabs can be imported into other applications as a QWidget. Thus there are separate .ui files corresponding to each. + +The code which imports the tabs into the main program resides in SysMon.pyw. This is where to look to see how to include the tabs into your own application. All files except SysMon.pyw and ui_sysmonMainWindow.* will be required when tabs are incorporated in other applications. + +The following command line arguments have been added: + --help to print out the help message. + --nompl to run the application minus matplotlib in support of the current MantidPlot (removes those tabs requiring matplotlib). + --custom to enable the custom menubar item in the standalone application (currently supports checking Matlab license status on SNS analysis computers). + +To run as a standalone application via the corresponding command lines: + *Change to the folder containing the Sysmon software, then: + *DOS: python SysMon.pyw + *Linux: ./SysMon.pyw + +The standalone application been tested on Windows and RHEL Linux, but not on Mac yet. + +Note that configuration and global constants and variables now reside in config.py. + diff --git a/Code/Mantid/MantidPlot/SysMon/SysMon.pyw b/Code/Mantid/MantidPlot/SysMon/SysMon.pyw new file mode 100755 index 000000000000..4fd044de0cbe --- /dev/null +++ b/Code/Mantid/MantidPlot/SysMon/SysMon.pyw @@ -0,0 +1,106 @@ +#!/usr/bin/python +""" +SysMon.pyw +Initial application development 03Sep14 by S. Miller +The application utilizes the psutil and platform python modules to provide system information +for display via text fields, a table and Matplotlib plots. + +The application utilizes a timer with user selectable timer intervals to update information +provided to the application. +""" +import config +import sys + +#parse args - doing it here as config structure needs to be filled prior to importing sysmon +if ['--nompl'] == [s for s in sys.argv if '--nompl' in s]: + #case to not use matplotlib + config.nompl=True +else: + #case to use matplotlib (default case) + config.nompl=False + +if ['--help'] == [s for s in sys.argv if '--help' in s]: + print "SysMon Help" + print "--help - this message" + print "--nompl - flag to disable using matplotlib, also disables History and Users tabs" + print "--custom: - flag to use facility specific options" + sys.exit() + +if ['--custom'] == [s for s in sys.argv if '--custom' in s]: + config.custom=True + +from PyQt4 import QtGui + +from ui_sysmonMainWindow import * +#from ui_sysmonTabs import * +from sysmon import * + +class SysMonMainWindow(QtGui.QMainWindow): + + def __init__(self, parent=None): + #setup main window + QtGui.QMainWindow.__init__(self, parent) + self.setWindowTitle("System Status") + self.ui = Ui_MainWindow() #defined from ui_sysmon.py + self.ui.setupUi(self) + #setup tabs - class imported from sysmon.py + self.sysmontabs=SysMon(self) + self.setCentralWidget(self.sysmontabs) + + #setup menu bar actions + self.connect(self.ui.actionExit, QtCore.SIGNAL('triggered()'), self.confirmExit) #define function to confirm and perform exit + self.connect(self.ui.actionAbout, QtCore.SIGNAL('triggered()'), self.About) + self.connect(self.ui.actionCheck_Matlab_Licenses, QtCore.SIGNAL('triggered()'), self.updateMatlab) + + #check if custom menu bar enabled via command line flag --custom and if not, remove it as it's built by default from Qt + if not(config.custom): + self.ui.menubar.removeAction(self.ui.menuCustom.menuAction()) + + + #define methods for menu bar options + def confirmExit(self): + reply = QtGui.QMessageBox.question(self, 'Message', + "Are you sure to quit?", QtGui.QMessageBox.Yes | + QtGui.QMessageBox.No, QtGui.QMessageBox.No) + + if reply == QtGui.QMessageBox.Yes: + #close application + self.close() + else: + #do nothing and return + pass + + def About(self): + dialog=QtGui.QMessageBox(self) + dialog.setText("PyQt4 System Monitoring Application V0.02") + info='Application Info: \n\r * Changing the Update Rate Clears plots \n\r * It may take one full new update cycle for changes to take effect \n\r * Update rate shown in History plot xaxis label \n\r * Process tab CPU percentage can be greater than 100 when more than a single core is involved' + dialog.setDetailedText(info) #give full info in detailed text + dialog.exec_() + + def updateMatlab(self): + #run license server command to extract license info + info=commands.getstatusoutput(config.matlabchk) + info=str(info[1]) #seem to need to make this a string for Linux to work properly + #test if info string contains MATLAB info + if info.find("MATLAB") < 0: + #case where no license server found + outstr="No Matlab License Server Found to Check" + else: + indx0=info.find("Users of MATLAB:") + indx1=info.find("licenses in use") + if indx0 > -1 and indx1 > -1: + outstr=info[indx0:indx1+15+1] + else: + outstr="Unable to determine Matlab license information" + dialog=QtGui.QMessageBox(self) + #print "outstr: "+outstr + dialog.setText(outstr) + dialog.setDetailedText(info) #give full info in detailed text + dialog.exec_() + +if __name__=="__main__": + app = QtGui.QApplication(sys.argv) + sysmon = SysMonMainWindow() + sysmon.show() + + sys.exit(app.exec_()) \ No newline at end of file diff --git a/Code/Mantid/MantidPlot/SysMon/__init__.py b/Code/Mantid/MantidPlot/SysMon/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/Code/Mantid/MantidPlot/SysMon/config.py b/Code/Mantid/MantidPlot/SysMon/config.py new file mode 100644 index 000000000000..508ba68e711b --- /dev/null +++ b/Code/Mantid/MantidPlot/SysMon/config.py @@ -0,0 +1,16 @@ + +#global definitions for constants and variables + +#Tab indices: +SYST_TAB=0 +HIST_TAB=1 +PROC_TAB=2 +USER_TAB=3 +OPTS_TAB=4 + +#Global Variables: +psutilVer=0 #flag for the version of psutil being used +nompl=False +mplLoaded=False #flag for matplotlib loading +custom=False +matlabchk='lmstat -S -c 27010@licenses1.sns.gov' \ No newline at end of file diff --git a/Code/Mantid/MantidPlot/SysMon/sysmon.py b/Code/Mantid/MantidPlot/SysMon/sysmon.py new file mode 100644 index 000000000000..1f6ce7662002 --- /dev/null +++ b/Code/Mantid/MantidPlot/SysMon/sysmon.py @@ -0,0 +1,224 @@ + + +import sys, os, time +import re +import config #application constants and variables +import psutil +#check psutil version as command syntax changes between version 1 and version 2 +ver=psutil.__version__ +verChk1=re.match('1.[0-9].[0-9]',ver) #latest psutil version 1 is 1.2.1 - using positional numeric wildcards to check sub versions +#thus the check is for version 1 as version 2 and following versions are still evolving +#match returns a string if a match is found else returns NoneType +if verChk1 != None: + config.psutilVer=1 +else: + config.psutilVer=2 + +from ui_sysmon import * +from sysmon_tools import * + + +import platform +import commands + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + _fromUtf8 = lambda s: s + +class SysMon(QtGui.QWidget): + + def __init__(self, parent=None): + QtGui.QWidget.__init__(self, parent) + self.ui = Ui_Form() #defined from ui_sysmon.py + self.ui.setupUi(self) + self.ui.progressBarStatusMemory.setStyleSheet("QProgressBar {width: 25px;border: 1px solid black; border-radius: 3px; background: white;text-align: center;padding: 0px;}" + +"QProgressBar::chunk:horizontal {background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #00CCEE, stop: 0.3 #00DDEE, stop: 0.6 #00EEEE, stop:1 #00FFEE);}") + self.ui.progressBarStatusCPU.setStyleSheet("QProgressBar {width: 25px;border: 1px solid black; border-radius: 3px; background: white;text-align: center;padding: 0px;}" + +"QProgressBar::chunk:horizontal {background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #00CCEE, stop: 0.3 #00DDEE, stop: 0.6 #00EEEE, stop:1 #00FFEE);}") + + #setup timer to enable periodic events such as status update checks + self.ctimer = QtCore.QTimer() + self.ctimer.start(2000) #time in mSec - set repetitive timer of 2 seconds + QtCore.QObject.connect(self.ctimer, QtCore.SIGNAL("timeout()"), self.constantUpdate) + + #update rate actions + QtCore.QObject.connect(self.ui.radioButton1Sec, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.update1Sec) + QtCore.QObject.connect(self.ui.radioButton2Secs, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.update2Sec) + QtCore.QObject.connect(self.ui.radioButton5Secs, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.update5Sec) + QtCore.QObject.connect(self.ui.radioButton10Secs, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.update10Sec) + self.update=2 #set default to 2 seconds update rate + + #duration actions + QtCore.QObject.connect(self.ui.radioButton60Secs, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.update60Duration) + QtCore.QObject.connect(self.ui.radioButton300Secs, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.update300Duration) + QtCore.QObject.connect(self.ui.radioButton600Secs, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.update600Duration) + QtCore.QObject.connect(self.ui.radioButton3600Secs, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.update3600Duration) + self.duration=60 #set default plot duration to 60 seconds + + QtCore.QObject.connect(self.ui.pushButtonUpdate, QtCore.SIGNAL('clicked(bool)'), self.updateProcesses) + + #Initialize System Tab + self.ui.tabWidget.setCurrentIndex(config.SYST_TAB) + self.ui.labelComputerName.setText("Computer Name: "+platform.node()) + if platform.os.name == 'nt': + info=platform.win32_ver() + oslabel="Windows "+info[0]+" Version: "+info[1] + elif platform.os.name == 'posix': + info=platform.linux_distribution() + oslabel=info[0]+" Version: "+info[1] + elif platform.os.name == 'mac': + info=platform.mac_ver() + oslabel=info[0]+" Version: "+info[1] + else: + oslabel=" " + + self.ui.labelOS.setText("Operating System: "+oslabel) + info=platform.uname() + self.ui.labelProcFam.setText("Processor Family: "+info[5]) + + #determine the number of users on the computer + userInfo=psutil.get_users() if config.psutilVer==1 else psutil.users() + lst=[] + for item in userInfo: + lst.append(item.name) + uusers=set(lst) + Nuusers=len(uusers) + self.ui.labelNUsers.setText("Number of Users Logged On: "+str(Nuusers)) + + #determine the computer uptime + if config.psutilVer == 1: + uptime = str(datetime.datetime.now() - datetime.datetime.fromtimestamp(psutil.BOOT_TIME)) + else: + uptime = str(datetime.datetime.now() - datetime.datetime.fromtimestamp(psutil.boot_time())) + self.ui.labelUptime.setText("System Uptime: "+uptime) + + if config.mplLoaded: + #if matplotlib loaded OK, initialize plotting + #Initialize History Tab + self.ui.tabWidget.setCurrentIndex(config.HIST_TAB) + #Place Matplotlib figure within the GUI frame + #create drawing canvas + # a figure instance to plot on + + matplotlib.rc_context({'toolbar':False}) + #initialize figure 1 and its canvas for cpu and memory history plots + self.ui.figure = plt.figure(1) + # the Canvas Widget displays the `figure` + # it takes the `figure` instance as a parameter to __init__ + self.ui.canvas = FigureCanvas(self.ui.figure) + layout=QtGui.QVBoxLayout(self.ui.framePlot) + layout.addWidget(self.ui.canvas) + self.ui.layout=layout + + #initialize figure 2 and its canvas for user usage bar chart + self.ui.figure2 = plt.figure(2) + self.ui.canvas2 = FigureCanvas(self.ui.figure2) + layout2=QtGui.QVBoxLayout(self.ui.frameBar) + layout2.addWidget(self.ui.canvas2) + self.ui.layout2=layout2 + + + else: + #if matplotlib not loaded, remove the tabs that depend upon it + self.removeMPLTabs() + + #initialize history plot arrays - easier just to initialize these even if not doing plotting in case when matplotlib not available. + Nsamples=3600 + self.ui.Nsamples=Nsamples + #need one extra sample to fill the plotting interval + self.ui.cpu=np.zeros(Nsamples+1) + self.ui.mem=np.zeros(Nsamples+1) + self.ui.dt=[None]*(Nsamples+1) + + self.ui.tabWidget.setTabsClosable(False) #disable the ability to close tabs once state of matplotlib is handled + + #initialize the process table + self.doUpdates=True #flag for updating the process tab table + updateProcTable(self,config) + + #upon initialization completion, set System tab (first tab on left) as the visible tab + self.ui.tabWidget.setCurrentIndex(config.SYST_TAB) + + def constantUpdate(self): + #redirct to global function + constantUpdateActor(self,config) + + def update1Sec(self): + self.update=1 + self.ctimer.stop() + self.ctimer.start(1000) + #clear persistent arrays when update rate changed + self.ui.cpu=self.ui.cpu*0 + self.ui.mem=self.ui.mem*0 + self.ui.dt=[None]*self.ui.Nsamples + + def update2Sec(self): + self.update=2 + self.ctimer.stop() + self.ctimer.start(2000) + #clear persistent arrays when update rate changed + self.ui.cpu=self.ui.cpu*0 + self.ui.mem=self.ui.mem*0 + self.ui.dt=[None]*self.ui.Nsamples + + def update5Sec(self): + self.update=5 + self.ctimer.stop() + self.ctimer.start(5000) + #clear persistent arrays when update rate changed + self.ui.cpu=self.ui.cpu*0 + self.ui.mem=self.ui.mem*0 + self.ui.dt=[None]*self.ui.Nsamples + + def update10Sec(self): + self.update=10 + self.ctimer.stop() + self.ctimer.start(10000) + #clear persistent arrays when update rate changed + self.ui.cpu=self.ui.cpu*0 + self.ui.mem=self.ui.mem*0 + self.ui.dt=[None]*self.ui.Nsamples + + def update60Duration(self): + self.duration=60 + def update300Duration(self): + self.duration=300 + def update600Duration(self): + self.duration=600 + def update3600Duration(self): + self.duration=3600 + + def updateProcesses(self): + if self.doUpdates == True: + #case to toggle to False + self.doUpdates=False + self.ui.pushButtonUpdate.setText('Continue') + else: + #case where updates must be off + self.doUpdates=True + self.ui.pushButtonUpdate.setText('Hold Updates') + + def resizeEvent(self,resizeEvent): + print "resizing" + sz=self.ui.tableWidgetProcess.size() + w=sz.width() + self.ui.tableWidgetProcess.setColumnWidth(0,3*w/20) + self.ui.tableWidgetProcess.setColumnWidth(1,5*w/20) + self.ui.tableWidgetProcess.setColumnWidth(2,3*w/20) + self.ui.tableWidgetProcess.setColumnWidth(3,3*w/20) + self.ui.tableWidgetProcess.setColumnWidth(4,6*w/20) + + def removeMPLTabs(self): + #In case matplotlib not available, remove tabs requiring this + #Note to developers - removing tabs changes the tab index numbers! + #Keep this in mind regarding setting and using tab indices + self.ui.tabWidget.removeTab(config.HIST_TAB) #History tab + config.HIST_TAB=-1 + config.PROC_TAB-=1 + config.USER_TAB-=1 + config.OPTS_TAB-=1 + self.ui.tabWidget.removeTab(config.USER_TAB) #Users tab - originally tab 3, but becomes tab 2 once history tab is removed + config.USER_TAB=-1 + config.OPTS_TAB-=1 + self.ui.tabWidget.setTabsClosable(False) diff --git a/Code/Mantid/MantidPlot/SysMon/sysmon_tools.py b/Code/Mantid/MantidPlot/SysMon/sysmon_tools.py new file mode 100644 index 000000000000..2e8d9eabb004 --- /dev/null +++ b/Code/Mantid/MantidPlot/SysMon/sysmon_tools.py @@ -0,0 +1,391 @@ +import psutil +from PyQt4 import Qt, QtCore, QtGui +import datetime +import numpy as np +import config + +#check if command line flag --nompl set to disable matplotlib +if not(config.nompl): + try: + import matplotlib + if matplotlib.get_backend() != 'QT4Agg': + matplotlib.use('QT4Agg') + from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas + from matplotlib.backends.backend_qt4 import NavigationToolbar2QT as NavigationToolbar + import matplotlib.pyplot as plt + config.mplLoaded=True + # print "matplotlib try successful" + except: + # print "matplotlib except case" + #case where matplotlib not available - need to know this for handling plotting tabs + config.mplLoaded=False + pass +else: + config.mplLoaded=False #use this flag to test case when matplotlib is not available + +def constantUpdateActor(self,config): + + #check duration + Ndur=self.duration + + #update global variables + + #mode to show status in percentage + cpu_stats = psutil.cpu_times_percent(interval=0,percpu=False) #syntax seems to be same for psutil versions 1 and 2 + percentcpubusy = 100.0 - cpu_stats.idle + self.ui.progressBarStatusCPU.setValue(round(percentcpubusy)) + percentmembusy=psutil.virtual_memory().percent + self.ui.progressBarStatusMemory.setValue(round(percentmembusy)) + Ncpus=len(psutil.cpu_percent(percpu=True)) + self.ui.Ncpus=Ncpus + totalcpustr='CPU Count: '+str(Ncpus) +# print "Total CPU str: ",totalcpustr + self.ui.labelCPUCount.setText(totalcpustr) + totalmem=int(round(float(psutil.virtual_memory().total)/(1024*1024*1024))) #psutil syntax OK for both versions +# print "Total Mem: ",totalmem + self.ui.labelMemUsage.setText('Memory Usage: '+str(totalmem*percentmembusy/100)+' GB') + self.ui.totalmem=totalmem + totalmemstr='Max Mem: '+str(totalmem)+' GB' +# print "Total Mem str: ",totalmemstr + self.ui.labelMaxMem.setText(totalmemstr) +# print "** config.mplLoaded: ",config.mplLoaded + + if config.mplLoaded: + #update first position with most recent value overwriting oldest value which has been shifted to first position + self.ui.cpu=np.roll(self.ui.cpu,1) + self.ui.cpu[0]=percentcpubusy + self.ui.mem=np.roll(self.ui.mem,1) + self.ui.mem[0]=percentmembusy + # self.ui.dt=np.roll(self.ui.dt,1) + # self.ui.dt[0]=datetime.datetime.now() + + # update system tab + if self.ui.tabWidget.currentIndex() == config.SYST_TAB: + #determine the computer uptime + if config.psutilVer == 1: + uptime = str(datetime.datetime.now() - datetime.datetime.fromtimestamp(psutil.BOOT_TIME)) + else: + uptime = str(datetime.datetime.now() - datetime.datetime.fromtimestamp(psutil.boot_time())) + self.ui.labelUptime.setText("System Uptime: "+uptime) + + + + #update the number of users each time interval as well + userInfo=psutil.get_users() if config.psutilVer == 1 else psutil.users() + lst=[] + for item in userInfo: + lst.append(item.name) + uusers=set(lst) + Nuusers=len(uusers) + self.ui.labelNUsers.setText("Number of Users Logged On: "+str(Nuusers)) + + #update the history plot + if self.ui.tabWidget.currentIndex() == config.HIST_TAB: + #only update history plot if tab is active + font = {'family' : 'sans-serif', + 'weight' : 'bold', + 'size' : 10} + matplotlib.rc('font', **font) + + xtime=range(0,self.ui.Nsamples+1,self.update) + + Npts=Ndur/self.update + + plt.figure(self.ui.figure.number) #make plot figure active + plt.clf() #clear figure each time for rolling updates to show + plt.plot(xtime[0:Npts+1],self.ui.cpu[0:Npts+1],color='Blue',label='CPU Busy') + plt.plot(xtime[0:Npts+1],self.ui.mem[0:Npts+1],color='Green',label='Mem Busy') + plt.title('Composite CPU and Memory Activity',fontsize=10,fontweight='bold') + plt.ylabel('% Busy',fontsize=9.5,fontweight='bold') + + if self.update == 1: + xlab="Seconds with 1 Second Updates" + elif self.update == 2: + xlab="Seconds with 2 Second Updates" + elif self.update == 5: + xlab="Seconds with 5 Second Updates" + elif self.update == 10: + xlab="Seconds with 10 Second Updates" + plt.xlabel(xlab,fontsize=9.5,fontweight='bold') + plt.legend(loc="upper right",prop={'size':9}) + plt.xlim([0,Ndur]) + self.ui.canvas.draw() + + #update the process table + if self.ui.tabWidget.currentIndex() == config.PROC_TAB: + #only update process table if tab is active + updateProcTable(self,config) + + #update the Users bar chart + if self.ui.tabWidget.currentIndex() == config.USER_TAB: + #only update bar chart if the tab is active. + updateUserChart(self,config) + + + +def updateProcTable(self,config): + if self.doUpdates==True: + table=self.ui.tableWidgetProcess + #first remove all rows + Nrows=table.rowCount() + for row in range(Nrows): + table.removeRow(0) + + #get the processes + pidList=psutil.get_pid_list() if config.psutilVer == 1 else psutil.pids() + Npids=len(pidList) + + #now add rows to the table according to the number of processes + # for row in range(Npids): + # table.insertRow(0) + + #now populate the table + row=0 #table row counter incremented for each row added to the process table + rout=0 #counter for number of rows to remove due to invalid processes + memtot=psutil.virtual_memory() #psutil syntax OK for both versions + + #determine which column has been selected for sorting + column_sorted=table.horizontalHeader().sortIndicatorSection() + order = table.horizontalHeader().sortIndicatorOrder() + #temporarily set sort column to outside column range so that table items can be filled properly + table.sortItems(5,order=QtCore.Qt.AscendingOrder) + #print table.horizontalHeader().sortIndicatorSection() + + #create empty dictionaries to be used by the process table + d_user={} + d_cpu={} + d_mem={} + d_name={} + + #fill the dictionaries - seems to need to be done faster than within loop which also fills the table...not sure why... + for proc in psutil.process_iter(): + cpupct=proc.get_cpu_percent(interval=0) if config.psutilVer == 1 else proc.cpu_percent(interval=0) + memVal=float(int(float(proc.get_memory_percent())*100.0))/100.0 if config.psutilVer == 1 else float(int(float(proc.memory_percent())*100.0))/100.0 + try: + #don't update dictionaries if name gives an access denied error when checking process name + pname=proc.name if config.psutilVer == 1 else proc.name() + d_user.update({proc.pid:proc.username}) if config.psutilVer == 1 else d_user.update({proc.pid:proc.username()}) + d_cpu.update({proc.pid:cpupct}) + d_mem.update({proc.pid:memVal}) + d_name.update({proc.pid:pname}) + except: + pass #place holder + + #now fill the table for display + for proc in d_user.keys(): + #print "proc: ",proc," type: ",type(proc) + pid=int(proc) + #print "pid: ",pid + + table.insertRow(0) + #print "inserting row" + #set process id + item=QtGui.QTableWidgetItem() + item.setData(QtCore.Qt.DisplayRole,pid) + table.setItem(0,0,item) + #set username + #print " d_user[proc]: ",d_user[proc]," proc: ",proc + table.setItem(0,1,QtGui.QTableWidgetItem(d_user[proc])) + #set CPU % + item=QtGui.QTableWidgetItem() + item.setData(QtCore.Qt.DisplayRole,d_cpu[proc]) + table.setItem(0,2,item) + #set memory % + item=QtGui.QTableWidgetItem() + item.setData(QtCore.Qt.DisplayRole,d_mem[proc]) + table.setItem(0,3,item) + #set process name + table.setItem(0,4,QtGui.QTableWidgetItem(d_name[proc])) + row+=1 + + + # for row in range(rout): + # table.removeRow(Npids-row) + #restore sort to previously selected column + #table.sortItems(column_sorted,order=QtCore.Qt.AscendingOrder) + table.sortItems(column_sorted,order=order) + self.ui.labelLastUpdate.setText("Last Update: "+str(datetime.datetime.now())) + +def updateUserChart(self,config): + + font = {'family' : 'sans-serif', + 'weight' : 'bold', + 'size' : 9} + + matplotlib.rc('font', **font) + + f=plt.figure(self.ui.figure2.number) + +# self.ui.figure2=plt.figure(2) + plt.clf() + plt.cla() +# f.gca().cla() + + #create empty dictionaries to be used by the process table + d_user={} + d_cpu={} + d_mem={} + d_name={} + #fill the dictionaries - seems to need to be done faster than within loop which also fills the table...not sure why... + for proc in psutil.process_iter(): + cpupct=proc.get_cpu_percent(interval=0) if config.psutilVer == 1 else proc.cpu_percent(interval=0) + memVal=float(int(float(proc.get_memory_percent())*100.0))/100.0 if config.psutilVer == 1 else float(int(float(proc.memory_percent())*100.0))/100.0 + try: + #don't update dictionaries if name gives an access denied error when checking process name + pname=proc.name if config.psutilVer == 1 else proc.name() + d_user.update({proc.pid:proc.username}) if config.psutilVer == 1 else d_user.update({proc.pid:proc.username()}) + d_cpu.update({proc.pid:cpupct}) + d_mem.update({proc.pid:memVal}) + d_name.update({proc.pid:pname}) + except: + pass #place holder + + users=d_user.values() + users_unique=list(set(users)) #use set() to find unique users then convert the resulting set to a list via list() + Nusers=len(users_unique) + + #create cpu and memory by users dictionaries + cpu_by_users={} + mem_by_users={} + for u in range(Nusers): + cpu_by_users.update({users_unique[u]:0}) + mem_by_users.update({users_unique[u]:0}) + #apparently update does not order keys in sequence to users_unique + #thus need to re-create users_unique according to the order of the users + #in the cpu and mem dictionary keys + users_unique=list(cpu_by_users.keys()) + + #fill cpu and memory dictionaries sequencing thru each PID + for pid in d_user.keys(): + user=d_user[pid] + cpu_by_users[user]=cpu_by_users[user] + d_cpu[pid] + mem_by_users[user]=mem_by_users[user] + d_mem[pid] + + #now convert to a list which we can index + cpu_by_users_lst=cpu_by_users.values() + mem_by_users_lst=mem_by_users.values() + + width=0.85 + + colors=['b','g','r','c','m','y','gray','hotpink','brown','k'] + Nmax=len(colors) #don't want to have more users than colors... + + if self.ui.radioButtonCPU.isChecked(): + sortBy='cpu' + elif self.ui.radioButtonMem.isChecked(): + sortBy='mem' + else: + print "invalid radio button selection - using CPU sort as default" + sortBy='cpu' + #sortBy='cpu' # 'cpu' or 'mem' - use for debugging + #create sort index + if sortBy=='cpu': + indx=sorted(range(len(cpu_by_users_lst)), key=cpu_by_users_lst.__getitem__,reverse=True) + elif sortBy=='mem': + indx=sorted(range(len(mem_by_users_lst)), key=mem_by_users_lst.__getitem__,reverse=True) + else: + print 'Incorrect sort parameter' + #sort lists + cpu_by_users_sorted=[cpu_by_users_lst[x] for x in indx] + mem_by_users_sorted=[mem_by_users_lst[x] for x in indx] + users_unique_sorted=[users_unique[x] for x in indx] + + #restrict the number of users we'll show to Nmax + if Nusers > Nmax: + #replace the Nmaxth - 1 element with the total of the values from index Nmax - 1 to the end of the list + cpu_by_users_sorted[Nmax-1]=sum(cpu_by_users_sorted[Nmax-1:]) + mem_remaining=sum(mem_by_users_sorted[Nmax-1:]) + users_unique_sorted[Nmax-1]='Remaining' + Nshow=Nmax + else: + Nshow=Nusers + + if min(cpu_by_users_sorted) < 0: + print " *** cp_by_users_sorted has values less than zero" + print cpu_by_users_sorted + print " ***" + if min(mem_by_users_sorted) < 0: + print " *** mem_by_users_sorted has values less than zero" + print mem_by_users_sorted + print " ***" + + #range check the values of the sorted lists - may not be necessary, just being cautious... + tst=np.array(cpu_by_users_sorted)<0 #need an array for summing + indx=cpu_by_users_sorted<0 #need bool list for indexing + if sum(tst) > 0: + print "cpu_by_users < 0: ",sum(indx) + cpu_by_users_sorted[indx]=0 + tst=np.array(cpu_by_users_sorted)>self.ui.Ncpus*100 + indx=cpu_by_users_sorted>self.ui.Ncpus*100 + if sum(tst) > 0: + print "cpu_by_users > Ncpus*100: ",sum(indx) + cpu_by_users_sorted[indx]=self.ui.Ncpus*100 + tst=np.array(mem_by_users_sorted)<0 + indx=mem_by_users_sorted<0 + if sum(tst) > 0: + print "mem_by_users < 0: ",sum(indx) + mem_by_users_sorted[indx]=0 + tst=np.array(mem_by_users_sorted)>self.ui.totalmem + indx=mem_by_users_sorted>self.ui.totalmem + if sum(tst) > 0: + print "mem_by_users > totalmem: ",sum(indx) + mem_by_users_sorted[indx]=self.ui.totalmem + + + p=[] #list to contain plot objects for use by the legend + ind=np.arange(2) + + + for u in range(Nshow): + if u == 0: + p.append(plt.bar(ind,(cpu_by_users_sorted[u],mem_by_users_sorted[u]),width,bottom=(0,0),color=colors[u])) + else: + p.append(plt.bar(ind,(cpu_by_users_sorted[u],mem_by_users_sorted[u]),width,bottom=(sum(cpu_by_users_sorted[0:u]),sum(mem_by_users_sorted[0:u])),color=colors[u])) + + plt.title('CPU and Memory Usage by User',fontsize=10,fontweight='bold') + + #remove default yaxis ticks then redraw them via ax1 and ax2 below + frame=plt.gca() + frame.axes.get_yaxis().set_ticks([]) + plt.xticks(np.arange(2)+width/2.,('CPU','Mem'),fontsize=9,fontweight='bold') + ymaxCPU=round(int((sum(cpu_by_users_sorted[0:Nshow])+100)/100)*100) + ymaxMEM=round(int((sum(mem_by_users_sorted[0:Nshow])+100)/100)*100) + ymax=max([ymaxCPU,ymaxMEM,100]) +# plt.ylim([0,ymax]) + + #compute composite % + ylab=np.arange(6)/5.0*float(ymax)/float(self.ui.Ncpus) + ylab=ylab*10 + tmp=ylab.astype('int') + tmp1=tmp.astype('float') + tmp1=tmp1/10 + ylab1=tmp1 + + ax1=plt.twinx() + ax1.set_ylabel('Composite CPU Percent',fontsize=9,fontweight='bold') + ax1.yaxis.set_ticks_position('left') + ax1.yaxis.set_label_position('left') + ax1.set_yticks(ylab1) + + usersLegend=users_unique_sorted[0:Nshow] + #reverse legend print order to have legend correspond with the order data are placed in the bar chart + usersLegend.reverse() + p.reverse() + plt.legend(p,usersLegend) + + + #place second y axis label on plot + ylab2=np.arange(5)/4.0*float(ymax) + ax2=plt.twinx() + ax2.set_ylabel('Percent',fontsize=9,fontweight='bold') + ax2.set_yticks(ylab2) + #ax2.set_yticks(ylab2) + ax2.yaxis.set_ticks_position('right') + ax2.yaxis.set_label_position('right') + + self.ui.canvas2.draw() + +def reLayout(self): + tmpWidget=QtGui.QWidget() + tmpWidget.setLayout(self.ui.layout2) + tmpLayout = QtGui.QVBoxLayout(self.ui.frameBar) \ No newline at end of file diff --git a/Code/Mantid/MantidPlot/SysMon/ui_sysmon.py b/Code/Mantid/MantidPlot/SysMon/ui_sysmon.py new file mode 100644 index 000000000000..cb543a389d72 --- /dev/null +++ b/Code/Mantid/MantidPlot/SysMon/ui_sysmon.py @@ -0,0 +1,377 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file '../../Code/Mantid/MantidPlot/SysMon/ui_sysmon.ui' +# +# Created: Fri Sep 19 12:44:16 2014 +# by: PyQt4 UI code generator 4.10.4 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) + +class Ui_Form(object): + def setupUi(self, Form): + Form.setObjectName(_fromUtf8("Form")) + Form.resize(230, 331) + Form.setMaximumSize(QtCore.QSize(16777215, 16777215)) + self.horizontalLayout = QtGui.QHBoxLayout(Form) + self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) + self.tabWidget = QtGui.QTabWidget(Form) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth()) + self.tabWidget.setSizePolicy(sizePolicy) + self.tabWidget.setObjectName(_fromUtf8("tabWidget")) + self.tab = QtGui.QWidget() + self.tab.setObjectName(_fromUtf8("tab")) + self.verticalLayout = QtGui.QVBoxLayout(self.tab) + self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) + self.scrollArea = QtGui.QScrollArea(self.tab) + self.scrollArea.setWidgetResizable(True) + self.scrollArea.setObjectName(_fromUtf8("scrollArea")) + self.scrollAreaWidgetContents = QtGui.QWidget() + self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 320, 293)) + self.scrollAreaWidgetContents.setObjectName(_fromUtf8("scrollAreaWidgetContents")) + self.verticalLayout_2 = QtGui.QVBoxLayout(self.scrollAreaWidgetContents) + self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) + self.groupBox_3 = QtGui.QGroupBox(self.scrollAreaWidgetContents) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.groupBox_3.sizePolicy().hasHeightForWidth()) + self.groupBox_3.setSizePolicy(sizePolicy) + self.groupBox_3.setMinimumSize(QtCore.QSize(0, 0)) + self.groupBox_3.setObjectName(_fromUtf8("groupBox_3")) + self.gridLayout_4 = QtGui.QGridLayout(self.groupBox_3) + self.gridLayout_4.setObjectName(_fromUtf8("gridLayout_4")) + self.gridLayout_7 = QtGui.QGridLayout() + self.gridLayout_7.setObjectName(_fromUtf8("gridLayout_7")) + self.labelComputerName = QtGui.QLabel(self.groupBox_3) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.labelComputerName.sizePolicy().hasHeightForWidth()) + self.labelComputerName.setSizePolicy(sizePolicy) + self.labelComputerName.setMinimumSize(QtCore.QSize(0, 0)) + self.labelComputerName.setObjectName(_fromUtf8("labelComputerName")) + self.gridLayout_7.addWidget(self.labelComputerName, 0, 0, 1, 1) + self.labelOS = QtGui.QLabel(self.groupBox_3) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.labelOS.sizePolicy().hasHeightForWidth()) + self.labelOS.setSizePolicy(sizePolicy) + self.labelOS.setMinimumSize(QtCore.QSize(0, 0)) + self.labelOS.setObjectName(_fromUtf8("labelOS")) + self.gridLayout_7.addWidget(self.labelOS, 1, 0, 1, 1) + self.labelProcFam = QtGui.QLabel(self.groupBox_3) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.labelProcFam.sizePolicy().hasHeightForWidth()) + self.labelProcFam.setSizePolicy(sizePolicy) + self.labelProcFam.setMinimumSize(QtCore.QSize(0, 0)) + self.labelProcFam.setObjectName(_fromUtf8("labelProcFam")) + self.gridLayout_7.addWidget(self.labelProcFam, 2, 0, 1, 1) + self.labelNUsers = QtGui.QLabel(self.groupBox_3) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.labelNUsers.sizePolicy().hasHeightForWidth()) + self.labelNUsers.setSizePolicy(sizePolicy) + self.labelNUsers.setMinimumSize(QtCore.QSize(0, 0)) + self.labelNUsers.setObjectName(_fromUtf8("labelNUsers")) + self.gridLayout_7.addWidget(self.labelNUsers, 3, 0, 1, 1) + self.labelUptime = QtGui.QLabel(self.groupBox_3) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.labelUptime.sizePolicy().hasHeightForWidth()) + self.labelUptime.setSizePolicy(sizePolicy) + self.labelUptime.setMinimumSize(QtCore.QSize(0, 0)) + self.labelUptime.setObjectName(_fromUtf8("labelUptime")) + self.gridLayout_7.addWidget(self.labelUptime, 4, 0, 1, 1) + self.gridLayout_4.addLayout(self.gridLayout_7, 0, 0, 1, 1) + self.groupBox_5 = QtGui.QGroupBox(self.groupBox_3) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.groupBox_5.sizePolicy().hasHeightForWidth()) + self.groupBox_5.setSizePolicy(sizePolicy) + self.groupBox_5.setMinimumSize(QtCore.QSize(0, 0)) + font = QtGui.QFont() + font.setBold(False) + font.setUnderline(False) + font.setWeight(50) + self.groupBox_5.setFont(font) + self.groupBox_5.setObjectName(_fromUtf8("groupBox_5")) + self.gridLayout_6 = QtGui.QGridLayout(self.groupBox_5) + self.gridLayout_6.setObjectName(_fromUtf8("gridLayout_6")) + self.labelMemUsage = QtGui.QLabel(self.groupBox_5) + font = QtGui.QFont() + font.setUnderline(False) + self.labelMemUsage.setFont(font) + self.labelMemUsage.setObjectName(_fromUtf8("labelMemUsage")) + self.gridLayout_6.addWidget(self.labelMemUsage, 0, 0, 1, 1) + self.labelCPUCount = QtGui.QLabel(self.groupBox_5) + self.labelCPUCount.setObjectName(_fromUtf8("labelCPUCount")) + self.gridLayout_6.addWidget(self.labelCPUCount, 3, 0, 1, 1) + self.labelMaxMem = QtGui.QLabel(self.groupBox_5) + self.labelMaxMem.setObjectName(_fromUtf8("labelMaxMem")) + self.gridLayout_6.addWidget(self.labelMaxMem, 1, 0, 1, 1) + self.label_102 = QtGui.QLabel(self.groupBox_5) + font = QtGui.QFont() + font.setUnderline(False) + self.label_102.setFont(font) + self.label_102.setObjectName(_fromUtf8("label_102")) + self.gridLayout_6.addWidget(self.label_102, 2, 0, 1, 1) + self.progressBarStatusCPU = QtGui.QProgressBar(self.groupBox_5) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.progressBarStatusCPU.sizePolicy().hasHeightForWidth()) + self.progressBarStatusCPU.setSizePolicy(sizePolicy) + self.progressBarStatusCPU.setProperty("value", 24) + self.progressBarStatusCPU.setObjectName(_fromUtf8("progressBarStatusCPU")) + self.gridLayout_6.addWidget(self.progressBarStatusCPU, 2, 1, 2, 1) + self.progressBarStatusMemory = QtGui.QProgressBar(self.groupBox_5) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.progressBarStatusMemory.sizePolicy().hasHeightForWidth()) + self.progressBarStatusMemory.setSizePolicy(sizePolicy) + self.progressBarStatusMemory.setProperty("value", 24) + self.progressBarStatusMemory.setObjectName(_fromUtf8("progressBarStatusMemory")) + self.gridLayout_6.addWidget(self.progressBarStatusMemory, 0, 1, 2, 1) + self.gridLayout_4.addWidget(self.groupBox_5, 1, 0, 1, 1) + self.verticalLayout_2.addWidget(self.groupBox_3) + self.scrollArea.setWidget(self.scrollAreaWidgetContents) + self.verticalLayout.addWidget(self.scrollArea) + self.tabWidget.addTab(self.tab, _fromUtf8("")) + self.tab_2 = QtGui.QWidget() + self.tab_2.setObjectName(_fromUtf8("tab_2")) + self.horizontalLayout_2 = QtGui.QHBoxLayout(self.tab_2) + self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) + self.framePlot = QtGui.QFrame(self.tab_2) + self.framePlot.setFrameShape(QtGui.QFrame.StyledPanel) + self.framePlot.setFrameShadow(QtGui.QFrame.Raised) + self.framePlot.setObjectName(_fromUtf8("framePlot")) + self.horizontalLayout_2.addWidget(self.framePlot) + self.tabWidget.addTab(self.tab_2, _fromUtf8("")) + self.tab_3 = QtGui.QWidget() + self.tab_3.setObjectName(_fromUtf8("tab_3")) + self.verticalLayout_3 = QtGui.QVBoxLayout(self.tab_3) + self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3")) + self.horizontalLayout_3 = QtGui.QHBoxLayout() + self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3")) + self.labelLastUpdate = QtGui.QLabel(self.tab_3) + self.labelLastUpdate.setMinimumSize(QtCore.QSize(0, 0)) + self.labelLastUpdate.setMaximumSize(QtCore.QSize(300, 16777215)) + self.labelLastUpdate.setObjectName(_fromUtf8("labelLastUpdate")) + self.horizontalLayout_3.addWidget(self.labelLastUpdate) + self.verticalLayout_3.addLayout(self.horizontalLayout_3) + self.tableWidgetProcess = QtGui.QTableWidget(self.tab_3) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(100) + sizePolicy.setVerticalStretch(100) + sizePolicy.setHeightForWidth(self.tableWidgetProcess.sizePolicy().hasHeightForWidth()) + self.tableWidgetProcess.setSizePolicy(sizePolicy) + self.tableWidgetProcess.setMinimumSize(QtCore.QSize(0, 0)) + self.tableWidgetProcess.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) + self.tableWidgetProcess.setRowCount(10) + self.tableWidgetProcess.setColumnCount(5) + self.tableWidgetProcess.setObjectName(_fromUtf8("tableWidgetProcess")) + item = QtGui.QTableWidgetItem() + self.tableWidgetProcess.setHorizontalHeaderItem(0, item) + item = QtGui.QTableWidgetItem() + self.tableWidgetProcess.setHorizontalHeaderItem(1, item) + item = QtGui.QTableWidgetItem() + self.tableWidgetProcess.setHorizontalHeaderItem(2, item) + item = QtGui.QTableWidgetItem() + self.tableWidgetProcess.setHorizontalHeaderItem(3, item) + item = QtGui.QTableWidgetItem() + self.tableWidgetProcess.setHorizontalHeaderItem(4, item) + self.tableWidgetProcess.horizontalHeader().setDefaultSectionSize(57) + self.tableWidgetProcess.horizontalHeader().setSortIndicatorShown(True) + self.tableWidgetProcess.horizontalHeader().setStretchLastSection(True) + self.tableWidgetProcess.verticalHeader().setVisible(False) + self.tableWidgetProcess.verticalHeader().setDefaultSectionSize(20) + self.tableWidgetProcess.verticalHeader().setStretchLastSection(True) + self.verticalLayout_3.addWidget(self.tableWidgetProcess) + self.horizontalLayout_7 = QtGui.QHBoxLayout() + self.horizontalLayout_7.setObjectName(_fromUtf8("horizontalLayout_7")) + spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self.horizontalLayout_7.addItem(spacerItem) + self.pushButtonUpdate = QtGui.QPushButton(self.tab_3) + self.pushButtonUpdate.setMinimumSize(QtCore.QSize(0, 0)) + self.pushButtonUpdate.setMaximumSize(QtCore.QSize(80, 15)) + font = QtGui.QFont() + font.setPointSize(7) + self.pushButtonUpdate.setFont(font) + self.pushButtonUpdate.setObjectName(_fromUtf8("pushButtonUpdate")) + self.horizontalLayout_7.addWidget(self.pushButtonUpdate) + self.verticalLayout_3.addLayout(self.horizontalLayout_7) + self.tabWidget.addTab(self.tab_3, _fromUtf8("")) + self.tab_5 = QtGui.QWidget() + self.tab_5.setObjectName(_fromUtf8("tab_5")) + self.verticalLayout_6 = QtGui.QVBoxLayout(self.tab_5) + self.verticalLayout_6.setObjectName(_fromUtf8("verticalLayout_6")) + self.groupBox = QtGui.QGroupBox(self.tab_5) + self.groupBox.setObjectName(_fromUtf8("groupBox")) + self.horizontalLayout_6 = QtGui.QHBoxLayout(self.groupBox) + self.horizontalLayout_6.setContentsMargins(-1, 3, -1, 2) + self.horizontalLayout_6.setObjectName(_fromUtf8("horizontalLayout_6")) + self.radioButtonCPU = QtGui.QRadioButton(self.groupBox) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.radioButtonCPU.sizePolicy().hasHeightForWidth()) + self.radioButtonCPU.setSizePolicy(sizePolicy) + self.radioButtonCPU.setMinimumSize(QtCore.QSize(0, 0)) + self.radioButtonCPU.setObjectName(_fromUtf8("radioButtonCPU")) + self.horizontalLayout_6.addWidget(self.radioButtonCPU) + self.radioButtonMem = QtGui.QRadioButton(self.groupBox) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.radioButtonMem.sizePolicy().hasHeightForWidth()) + self.radioButtonMem.setSizePolicy(sizePolicy) + self.radioButtonMem.setMinimumSize(QtCore.QSize(0, 0)) + self.radioButtonMem.setChecked(True) + self.radioButtonMem.setObjectName(_fromUtf8("radioButtonMem")) + self.horizontalLayout_6.addWidget(self.radioButtonMem) + self.verticalLayout_6.addWidget(self.groupBox) + self.frameBar = QtGui.QFrame(self.tab_5) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.frameBar.sizePolicy().hasHeightForWidth()) + self.frameBar.setSizePolicy(sizePolicy) + self.frameBar.setFrameShape(QtGui.QFrame.StyledPanel) + self.frameBar.setFrameShadow(QtGui.QFrame.Raised) + self.frameBar.setObjectName(_fromUtf8("frameBar")) + self.verticalLayout_6.addWidget(self.frameBar) + self.tabWidget.addTab(self.tab_5, _fromUtf8("")) + self.tab_4 = QtGui.QWidget() + self.tab_4.setObjectName(_fromUtf8("tab_4")) + self.horizontalLayout_4 = QtGui.QHBoxLayout(self.tab_4) + self.horizontalLayout_4.setObjectName(_fromUtf8("horizontalLayout_4")) + self.scrollArea_2 = QtGui.QScrollArea(self.tab_4) + self.scrollArea_2.setWidgetResizable(True) + self.scrollArea_2.setObjectName(_fromUtf8("scrollArea_2")) + self.scrollAreaWidgetContents_2 = QtGui.QWidget() + self.scrollAreaWidgetContents_2.setGeometry(QtCore.QRect(0, 0, 303, 244)) + self.scrollAreaWidgetContents_2.setObjectName(_fromUtf8("scrollAreaWidgetContents_2")) + self.horizontalLayout_5 = QtGui.QHBoxLayout(self.scrollAreaWidgetContents_2) + self.horizontalLayout_5.setObjectName(_fromUtf8("horizontalLayout_5")) + self.groupBox_6 = QtGui.QGroupBox(self.scrollAreaWidgetContents_2) + self.groupBox_6.setMinimumSize(QtCore.QSize(0, 0)) + self.groupBox_6.setObjectName(_fromUtf8("groupBox_6")) + self.verticalLayout_5 = QtGui.QVBoxLayout(self.groupBox_6) + self.verticalLayout_5.setObjectName(_fromUtf8("verticalLayout_5")) + self.radioButton60Secs = QtGui.QRadioButton(self.groupBox_6) + self.radioButton60Secs.setChecked(True) + self.radioButton60Secs.setObjectName(_fromUtf8("radioButton60Secs")) + self.verticalLayout_5.addWidget(self.radioButton60Secs) + self.radioButton300Secs = QtGui.QRadioButton(self.groupBox_6) + self.radioButton300Secs.setObjectName(_fromUtf8("radioButton300Secs")) + self.verticalLayout_5.addWidget(self.radioButton300Secs) + self.radioButton600Secs = QtGui.QRadioButton(self.groupBox_6) + self.radioButton600Secs.setObjectName(_fromUtf8("radioButton600Secs")) + self.verticalLayout_5.addWidget(self.radioButton600Secs) + self.radioButton3600Secs = QtGui.QRadioButton(self.groupBox_6) + self.radioButton3600Secs.setObjectName(_fromUtf8("radioButton3600Secs")) + self.verticalLayout_5.addWidget(self.radioButton3600Secs) + spacerItem1 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + self.verticalLayout_5.addItem(spacerItem1) + self.horizontalLayout_5.addWidget(self.groupBox_6) + self.groupBox_4 = QtGui.QGroupBox(self.scrollAreaWidgetContents_2) + self.groupBox_4.setMinimumSize(QtCore.QSize(0, 0)) + self.groupBox_4.setObjectName(_fromUtf8("groupBox_4")) + self.verticalLayout_4 = QtGui.QVBoxLayout(self.groupBox_4) + self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4")) + self.radioButton1Sec = QtGui.QRadioButton(self.groupBox_4) + self.radioButton1Sec.setObjectName(_fromUtf8("radioButton1Sec")) + self.verticalLayout_4.addWidget(self.radioButton1Sec) + self.radioButton2Secs = QtGui.QRadioButton(self.groupBox_4) + self.radioButton2Secs.setChecked(True) + self.radioButton2Secs.setObjectName(_fromUtf8("radioButton2Secs")) + self.verticalLayout_4.addWidget(self.radioButton2Secs) + self.radioButton5Secs = QtGui.QRadioButton(self.groupBox_4) + self.radioButton5Secs.setObjectName(_fromUtf8("radioButton5Secs")) + self.verticalLayout_4.addWidget(self.radioButton5Secs) + self.radioButton10Secs = QtGui.QRadioButton(self.groupBox_4) + self.radioButton10Secs.setObjectName(_fromUtf8("radioButton10Secs")) + self.verticalLayout_4.addWidget(self.radioButton10Secs) + spacerItem2 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + self.verticalLayout_4.addItem(spacerItem2) + self.horizontalLayout_5.addWidget(self.groupBox_4) + self.scrollArea_2.setWidget(self.scrollAreaWidgetContents_2) + self.horizontalLayout_4.addWidget(self.scrollArea_2) + self.tabWidget.addTab(self.tab_4, _fromUtf8("")) + self.horizontalLayout.addWidget(self.tabWidget) + + self.retranslateUi(Form) + self.tabWidget.setCurrentIndex(0) + QtCore.QMetaObject.connectSlotsByName(Form) + + def retranslateUi(self, Form): + Form.setWindowTitle(_translate("Form", "Form", None)) + self.groupBox_3.setTitle(_translate("Form", "System Info", None)) + self.labelComputerName.setText(_translate("Form", "Computer Name: ", None)) + self.labelOS.setText(_translate("Form", "Operating System:", None)) + self.labelProcFam.setText(_translate("Form", "Processor Family:", None)) + self.labelNUsers.setText(_translate("Form", "Number of Users Logged On:", None)) + self.labelUptime.setText(_translate("Form", "System Uptime: ", None)) + self.groupBox_5.setTitle(_translate("Form", "Composite System Status", None)) + self.labelMemUsage.setText(_translate("Form", "Memory Usage", None)) + self.labelCPUCount.setText(_translate("Form", "CPU count:", None)) + self.labelMaxMem.setText(_translate("Form", "Max Mem:", None)) + self.label_102.setText(_translate("Form", "Composite CPU Usage", None)) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("Form", "System", None)) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("Form", "History", None)) + self.labelLastUpdate.setText(_translate("Form", "Last Update: ", None)) + self.tableWidgetProcess.setSortingEnabled(True) + item = self.tableWidgetProcess.horizontalHeaderItem(0) + item.setText(_translate("Form", "PID", None)) + item = self.tableWidgetProcess.horizontalHeaderItem(1) + item.setText(_translate("Form", "USER", None)) + item = self.tableWidgetProcess.horizontalHeaderItem(2) + item.setText(_translate("Form", "CPU%", None)) + item = self.tableWidgetProcess.horizontalHeaderItem(3) + item.setText(_translate("Form", "MEM%", None)) + item = self.tableWidgetProcess.horizontalHeaderItem(4) + item.setText(_translate("Form", "NAME", None)) + self.pushButtonUpdate.setText(_translate("Form", "Hold Updates", None)) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("Form", "Processes", None)) + self.groupBox.setTitle(_translate("Form", "Sort", None)) + self.radioButtonCPU.setText(_translate("Form", "CPU", None)) + self.radioButtonMem.setText(_translate("Form", "Memory", None)) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_5), _translate("Form", "Users", None)) + self.groupBox_6.setTitle(_translate("Form", "Display Period", None)) + self.radioButton60Secs.setText(_translate("Form", "60 Seconds", None)) + self.radioButton300Secs.setText(_translate("Form", "300 Seconds", None)) + self.radioButton600Secs.setText(_translate("Form", "600 Seconds", None)) + self.radioButton3600Secs.setText(_translate("Form", "3600 Seconds", None)) + self.groupBox_4.setTitle(_translate("Form", "Update Rate", None)) + self.radioButton1Sec.setText(_translate("Form", "1 Second", None)) + self.radioButton2Secs.setText(_translate("Form", "2 Seconds", None)) + self.radioButton5Secs.setText(_translate("Form", "5 Seconds", None)) + self.radioButton10Secs.setText(_translate("Form", "10 Seconds", None)) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), _translate("Form", "Options", None)) + diff --git a/Code/Mantid/MantidPlot/SysMon/ui_sysmon.ui b/Code/Mantid/MantidPlot/SysMon/ui_sysmon.ui new file mode 100644 index 000000000000..2dfbc897f680 --- /dev/null +++ b/Code/Mantid/MantidPlot/SysMon/ui_sysmon.ui @@ -0,0 +1,670 @@ + + + Form + + + + 0 + 0 + 230 + 331 + + + + + 16777215 + 16777215 + + + + Form + + + + + + + 0 + 0 + + + + 0 + + + + System + + + + + + true + + + + + 0 + 0 + 320 + 293 + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + System Info + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Computer Name: + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Operating System: + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Processor Family: + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Number of Users Logged On: + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + System Uptime: + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 50 + false + false + + + + Composite System Status + + + + + + + false + + + + Memory Usage + + + + + + + CPU count: + + + + + + + Max Mem: + + + + + + + + false + + + + Composite CPU Usage + + + + + + + + 0 + 0 + + + + 24 + + + + + + + + 0 + 0 + + + + 24 + + + + + + + + + + + + + + + + + + History + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + Processes + + + + + + + + + 0 + 0 + + + + + 300 + 16777215 + + + + Last Update: + + + + + + + + + + 100 + 100 + + + + + 0 + 0 + + + + QAbstractItemView::NoEditTriggers + + + true + + + 10 + + + 5 + + + 57 + + + true + + + true + + + false + + + 20 + + + true + + + + + + + + + + + + + + PID + + + + + USER + + + + + CPU% + + + + + MEM% + + + + + NAME + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 80 + 15 + + + + + 7 + + + + Hold Updates + + + + + + + + + + Users + + + + + + Sort + + + + 3 + + + 2 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + CPU + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Memory + + + true + + + + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + Options + + + + + + true + + + + + 0 + 0 + 303 + 244 + + + + + + + + 0 + 0 + + + + Display Period + + + + + + 60 Seconds + + + true + + + + + + + 300 Seconds + + + + + + + 600 Seconds + + + + + + + 3600 Seconds + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + 0 + 0 + + + + Update Rate + + + + + + 1 Second + + + + + + + 2 Seconds + + + true + + + + + + + 5 Seconds + + + + + + + 10 Seconds + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + + + + + diff --git a/Code/Mantid/MantidPlot/SysMon/ui_sysmonMainWindow.py b/Code/Mantid/MantidPlot/SysMon/ui_sysmonMainWindow.py new file mode 100644 index 000000000000..a7c6a67caaf2 --- /dev/null +++ b/Code/Mantid/MantidPlot/SysMon/ui_sysmonMainWindow.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'ui_sysmonMainWindow.ui' +# +# Created: Wed Sep 17 15:59:14 2014 +# by: PyQt4 UI code generator 4.8.3 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + _fromUtf8 = lambda s: s + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + MainWindow.setObjectName(_fromUtf8("MainWindow")) + MainWindow.resize(427, 323) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth()) + MainWindow.setSizePolicy(sizePolicy) + MainWindow.setMinimumSize(QtCore.QSize(336, 282)) + self.centralwidget = QtGui.QWidget(MainWindow) + self.centralwidget.setObjectName(_fromUtf8("centralwidget")) + self.gridLayout = QtGui.QGridLayout(self.centralwidget) + self.gridLayout.setObjectName(_fromUtf8("gridLayout")) + MainWindow.setCentralWidget(self.centralwidget) + self.statusbar = QtGui.QStatusBar(MainWindow) + self.statusbar.setObjectName(_fromUtf8("statusbar")) + MainWindow.setStatusBar(self.statusbar) + self.menubar = QtGui.QMenuBar(MainWindow) + self.menubar.setGeometry(QtCore.QRect(0, 0, 427, 21)) + self.menubar.setObjectName(_fromUtf8("menubar")) + self.menuFile = QtGui.QMenu(self.menubar) + self.menuFile.setObjectName(_fromUtf8("menuFile")) + self.menuHelp = QtGui.QMenu(self.menubar) + self.menuHelp.setObjectName(_fromUtf8("menuHelp")) + self.menuCustom = QtGui.QMenu(self.menubar) + self.menuCustom.setObjectName(_fromUtf8("menuCustom")) + MainWindow.setMenuBar(self.menubar) + self.actionExit = QtGui.QAction(MainWindow) + self.actionExit.setObjectName(_fromUtf8("actionExit")) + self.actionAbout = QtGui.QAction(MainWindow) + self.actionAbout.setObjectName(_fromUtf8("actionAbout")) + self.actionCheck_Matlab_Licenses = QtGui.QAction(MainWindow) + self.actionCheck_Matlab_Licenses.setObjectName(_fromUtf8("actionCheck_Matlab_Licenses")) + self.menuFile.addAction(self.actionExit) + self.menuHelp.addAction(self.actionAbout) + self.menuCustom.addAction(self.actionCheck_Matlab_Licenses) + self.menubar.addAction(self.menuFile.menuAction()) + self.menubar.addAction(self.menuHelp.menuAction()) + self.menubar.addAction(self.menuCustom.menuAction()) + + self.retranslateUi(MainWindow) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + + def retranslateUi(self, MainWindow): + MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "System Monitor", None, QtGui.QApplication.UnicodeUTF8)) + self.menuFile.setTitle(QtGui.QApplication.translate("MainWindow", "File", None, QtGui.QApplication.UnicodeUTF8)) + self.menuHelp.setTitle(QtGui.QApplication.translate("MainWindow", "Help", None, QtGui.QApplication.UnicodeUTF8)) + self.menuCustom.setTitle(QtGui.QApplication.translate("MainWindow", "Custom", None, QtGui.QApplication.UnicodeUTF8)) + self.actionExit.setText(QtGui.QApplication.translate("MainWindow", "Exit", None, QtGui.QApplication.UnicodeUTF8)) + self.actionAbout.setText(QtGui.QApplication.translate("MainWindow", "About", None, QtGui.QApplication.UnicodeUTF8)) + self.actionCheck_Matlab_Licenses.setText(QtGui.QApplication.translate("MainWindow", "Check Matlab Licenses", None, QtGui.QApplication.UnicodeUTF8)) + diff --git a/Code/Mantid/MantidPlot/SysMon/ui_sysmonMainWindow.ui b/Code/Mantid/MantidPlot/SysMon/ui_sysmonMainWindow.ui new file mode 100644 index 000000000000..75196f8911a9 --- /dev/null +++ b/Code/Mantid/MantidPlot/SysMon/ui_sysmonMainWindow.ui @@ -0,0 +1,81 @@ + + + MainWindow + + + + 0 + 0 + 427 + 323 + + + + + 0 + 0 + + + + + 336 + 282 + + + + System Monitor + + + + + + + + + 0 + 0 + 427 + 21 + + + + + File + + + + + + Help + + + + + + Custom + + + + + + + + + + Exit + + + + + About + + + + + Check Matlab Licenses + + + + + + diff --git a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp index 9bef2715e1ac..191ac4fd666d 100644 --- a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp +++ b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp @@ -179,8 +179,9 @@ //Mantid #include "ScriptingWindow.h" -#include "Mantid/MantidUI.h" #include "Mantid/MantidAbout.h" +#include "Mantid/MantidDock.h" +#include "Mantid/MantidUI.h" #include "Mantid/PeakPickerTool.h" #include "Mantid/ManageCustomMenus.h" #include "Mantid/ManageInterfaceCategories.h" @@ -433,6 +434,10 @@ void ApplicationWindow::init(bool factorySettings, const QStringList& args) explorerSplitter->setSizes( splitterSizes << 45 << 45); explorerWindow->hide(); + // Other docked widgets + m_interpreterDock = new QDockWidget(this); + m_sysMonitorDock = new QDockWidget(this); + // Needs to be done after initialization of dock windows, // because we now use QDockWidget::toggleViewAction() createActions(); @@ -562,7 +567,7 @@ void ApplicationWindow::init(bool factorySettings, const QStringList& args) setScriptingLanguage(defaultScriptingLang); m_iface_script = NULL; - m_interpreterDock = new QDockWidget(this); + // -- IPython docked widget -- m_interpreterDock->setObjectName("interpreterDock"); // this is needed for QMainWindow::restoreState() m_interpreterDock->setWindowTitle("Script Interpreter"); runPythonScript("from ipython_widget import *\nw = _qti.app._getInterpreterDock()\nw.setWidget(MantidIPythonWidget())",false,true,true); @@ -572,6 +577,33 @@ void ApplicationWindow::init(bool factorySettings, const QStringList& args) addDockWidget( Qt::BottomDockWidgetArea, m_interpreterDock ); } + // Algorithms, Workspaces & SysMonitor + if ( !restoreDockWidget(mantidUI->m_exploreMantid)) + { + addDockWidget(Qt::RightDockWidgetArea, mantidUI->m_exploreMantid); + } + if ( !restoreDockWidget(mantidUI->m_exploreAlgorithms)) + { + addDockWidget(Qt::RightDockWidgetArea, mantidUI->m_exploreAlgorithms); + } + m_sysMonitorDock->setObjectName("systemMonitor"); // this is needed for QMainWindow::restoreState() + m_sysMonitorDock->setWindowTitle("System Monitor"); + runPythonScript("from SysMon import sysmon\n" + "w = sysmon.SysMon(_qti.app._getSysMonitorDock())\n" + "_qti.app._getSysMonitorDock().setWidget(w)", + false,true,true); + if ( !restoreDockWidget(m_sysMonitorDock)) + { + // Setting the max width to 300 and then to -1 later seems to + // be the only way that I found to get the dock to have a decent initial + // size but then still be resizable. + m_sysMonitorDock->setMaximumWidth(300); + addDockWidget(Qt::RightDockWidgetArea, m_sysMonitorDock); + m_sysMonitorDock->setMaximumWidth(-1); + } + tabifyDockWidget(mantidUI->m_exploreAlgorithms, m_sysMonitorDock); // first, second in that order on tabs + mantidUI->m_exploreAlgorithms->raise(); + loadCustomActions(); // Nullify catalogSearch @@ -598,13 +630,13 @@ void ApplicationWindow::init(bool factorySettings, const QStringList& args) { const Mantid::Kernel::FacilityInfo& facilityInfo = config.getFacility(facility); const Mantid::Kernel::InstrumentInfo& instrumentInfo = config.getInstrument(instrument); - g_log.information()<<"Default facility '" << facilityInfo.name() + g_log.information()<<"Default facility '" << facilityInfo.name() << "', instrument '" << instrumentInfo.name() << "'" << std::endl; } catch (Mantid::Kernel::Exception::NotFoundError&) { //failed to find the facility or instrument - g_log.error()<<"Could not find your default facility '" << facility + g_log.error()<<"Could not find your default facility '" << facility <<"' or instrument '" << instrument << "' in facilities.xml, showing please select again." << std::endl; showFirstTimeSetup(); } @@ -1198,6 +1230,10 @@ void ApplicationWindow::initMainMenu() mantidUI->addMenuItems(view); + view->insertSeparator(); + m_sysMonitorDock->toggleViewAction()->setChecked(false); + view->addAction(m_sysMonitorDock->toggleViewAction()); + view->insertSeparator(); toolbarsMenu = view->addMenu(tr("&Toolbars")); view->addAction(actionShowConfigureDialog); diff --git a/Code/Mantid/MantidPlot/src/ApplicationWindow.h b/Code/Mantid/MantidPlot/src/ApplicationWindow.h index 5de461c6140a..1b6c59ccfc72 100644 --- a/Code/Mantid/MantidPlot/src/ApplicationWindow.h +++ b/Code/Mantid/MantidPlot/src/ApplicationWindow.h @@ -238,7 +238,7 @@ public slots: void onScriptExecuteError(const QString & message, const QString & scriptName, int lineNumber); /// Runs an arbitrary lump of python code, return true/false on success/failure. bool runPythonScript(const QString & code, bool async = false, bool quiet=false, bool redirect=true); - + QList windowsList() const; QList getAllWindows() const; void updateWindowLists(MdiSubWindow *w); @@ -607,8 +607,8 @@ public slots: //! Creates a new empty multilayer plot MultiLayer* newGraph(const QString& caption = tr("Graph")); - /// Prepares MultiLayer for plotting - creates if necessary, clears, applies initial settings - MultiLayer* prepareMultiLayer(bool& isNew, MultiLayer* window, const QString& newWindowName = "Graph", + /// Prepares MultiLayer for plotting - creates if necessary, clears, applies initial settings + MultiLayer* prepareMultiLayer(bool& isNew, MultiLayer* window, const QString& newWindowName = "Graph", bool clearWindow = false); //! \name Reading from a Project File @@ -1020,12 +1020,12 @@ public slots: //@{ //! show scripting language selection dialog void showScriptingLangDialog(); - //! switches to the given scripting language; + //! switches to the given scripting language; bool setScriptingLanguage(const QString &lang); void scriptsDirPathChanged(const QString& path); //@} - + void makeToolbarsMenu(); void savetoNexusFile(); @@ -1105,7 +1105,7 @@ public slots: private slots: //! \name Initialization //@{ - + void setToolbars(); void displayToolbars(); void insertTranslatedStrings(); @@ -1321,7 +1321,7 @@ public slots: bool applyCurveStyleToMantid; ///< if true defaultCurveStyle, defaultSymbolSize are applyed to MantidCurves /// if true all errors are drawn on new plots with error bars, for a particular graph can be overridden /// form Add Error bars dialog - bool drawAllErrors; + bool drawAllErrors; QFont appFont, plot3DTitleFont, plot3DNumbersFont, plot3DAxesFont; QFont tableTextFont, tableHeaderFont, plotAxesFont, plotLegendFont, plotNumbersFont, plotTitleFont; QColor tableBkgdColor, tableTextColor, tableHeaderColor; @@ -1355,7 +1355,8 @@ public slots: QString defaultScriptingLang; QDockWidget *m_interpreterDock; - + QDockWidget *m_sysMonitorDock; + QSet allCategories() const { return m_allCategories; } private: @@ -1414,7 +1415,7 @@ public slots: QWidget* catalogSearch; QMenu *windowsMenu, *foldersMenu, *view, *graph, *fileMenu, *format, *edit, *recent, *interfaceMenu; - + QMenu *help, *plot2DMenu, *analysisMenu, *multiPeakMenu, *icat; QMenu *matrixMenu, *plot3DMenu, *plotDataMenu, *tablesDepend, *scriptingMenu; QMenu *tableMenu, *fillMenu, *normMenu, *newMenu, *exportPlotMenu, *smoothMenu, *filterMenu, *decayMenu,*saveMenu,*openMenu, *toolbarsMenu; @@ -1497,7 +1498,7 @@ public slots: QList d_user_actions; QList d_user_menus; //Mantid - + QList m_interfaceActions; /// list of mantidmatrix windows opened from project file. @@ -1516,7 +1517,7 @@ public slots: QList m_floatingWindows; // To block activating new window when a floating window is in process of resetting flags bool blockWindowActivation; - /// + /// bool m_enableQtiPlotFitting; #ifdef SHARED_MENUBAR diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidDock.cpp b/Code/Mantid/MantidPlot/src/Mantid/MantidDock.cpp index 7afd72387f57..34762962e1e0 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/MantidDock.cpp +++ b/Code/Mantid/MantidPlot/src/Mantid/MantidDock.cpp @@ -43,7 +43,6 @@ MantidDockWidget::MantidDockWidget(MantidUI *mui, ApplicationWindow *parent) : setObjectName("exploreMantid"); // this is needed for QMainWindow::restoreState() setMinimumHeight(150); setMinimumWidth(200); - parent->addDockWidget( Qt::RightDockWidgetArea, this ); QFrame *f = new QFrame(this); setWidget(f); @@ -65,13 +64,13 @@ MantidDockWidget::MantidDockWidget(MantidUI *mui, ApplicationWindow *parent) : buttonLayout->addWidget(m_sortButton); m_workspaceFilter = new MantidQt::MantidWidgets::LineEditWithClear(); - m_workspaceFilter->setPlaceholderText("Filter Workspaces"); - m_workspaceFilter->setToolTip("Type here to filter the workspaces"); + m_workspaceFilter->setPlaceholderText("Filter Workspaces"); + m_workspaceFilter->setToolTip("Type here to filter the workspaces"); connect(m_workspaceFilter, SIGNAL(textChanged(const QString&)), this, SLOT(filterWorkspaceTree(const QString&))); QVBoxLayout * layout = new QVBoxLayout(); - f->setLayout(layout); + f->setLayout(layout); layout->setSpacing(0); layout->setMargin(0); layout->addLayout(buttonLayout); @@ -189,7 +188,7 @@ void MantidDockWidget::createWorkspaceMenuActions() connect(m_showMDPlot, SIGNAL(activated()), m_mantidUI, SLOT(showMDPlot())); m_showListData = new QAction(tr("List Data"), this); - connect(m_showListData, SIGNAL(activated()), m_mantidUI, SLOT(showListData())); + connect(m_showListData, SIGNAL(activated()), m_mantidUI, SLOT(showListData())); m_showSpectrumViewer = new QAction(tr("Show Spectrum Viewer"), this); connect(m_showSpectrumViewer, SIGNAL(activated()), m_mantidUI, SLOT(showSpectrumViewer())); @@ -668,7 +667,7 @@ void MantidDockWidget::filterWorkspaceTree(const QString &text) //show all items QTreeWidgetItemIterator it(m_tree); - while (*it) + while (*it) { (*it)->setHidden(false); ++it; @@ -691,7 +690,7 @@ void MantidDockWidget::filterWorkspaceTree(const QString &text) { expanded << item->text(0); } - else + else { //expand everything that is at the top level (as we lazy load this is required) item->setExpanded(true); @@ -700,12 +699,12 @@ void MantidDockWidget::filterWorkspaceTree(const QString &text) //filter based on the string QTreeWidgetItemIterator it(m_tree,QTreeWidgetItemIterator::All); - while (*it) + while (*it) { QTreeWidgetItem *item = (*it); QVariant userData = item->data(0, Qt::UserRole); - if (!userData.isNull() ) + if (!userData.isNull() ) { Workspace_sptr workspace = userData.value(); if (workspace) @@ -756,10 +755,10 @@ void MantidDockWidget::filterWorkspaceTree(const QString &text) //make children of visible groups visible for (auto itGroup = visibleGroups.begin(); itGroup != visibleGroups.end(); ++itGroup) { - QTreeWidgetItem *group = (*itGroup); + QTreeWidgetItem *group = (*itGroup); for (int i = 0; i < group->childCount(); i++) { - QTreeWidgetItem *child = group->child(i); + QTreeWidgetItem *child = group->child(i); if (child->isHidden()) { //I was previously hidden, show me @@ -797,7 +796,7 @@ void MantidDockWidget::clickedWorkspace(QTreeWidgetItem* item, int) } void MantidDockWidget::workspaceSelected() -{ +{ QList selectedItems=m_tree->selectedItems(); if(selectedItems.isEmpty()) return; QString wsName=selectedItems[0]->text(0); @@ -820,7 +819,7 @@ void MantidDockWidget::deleteWorkspaces() if(m->workspaceName().isEmpty()) return; if(m_ads.doesExist(m->workspaceName().toStdString())) - { + { m_mantidUI->deleteWorkspace(m->workspaceName()); } return; @@ -893,7 +892,7 @@ void MantidDockWidget::saveToProgram(const QString & name) } //Check to see if mandatory information is included - if ((programKeysAndDetails.count("name") != 0) && (programKeysAndDetails.count("target") != 0) && (programKeysAndDetails.count("saveusing") != 0)) + if ((programKeysAndDetails.count("name") != 0) && (programKeysAndDetails.count("target") != 0) && (programKeysAndDetails.count("saveusing") != 0)) { std::string expTarget = Poco::Path::expand(programKeysAndDetails.find("target")->second); @@ -1057,7 +1056,7 @@ void MantidDockWidget::popupMenu(const QPoint & pos) } // Add the items that are appropriate for the type - if( MatrixWorkspace_const_sptr matrixWS = boost::dynamic_pointer_cast(ws) ) + if( MatrixWorkspace_const_sptr matrixWS = boost::dynamic_pointer_cast(ws) ) { addMatrixWorkspaceMenuItems(menu, matrixWS); } @@ -1073,7 +1072,7 @@ void MantidDockWidget::popupMenu(const QPoint & pos) { addPeaksWorkspaceMenuItems(menu, peaksWS); } - else if( boost::dynamic_pointer_cast(ws) ) + else if( boost::dynamic_pointer_cast(ws) ) { addWorkspaceGroupMenuItems(menu); } @@ -1120,16 +1119,16 @@ void MantidDockWidget::popupMenu(const QPoint & pos) connect(m_program,SIGNAL(activated()),m_programMapper,SLOT(map())); //Send name of program when clicked m_programMapper->setMapping(m_program, name); - m_saveToProgram->addAction(m_program); + m_saveToProgram->addAction(m_program); // Set first pass to false so that it doesn't set up another menu entry for all programs. firstPass = false; } - } + } } //Tell the button what to listen for and what to do once clicked (if there is anything to connect it will be set to false) - if (firstPass == false) + if (firstPass == false) connect(m_programMapper, SIGNAL(mapped(const QString &)), this, SLOT(saveToProgram(const QString &))); //Rename is valid for all workspace types @@ -1352,11 +1351,11 @@ void MantidTreeWidget::dragEnterEvent(QDragEnterEvent *de) void MantidTreeWidget::dropEvent(QDropEvent *de) { QStringList filenames; - const QMimeData *mimeData = de->mimeData(); - if (mimeData->hasUrls()) + const QMimeData *mimeData = de->mimeData(); + if (mimeData->hasUrls()) { QList urlList = mimeData->urls(); - for (int i = 0; i < urlList.size(); ++i) + for (int i = 0; i < urlList.size(); ++i) { QString fName = urlList[i].toLocalFile(); if (fName.size()>0) @@ -1367,7 +1366,7 @@ void MantidTreeWidget::dropEvent(QDropEvent *de) } de->acceptProposedAction(); - for (int i = 0; i < filenames.size(); ++i) + for (int i = 0; i < filenames.size(); ++i) { try { @@ -1382,7 +1381,7 @@ void MantidTreeWidget::dropEvent(QDropEvent *de) catch (std::runtime_error& error) { treelog.error()<<"Failed to Load the file "< > MantidTreeWidget::chooseSpectrumFromSelected() return spectrumToPlot; } - // Else, one or more workspaces + // Else, one or more workspaces MantidWSIndexDialog *dio = new MantidWSIndexDialog(m_mantidUI, 0, selectedMatrixWsNameList); dio->exec(); return dio->getPlots(); @@ -1716,7 +1715,6 @@ AlgorithmDockWidget::AlgorithmDockWidget(MantidUI *mui, ApplicationWindow *w): setObjectName("exploreAlgorithms"); // this is needed for QMainWindow::restoreState() setMinimumHeight(150); setMinimumWidth(200); - w->addDockWidget( Qt::RightDockWidgetArea, this );//*/ //Add the AlgorithmSelectorWidget m_selector = new MantidQt::MantidWidgets::AlgorithmSelectorWidget(this); @@ -1829,4 +1827,3 @@ void AlgorithmDockWidget::hideProgressBar() //-------------------- ----------------------// - diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidUI.h b/Code/Mantid/MantidPlot/src/Mantid/MantidUI.h index 5f7f9194029f..b64a7c3d45ca 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/MantidUI.h +++ b/Code/Mantid/MantidPlot/src/Mantid/MantidUI.h @@ -192,7 +192,7 @@ class MantidUI:public QObject void showAlgWidget(bool on = true); /// Plot a 1D graph for an integrated mdworkspace - MultiLayer* plotMDList(const QStringList& wsNames, const int plotAxis, + MultiLayer* plotMDList(const QStringList& wsNames, const int plotAxis, const Mantid::API::MDNormalization normalization, const bool showError, MultiLayer* plotWindow = NULL, bool clearWindow = false); @@ -239,7 +239,7 @@ class MantidUI:public QObject /// Create a table showing detector information for the given workspace and indices and optionally the data for that detector Table* createDetectorTable(const QString & wsName, const std::vector& indices, bool include_data = false); /// Create the instrument detector table from a MatrixWorkspace - Table* createDetectorTable(const QString & wsName, const Mantid::API::MatrixWorkspace_sptr & ws, + Table* createDetectorTable(const QString & wsName, const Mantid::API::MatrixWorkspace_sptr & ws, const std::vector& indices, bool include_data = false); /// Create a table of detectors from a PeaksWorkspace Table* createDetectorTable(const QString & wsName, const Mantid::API::IPeaksWorkspace_sptr & ws); @@ -253,7 +253,7 @@ class MantidUI:public QObject void renameWorkspace(QStringList = QStringList()); /** - * Set the currently used fit property browser. Is needed because e.g. Muon Analysis is using its + * Set the currently used fit property browser. Is needed because e.g. Muon Analysis is using its * own fit browser. * @param newBrowser The browser to be used. If is null, is set to default one. */ @@ -281,7 +281,7 @@ class MantidUI:public QObject */ void savedatainNexusFormat(const std::string& fileName,const std::string & wsName); - /** load data from nexus file.This method is useful + /** load data from nexus file.This method is useful when a project is opened from mantidplot */ void loaddataFromNexusFile(const std::string& wsname,const std::string& fileName,bool project=false); @@ -300,6 +300,15 @@ class MantidUI:public QObject public: + // QMainWindow needs the dock widgets to be accessible + MantidDockWidget *m_exploreMantid; // Dock window for manipulating workspaces + AlgorithmDockWidget *m_exploreAlgorithms; // Dock window for using algorithms + RemoteClusterDockWidget *m_exploreRemoteTasks; // Dock window for using remote tasks + /// Current fit property browser being used + MantidQt::MantidWidgets::FitPropertyBrowser* m_fitFunction; + /// Default fit property browser (the one docked on the left) + MantidQt::MantidWidgets::FitPropertyBrowser* m_defaultFitFunction; + signals: // These signals are to be fired from methods run in threads other than the main one @@ -463,11 +472,11 @@ class MantidUI:public QObject void handleRenameWorkspace(Mantid::API::WorkspaceRenameNotification_ptr pNf); Poco::NObserver m_renameObserver; - //handles notification send by Groupworkspaces algorithm + //handles notification send by Groupworkspaces algorithm void handleGroupWorkspaces(Mantid::API::WorkspacesGroupedNotification_ptr pNf); Poco::NObserver m_groupworkspacesObserver; - //handles notification send by UnGroupworkspaces algorithm + //handles notification send by UnGroupworkspaces algorithm void handleUnGroupWorkspace(Mantid::API::WorkspaceUnGroupingNotification_ptr pNf); Poco::NObserver m_ungroupworkspaceObserver; @@ -498,13 +507,6 @@ class MantidUI:public QObject // Private variables ApplicationWindow *m_appWindow; // QtiPlot main ApplicationWindow - MantidDockWidget *m_exploreMantid; // Dock window for manipulating workspaces - AlgorithmDockWidget *m_exploreAlgorithms; // Dock window for using algorithms - RemoteClusterDockWidget *m_exploreRemoteTasks; // Dock window for using remote tasks - /// Current fit property browser being used - MantidQt::MantidWidgets::FitPropertyBrowser* m_fitFunction; - /// Default fit property browser (the one docked on the left) - MantidQt::MantidWidgets::FitPropertyBrowser* m_defaultFitFunction; QAction *actionCopyRowToTable; QAction *actionCopyRowToGraph; diff --git a/Code/Mantid/MantidPlot/src/qti.sip b/Code/Mantid/MantidPlot/src/qti.sip index ac8ddf4dfe69..6e13fc1d2d37 100644 --- a/Code/Mantid/MantidPlot/src/qti.sip +++ b/Code/Mantid/MantidPlot/src/qti.sip @@ -1083,9 +1083,9 @@ public: %End Matrix* newMatrix(); Matrix* newMatrix(const QString&, int=32, int=32); - + TiledWindow *newTiledWindow(); - + MultiLayer *plot(const QString&) /PyName=graph/; %MethodCode sipRes = sipCpp->current_folder->graph(*a0, false); @@ -1167,6 +1167,12 @@ public: sipRes = sipCpp->m_interpreterDock; %End + // Required for setting the SysMon widget + QDockWidget _getSysMonitorDock(); +%MethodCode + sipRes = sipCpp->m_sysMonitorDock; +%End + // folders Folder *activeFolder(); %MethodCode From e59fb62ec8f1d28de3fe6d30383d20463bedaecd Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Fri, 19 Sep 2014 14:32:04 +0100 Subject: [PATCH 002/275] Add a check for the psutil package The system monitor is only made available if this package is present. Refs #9843 --- .../MantidPlot/src/ApplicationWindow.cpp | 63 +++++++++++++------ .../Mantid/MantidPlot/src/ApplicationWindow.h | 2 + 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp index 191ac4fd666d..0400d6a8ed8a 100644 --- a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp +++ b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp @@ -436,7 +436,7 @@ void ApplicationWindow::init(bool factorySettings, const QStringList& args) // Other docked widgets m_interpreterDock = new QDockWidget(this); - m_sysMonitorDock = new QDockWidget(this); + if(psutilPresent()) m_sysMonitorDock = new QDockWidget(this); // Needs to be done after initialization of dock windows, // because we now use QDockWidget::toggleViewAction() @@ -586,23 +586,26 @@ void ApplicationWindow::init(bool factorySettings, const QStringList& args) { addDockWidget(Qt::RightDockWidgetArea, mantidUI->m_exploreAlgorithms); } - m_sysMonitorDock->setObjectName("systemMonitor"); // this is needed for QMainWindow::restoreState() - m_sysMonitorDock->setWindowTitle("System Monitor"); - runPythonScript("from SysMon import sysmon\n" - "w = sysmon.SysMon(_qti.app._getSysMonitorDock())\n" - "_qti.app._getSysMonitorDock().setWidget(w)", - false,true,true); - if ( !restoreDockWidget(m_sysMonitorDock)) + if(psutilPresent()) { - // Setting the max width to 300 and then to -1 later seems to - // be the only way that I found to get the dock to have a decent initial - // size but then still be resizable. - m_sysMonitorDock->setMaximumWidth(300); - addDockWidget(Qt::RightDockWidgetArea, m_sysMonitorDock); - m_sysMonitorDock->setMaximumWidth(-1); + m_sysMonitorDock->setObjectName("systemMonitor"); // this is needed for QMainWindow::restoreState() + m_sysMonitorDock->setWindowTitle("System Monitor"); + runPythonScript("from SysMon import sysmon\n" + "w = sysmon.SysMon(_qti.app._getSysMonitorDock())\n" + "_qti.app._getSysMonitorDock().setWidget(w)", + false, true, true); + if ( !restoreDockWidget(m_sysMonitorDock)) + { + // Setting the max width to 300 and then to -1 later seems to + // be the only way that I found to get the dock to have a decent initial + // size but then still be resizable. + m_sysMonitorDock->setMaximumWidth(300); + addDockWidget(Qt::RightDockWidgetArea, m_sysMonitorDock); + m_sysMonitorDock->setMaximumWidth(-1); + } + tabifyDockWidget(mantidUI->m_exploreAlgorithms, m_sysMonitorDock); // first, second in that order on tabs + mantidUI->m_exploreAlgorithms->raise(); } - tabifyDockWidget(mantidUI->m_exploreAlgorithms, m_sysMonitorDock); // first, second in that order on tabs - mantidUI->m_exploreAlgorithms->raise(); loadCustomActions(); @@ -1230,9 +1233,12 @@ void ApplicationWindow::initMainMenu() mantidUI->addMenuItems(view); - view->insertSeparator(); - m_sysMonitorDock->toggleViewAction()->setChecked(false); - view->addAction(m_sysMonitorDock->toggleViewAction()); + if(psutilPresent()) + { + view->insertSeparator(); + m_sysMonitorDock->toggleViewAction()->setChecked(false); + view->addAction(m_sysMonitorDock->toggleViewAction()); + } view->insertSeparator(); toolbarsMenu = view->addMenu(tr("&Toolbars")); @@ -16662,6 +16668,25 @@ bool ApplicationWindow::runPythonScript(const QString & code, bool async, return success; } +/// @return True if the psuitl python module is present and importable otherwise return false +bool ApplicationWindow::psutilPresent() +{ + static bool checkPerformed(false); + static bool pkgPresent(false); + + if(!checkPerformed) + { + g_log.debug("Checking for psutil\n"); + using Mantid::Kernel::Logger; + bool verbose = g_log.is(Logger::Priority::PRIO_DEBUG); + pkgPresent = runPythonScript("import psutil", false, false, verbose); + if(pkgPresent) g_log.debug() << "Found psutil package"; + else g_log.debug() << "Unable to find psutil package"; + checkPerformed = true; + } + + return pkgPresent; +} bool ApplicationWindow::validFor2DPlot(Table *table) diff --git a/Code/Mantid/MantidPlot/src/ApplicationWindow.h b/Code/Mantid/MantidPlot/src/ApplicationWindow.h index 1b6c59ccfc72..0a4adca650d1 100644 --- a/Code/Mantid/MantidPlot/src/ApplicationWindow.h +++ b/Code/Mantid/MantidPlot/src/ApplicationWindow.h @@ -238,6 +238,8 @@ public slots: void onScriptExecuteError(const QString & message, const QString & scriptName, int lineNumber); /// Runs an arbitrary lump of python code, return true/false on success/failure. bool runPythonScript(const QString & code, bool async = false, bool quiet=false, bool redirect=true); + /// Checks for the presence of the Python psutil module for the system monitor widget + bool psutilPresent(); QList windowsList() const; QList getAllWindows() const; From 666e9bfbb3064c58f1623b329849936cd5899c87 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Fri, 19 Sep 2014 17:28:40 +0100 Subject: [PATCH 003/275] Fix order in which psutil check is applied. The scripting environment needs to have been started before we can check for the package. Refs #9843 --- .../MantidPlot/src/ApplicationWindow.cpp | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp index 0400d6a8ed8a..a643d4b13020 100644 --- a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp +++ b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp @@ -436,7 +436,7 @@ void ApplicationWindow::init(bool factorySettings, const QStringList& args) // Other docked widgets m_interpreterDock = new QDockWidget(this); - if(psutilPresent()) m_sysMonitorDock = new QDockWidget(this); + m_sysMonitorDock = new QDockWidget(this); // Needs to be done after initialization of dock windows, // because we now use QDockWidget::toggleViewAction() @@ -605,6 +605,24 @@ void ApplicationWindow::init(bool factorySettings, const QStringList& args) } tabifyDockWidget(mantidUI->m_exploreAlgorithms, m_sysMonitorDock); // first, second in that order on tabs mantidUI->m_exploreAlgorithms->raise(); + + } + else + { + // Remove menu item + auto actions = view->actions(); + auto itr = actions.constBegin(); + auto iend = actions.constEnd(); + for(; itr != iend; ++itr) + { + if(*itr == m_sysMonitorDock->toggleViewAction()) break; + } + // Move back for the separator + if(itr != actions.constBegin()) --itr; + view->removeAction(*itr); + ++itr; + view->removeAction(*itr); + delete m_sysMonitorDock; } loadCustomActions(); @@ -1233,12 +1251,11 @@ void ApplicationWindow::initMainMenu() mantidUI->addMenuItems(view); - if(psutilPresent()) - { - view->insertSeparator(); - m_sysMonitorDock->toggleViewAction()->setChecked(false); - view->addAction(m_sysMonitorDock->toggleViewAction()); - } + // System monitor (might get removed later after check) + view->insertSeparator(); + m_sysMonitorDock->toggleViewAction()->setChecked(false); + view->addAction(m_sysMonitorDock->toggleViewAction()); + view->insertSeparator(); toolbarsMenu = view->addMenu(tr("&Toolbars")); From 04c574420718614e4d85a25ad4db05f63582f685 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Tue, 23 Sep 2014 07:55:29 +0100 Subject: [PATCH 004/275] Install the SysMon utility to include it in the package Refs #9843 --- Code/Mantid/MantidPlot/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Code/Mantid/MantidPlot/CMakeLists.txt b/Code/Mantid/MantidPlot/CMakeLists.txt index 20ffa62bc0a5..731f74d95fad 100644 --- a/Code/Mantid/MantidPlot/CMakeLists.txt +++ b/Code/Mantid/MantidPlot/CMakeLists.txt @@ -847,7 +847,7 @@ copy_python_files_to_dir ( "${IPY_FILES}" ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/ipython_widget IPYTHON_INSTALL_FILES ) -# IPython scripts +# SysMon scripts set( SYSMON_FILES __init__.py config.py @@ -1005,6 +1005,9 @@ endforeach() foreach(PY_FILE ${IPY_FILES} ) install ( FILES ipython_widget/${PY_FILE} DESTINATION ${BIN_DIR}/ipython_widget ) endforeach() +foreach(PY_FILE ${SYSMON_FILES} ) + install ( FILES SysMon/${PY_FILE} DESTINATION ${BIN_DIR}/SysMon ) +endforeach() if ( APPLE ) configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/FixBundle.cmake.in From f18d79b8ff43f0709bc4e5d2abe99f9cdc463cbd Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Tue, 23 Sep 2014 16:06:24 +0100 Subject: [PATCH 005/275] Don't use negative sizes in the max width settings. Refs #9843 --- Code/Mantid/MantidPlot/src/ApplicationWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp index a643d4b13020..cb639704e6af 100644 --- a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp +++ b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp @@ -601,7 +601,7 @@ void ApplicationWindow::init(bool factorySettings, const QStringList& args) // size but then still be resizable. m_sysMonitorDock->setMaximumWidth(300); addDockWidget(Qt::RightDockWidgetArea, m_sysMonitorDock); - m_sysMonitorDock->setMaximumWidth(-1); + m_sysMonitorDock->setMaximumWidth(QWIDGETSIZE_MAX); // reset it } tabifyDockWidget(mantidUI->m_exploreAlgorithms, m_sysMonitorDock); // first, second in that order on tabs mantidUI->m_exploreAlgorithms->raise(); From 68c021ccbf466abf4eddbc5b0caf34cd622c8579 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Wed, 1 Oct 2014 15:46:51 +0100 Subject: [PATCH 006/275] Updating to SysMon v0.23 Refs #9843 --- Code/Mantid/MantidPlot/SysMon/config.py | 12 +- Code/Mantid/MantidPlot/SysMon/sysmon.py | 42 ++- Code/Mantid/MantidPlot/SysMon/sysmon_tools.py | 251 ++++++++++++------ Code/Mantid/MantidPlot/SysMon/ui_sysmon.py | 157 +++++------ Code/Mantid/MantidPlot/SysMon/ui_sysmon.ui | 93 ++++--- 5 files changed, 345 insertions(+), 210 deletions(-) diff --git a/Code/Mantid/MantidPlot/SysMon/config.py b/Code/Mantid/MantidPlot/SysMon/config.py index 508ba68e711b..f52dcf1e520e 100644 --- a/Code/Mantid/MantidPlot/SysMon/config.py +++ b/Code/Mantid/MantidPlot/SysMon/config.py @@ -1,7 +1,7 @@ #global definitions for constants and variables -#Tab indices: +#Tab indices - based upon the order of the tabs as built via Qt and these must be the same as the Qt GUI. SYST_TAB=0 HIST_TAB=1 PROC_TAB=2 @@ -10,7 +10,11 @@ #Global Variables: psutilVer=0 #flag for the version of psutil being used -nompl=False +nompl=False #Flag to indicate if using matplotlib - True, then do not use plots, False, then try to use matplotlib plots mplLoaded=False #flag for matplotlib loading -custom=False -matlabchk='lmstat -S -c 27010@licenses1.sns.gov' \ No newline at end of file +custom=False #flag to indicate if the custom interface is to be used (usually not) +matlabchk='lmstat -S -c 27010@licenses1.sns.gov' #text command to status the Matlab license server (only for custom mode with SysMon.pyw) +basefontsize=9 #basic font size when GUI is at minimum size +fscl=0.5 #scale factor for font size change with GUI resizing - less than one, font size slower than GUI size change, and greater than one font size faster than GUI size change +pltFont=9 #initial font size for matplotlib plots +linewidth=1 #initial line widths for matplotlib plots \ No newline at end of file diff --git a/Code/Mantid/MantidPlot/SysMon/sysmon.py b/Code/Mantid/MantidPlot/SysMon/sysmon.py index 1f6ce7662002..d62254f7cff0 100644 --- a/Code/Mantid/MantidPlot/SysMon/sysmon.py +++ b/Code/Mantid/MantidPlot/SysMon/sysmon.py @@ -1,5 +1,5 @@ - + import sys, os, time import re import config #application constants and variables @@ -32,6 +32,7 @@ def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.ui = Ui_Form() #defined from ui_sysmon.py self.ui.setupUi(self) + self.ui.parent=parent self.ui.progressBarStatusMemory.setStyleSheet("QProgressBar {width: 25px;border: 1px solid black; border-radius: 3px; background: white;text-align: center;padding: 0px;}" +"QProgressBar::chunk:horizontal {background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #00CCEE, stop: 0.3 #00DDEE, stop: 0.6 #00EEEE, stop:1 #00FFEE);}") self.ui.progressBarStatusCPU.setStyleSheet("QProgressBar {width: 25px;border: 1px solid black; border-radius: 3px; background: white;text-align: center;padding: 0px;}" @@ -39,7 +40,7 @@ def __init__(self, parent=None): #setup timer to enable periodic events such as status update checks self.ctimer = QtCore.QTimer() - self.ctimer.start(2000) #time in mSec - set repetitive timer of 2 seconds + self.ctimer.start(2000) #time in mSec - set default update timer cycle to 2 seconds QtCore.QObject.connect(self.ctimer, QtCore.SIGNAL("timeout()"), self.constantUpdate) #update rate actions @@ -130,13 +131,15 @@ def __init__(self, parent=None): self.ui.cpu=np.zeros(Nsamples+1) self.ui.mem=np.zeros(Nsamples+1) self.ui.dt=[None]*(Nsamples+1) + self.ui.cpuMe=np.zeros(Nsamples+1) + self.ui.memMe=np.zeros(Nsamples+1) self.ui.tabWidget.setTabsClosable(False) #disable the ability to close tabs once state of matplotlib is handled #initialize the process table self.doUpdates=True #flag for updating the process tab table updateProcTable(self,config) - + #upon initialization completion, set System tab (first tab on left) as the visible tab self.ui.tabWidget.setCurrentIndex(config.SYST_TAB) @@ -151,6 +154,8 @@ def update1Sec(self): #clear persistent arrays when update rate changed self.ui.cpu=self.ui.cpu*0 self.ui.mem=self.ui.mem*0 + self.ui.cpuMe=self.ui.cpuMe*0 + self.ui.memMe=self.ui.memMe*0 self.ui.dt=[None]*self.ui.Nsamples def update2Sec(self): @@ -160,6 +165,8 @@ def update2Sec(self): #clear persistent arrays when update rate changed self.ui.cpu=self.ui.cpu*0 self.ui.mem=self.ui.mem*0 + self.ui.cpuMe=self.ui.cpuMe*0 + self.ui.memMe=self.ui.memMe*0 self.ui.dt=[None]*self.ui.Nsamples def update5Sec(self): @@ -169,6 +176,8 @@ def update5Sec(self): #clear persistent arrays when update rate changed self.ui.cpu=self.ui.cpu*0 self.ui.mem=self.ui.mem*0 + self.ui.cpuMe=self.ui.cpuMe*0 + self.ui.memMe=self.ui.memMe*0 self.ui.dt=[None]*self.ui.Nsamples def update10Sec(self): @@ -178,6 +187,8 @@ def update10Sec(self): #clear persistent arrays when update rate changed self.ui.cpu=self.ui.cpu*0 self.ui.mem=self.ui.mem*0 + self.ui.cpuMe=self.ui.cpuMe*0 + self.ui.memMe=self.ui.memMe*0 self.ui.dt=[None]*self.ui.Nsamples def update60Duration(self): @@ -203,11 +214,26 @@ def resizeEvent(self,resizeEvent): print "resizing" sz=self.ui.tableWidgetProcess.size() w=sz.width() - self.ui.tableWidgetProcess.setColumnWidth(0,3*w/20) - self.ui.tableWidgetProcess.setColumnWidth(1,5*w/20) - self.ui.tableWidgetProcess.setColumnWidth(2,3*w/20) - self.ui.tableWidgetProcess.setColumnWidth(3,3*w/20) - self.ui.tableWidgetProcess.setColumnWidth(4,6*w/20) + wmin=self.ui.parent.minimumSize().width() #establish minimum table size based upon parent widget minimum size + if w < wmin: + w=wmin + #now use widget width to determine process table column width + self.ui.tableWidgetProcess.setColumnWidth(0,3.5*w/20) #PID + self.ui.tableWidgetProcess.setColumnWidth(1,4*w/20) #User + self.ui.tableWidgetProcess.setColumnWidth(2,3.5*w/20) #CPU% + self.ui.tableWidgetProcess.setColumnWidth(3,3.5*w/20) #MEM% + self.ui.tableWidgetProcess.setColumnWidth(4,5.5*w/20) #Name + + #check size of GUI to determine the size of font to use. + minSz=self.ui.parent.minimumSize().width() #establish minimum table size based upon parent widget minimum size + curSz=self.ui.parent.size().width() + #print "current size: ",curSz," type: ",type(curSz)," min size: ",minSz," type: ",type(minSz) + fsize=max([int(config.basefontsize*float(curSz)/float(minSz)*config.fscl),config.basefontsize]) + #print "Font Size: ",fsize + config.pltFont=fsize + + #adapt plot line width to GUI size change + config.linewidth=min([max([int(float(curSz)/float(minSz)),1]),3]) def removeMPLTabs(self): #In case matplotlib not available, remove tabs requiring this diff --git a/Code/Mantid/MantidPlot/SysMon/sysmon_tools.py b/Code/Mantid/MantidPlot/SysMon/sysmon_tools.py index 2e8d9eabb004..0fe4e1f87ad7 100644 --- a/Code/Mantid/MantidPlot/SysMon/sysmon_tools.py +++ b/Code/Mantid/MantidPlot/SysMon/sysmon_tools.py @@ -3,6 +3,8 @@ import datetime import numpy as np import config +import math +import getpass #check if command line flag --nompl set to disable matplotlib if not(config.nompl): @@ -31,8 +33,24 @@ def constantUpdateActor(self,config): #update global variables #mode to show status in percentage + if self.update < 3: + #use averaging if using faster update rates + Navg=1 + else: + #Don't need averaging in longer acquisition cases + Navg=1 + busy_avg=0 cpu_stats = psutil.cpu_times_percent(interval=0,percpu=False) #syntax seems to be same for psutil versions 1 and 2 - percentcpubusy = 100.0 - cpu_stats.idle + + tmpsum=cpu_stats.system+cpu_stats.user + if sum(self.ui.cpu[0:Navg-2+1]) == 0: + #avoid initial zeros in the array pulling down the average - just use the value measured in this case. + busy_avg=tmpsum + else: + #case to average + busy_avg=(tmpsum+sum(self.ui.cpu[0:Navg-2+1]))/Navg + + percentcpubusy = busy_avg self.ui.progressBarStatusCPU.setValue(round(percentcpubusy)) percentmembusy=psutil.virtual_memory().percent self.ui.progressBarStatusMemory.setValue(round(percentmembusy)) @@ -40,24 +58,13 @@ def constantUpdateActor(self,config): self.ui.Ncpus=Ncpus totalcpustr='CPU Count: '+str(Ncpus) # print "Total CPU str: ",totalcpustr - self.ui.labelCPUCount.setText(totalcpustr) + self.ui.labelCPUCount.setText(totalcpustr+' - CPU Utilization:') totalmem=int(round(float(psutil.virtual_memory().total)/(1024*1024*1024))) #psutil syntax OK for both versions # print "Total Mem: ",totalmem - self.ui.labelMemUsage.setText('Memory Usage: '+str(totalmem*percentmembusy/100)+' GB') self.ui.totalmem=totalmem - totalmemstr='Max Mem: '+str(totalmem)+' GB' + totalmemstr=str(totalmem)+' GB' + self.ui.labelMemUsage.setText('Memory Usage: '+str(totalmem*percentmembusy/100)+' GB of '+totalmemstr) # print "Total Mem str: ",totalmemstr - self.ui.labelMaxMem.setText(totalmemstr) -# print "** config.mplLoaded: ",config.mplLoaded - - if config.mplLoaded: - #update first position with most recent value overwriting oldest value which has been shifted to first position - self.ui.cpu=np.roll(self.ui.cpu,1) - self.ui.cpu[0]=percentcpubusy - self.ui.mem=np.roll(self.ui.mem,1) - self.ui.mem[0]=percentmembusy - # self.ui.dt=np.roll(self.ui.dt,1) - # self.ui.dt[0]=datetime.datetime.now() # update system tab if self.ui.tabWidget.currentIndex() == config.SYST_TAB: @@ -78,13 +85,55 @@ def constantUpdateActor(self,config): uusers=set(lst) Nuusers=len(uusers) self.ui.labelNUsers.setText("Number of Users Logged On: "+str(Nuusers)) - + + #determine "Me" user CPU and memory statistics + Me=getpass.getuser() + cpupctMe=0 + memValMe=0 + cpupctTot=0 + memValTot=0 + for proc in psutil.process_iter(): + try: + #check if process still exists, if so, update dictionaries + cpupct=proc.get_cpu_percent(interval=0) if config.psutilVer == 1 else proc.cpu_percent(interval=0) + memVal=proc.get_memory_percent() if config.psutilVer == 1 else proc.memory_percent() + + try: + #some processes give permission denied when getting the name, if so, fail out gracefully using this try. + if config.psutilVer == 1: + uname=proc.username + else: + uname=proc.username() + #print "proc.username: ",uname," type: ",type(uname)," Me: ",Me," type: ",type(Me) + except: + uname='' + except: + pass #skip process - case where process no longer exists + cpupctTot+=cpupct + memValTot+=memVal + #print "uname: ",uname," Me: ",Me + #note that on Windows systems that getpass.getuser() does not return the same base username as proc.username, so check for the smaller + if Me in uname: + cpupctMe+=cpupct + memValMe+=memVal + #print "cpupctMe: ",cpupctMe," memValMe: ",memValMe + if config.mplLoaded: + #update first position with most recent value overwriting oldest value which has been shifted to first position + self.ui.cpu=np.roll(self.ui.cpu,1) + self.ui.cpu[0]=percentcpubusy #percentcpubusy seems to agree better with system System Monitor than cpupctTot/Ncpus + self.ui.mem=np.roll(self.ui.mem,1) + self.ui.mem[0]=percentmembusy + self.ui.cpuMe=np.roll(self.ui.cpuMe,1) + self.ui.cpuMe[0]=cpupctMe/(Ncpus) + self.ui.memMe=np.roll(self.ui.memMe,1) + self.ui.memMe[0]=memValMe + #update the history plot if self.ui.tabWidget.currentIndex() == config.HIST_TAB: #only update history plot if tab is active font = {'family' : 'sans-serif', 'weight' : 'bold', - 'size' : 10} + 'size' : config.pltFont+1} matplotlib.rc('font', **font) xtime=range(0,self.ui.Nsamples+1,self.update) @@ -93,10 +142,13 @@ def constantUpdateActor(self,config): plt.figure(self.ui.figure.number) #make plot figure active plt.clf() #clear figure each time for rolling updates to show - plt.plot(xtime[0:Npts+1],self.ui.cpu[0:Npts+1],color='Blue',label='CPU Busy') - plt.plot(xtime[0:Npts+1],self.ui.mem[0:Npts+1],color='Green',label='Mem Busy') - plt.title('Composite CPU and Memory Activity',fontsize=10,fontweight='bold') - plt.ylabel('% Busy',fontsize=9.5,fontweight='bold') + plt.plot(xtime[0:Npts+1],self.ui.cpu[0:Npts+1],color='Blue',label='CPU: All',linewidth=config.linewidth) + plt.plot(xtime[0:Npts+1],self.ui.mem[0:Npts+1],color='Green',label='Mem: All',linewidth=config.linewidth) + plt.plot(xtime[0:Npts+1],self.ui.cpuMe[0:Npts+1],color='red',label='CPU: '+Me,linewidth=config.linewidth) + plt.plot(xtime[0:Npts+1],self.ui.memMe[0:Npts+1],color='cyan',label='Mem: '+Me,linewidth=config.linewidth) + + plt.title('Composite CPU and Memory Activity',fontsize=config.pltFont+1,fontweight='bold') + plt.ylabel('% Used',fontsize=config.pltFont+0.5,fontweight='bold') if self.update == 1: xlab="Seconds with 1 Second Updates" @@ -106,8 +158,9 @@ def constantUpdateActor(self,config): xlab="Seconds with 5 Second Updates" elif self.update == 10: xlab="Seconds with 10 Second Updates" - plt.xlabel(xlab,fontsize=9.5,fontweight='bold') - plt.legend(loc="upper right",prop={'size':9}) + plt.xlabel(xlab,fontsize=config.pltFont+0.5,fontweight='bold') + plt.legend(loc="upper right",prop={'size':config.pltFont}) + plt.xlim([0,Ndur]) self.ui.canvas.draw() @@ -159,17 +212,21 @@ def updateProcTable(self,config): #fill the dictionaries - seems to need to be done faster than within loop which also fills the table...not sure why... for proc in psutil.process_iter(): - cpupct=proc.get_cpu_percent(interval=0) if config.psutilVer == 1 else proc.cpu_percent(interval=0) - memVal=float(int(float(proc.get_memory_percent())*100.0))/100.0 if config.psutilVer == 1 else float(int(float(proc.memory_percent())*100.0))/100.0 try: - #don't update dictionaries if name gives an access denied error when checking process name - pname=proc.name if config.psutilVer == 1 else proc.name() - d_user.update({proc.pid:proc.username}) if config.psutilVer == 1 else d_user.update({proc.pid:proc.username()}) - d_cpu.update({proc.pid:cpupct}) - d_mem.update({proc.pid:memVal}) - d_name.update({proc.pid:pname}) + #check if process still exists, if so, update dictionaries + cpupct=proc.get_cpu_percent(interval=0) if config.psutilVer == 1 else proc.cpu_percent(interval=0) + memVal=float(int(float(proc.get_memory_percent())*100.0))/100.0 if config.psutilVer == 1 else float(int(float(proc.memory_percent())*100.0))/100.0 + try: + #don't update dictionaries if name gives an access denied error when checking process name + pname=proc.name if config.psutilVer == 1 else proc.name() + d_user.update({proc.pid:proc.username}) if config.psutilVer == 1 else d_user.update({proc.pid:proc.username()}) + d_cpu.update({proc.pid:cpupct}) + d_mem.update({proc.pid:memVal}) + d_name.update({proc.pid:pname}) + except: + pass #place holder except: - pass #place holder + pass #skip this process - case where it no longer exists #now fill the table for display for proc in d_user.keys(): @@ -207,10 +264,10 @@ def updateProcTable(self,config): self.ui.labelLastUpdate.setText("Last Update: "+str(datetime.datetime.now())) def updateUserChart(self,config): - + font = {'family' : 'sans-serif', 'weight' : 'bold', - 'size' : 9} + 'size' : config.pltFont} matplotlib.rc('font', **font) @@ -220,7 +277,7 @@ def updateUserChart(self,config): plt.clf() plt.cla() # f.gca().cla() - + plt.subplot(121) #divide plot area into two: plot on left and legend on right #create empty dictionaries to be used by the process table d_user={} d_cpu={} @@ -228,18 +285,24 @@ def updateUserChart(self,config): d_name={} #fill the dictionaries - seems to need to be done faster than within loop which also fills the table...not sure why... for proc in psutil.process_iter(): - cpupct=proc.get_cpu_percent(interval=0) if config.psutilVer == 1 else proc.cpu_percent(interval=0) - memVal=float(int(float(proc.get_memory_percent())*100.0))/100.0 if config.psutilVer == 1 else float(int(float(proc.memory_percent())*100.0))/100.0 try: - #don't update dictionaries if name gives an access denied error when checking process name - pname=proc.name if config.psutilVer == 1 else proc.name() - d_user.update({proc.pid:proc.username}) if config.psutilVer == 1 else d_user.update({proc.pid:proc.username()}) - d_cpu.update({proc.pid:cpupct}) - d_mem.update({proc.pid:memVal}) - d_name.update({proc.pid:pname}) + #check if process still exists, if so, update dictionaries + cpupct=proc.get_cpu_percent(interval=0) if config.psutilVer == 1 else proc.cpu_percent(interval=0) + memVal=float(int(float(proc.get_memory_percent())*100.0))/100.0 if config.psutilVer == 1 else float(int(float(proc.memory_percent())*100.0))/100.0 + try: + #don't update dictionaries if name gives an access denied error when checking process name + pname=proc.name if config.psutilVer == 1 else proc.name() + d_user.update({proc.pid:proc.username}) if config.psutilVer == 1 else d_user.update({proc.pid:proc.username()}) + d_cpu.update({proc.pid:cpupct}) + d_mem.update({proc.pid:memVal}) + d_name.update({proc.pid:pname}) + except: + #print "access denied" + pass #place holder except: - pass #place holder - + #print "skipped process" + pass #skip this process as it no longer exists + #print "** Total Mem Used: ",sum(d_mem.values()) users=d_user.values() users_unique=list(set(users)) #use set() to find unique users then convert the resulting set to a list via list() Nusers=len(users_unique) @@ -274,6 +337,8 @@ def updateUserChart(self,config): sortBy='cpu' elif self.ui.radioButtonMem.isChecked(): sortBy='mem' + elif self.ui.radioButtonMax.isChecked(): + sortBy='max' else: print "invalid radio button selection - using CPU sort as default" sortBy='cpu' @@ -283,6 +348,14 @@ def updateUserChart(self,config): indx=sorted(range(len(cpu_by_users_lst)), key=cpu_by_users_lst.__getitem__,reverse=True) elif sortBy=='mem': indx=sorted(range(len(mem_by_users_lst)), key=mem_by_users_lst.__getitem__,reverse=True) + elif sortBy=='max': + #determine if cpu or mem is larger + if sum(cpu_by_users_lst) > sum(mem_by_users_lst): + #case where cpu usage is larger value + indx=sorted(range(len(cpu_by_users_lst)), key=cpu_by_users_lst.__getitem__,reverse=True) + else: + #case where mem usage is larger + indx=sorted(range(len(mem_by_users_lst)), key=mem_by_users_lst.__getitem__,reverse=True) else: print 'Incorrect sort parameter' #sort lists @@ -294,90 +367,120 @@ def updateUserChart(self,config): if Nusers > Nmax: #replace the Nmaxth - 1 element with the total of the values from index Nmax - 1 to the end of the list cpu_by_users_sorted[Nmax-1]=sum(cpu_by_users_sorted[Nmax-1:]) - mem_remaining=sum(mem_by_users_sorted[Nmax-1:]) + mem_by_users_sorted[Nmax-1]=sum(mem_by_users_sorted[Nmax-1:]) users_unique_sorted[Nmax-1]='Remaining' Nshow=Nmax else: Nshow=Nusers if min(cpu_by_users_sorted) < 0: - print " *** cp_by_users_sorted has values less than zero" + print " *** cpu_by_users_sorted has values less than zero - should not occur, please check" print cpu_by_users_sorted print " ***" if min(mem_by_users_sorted) < 0: - print " *** mem_by_users_sorted has values less than zero" + print " *** mem_by_users_sorted has values less than zero - should not occur, please check" print mem_by_users_sorted print " ***" #range check the values of the sorted lists - may not be necessary, just being cautious... tst=np.array(cpu_by_users_sorted)<0 #need an array for summing - indx=cpu_by_users_sorted<0 #need bool list for indexing + indx=list(np.array(cpu_by_users_sorted)<0) #need bool list for indexing + #check if any users have less than zero CPU usage and set usage to 0 for these users if sum(tst) > 0: print "cpu_by_users < 0: ",sum(indx) - cpu_by_users_sorted[indx]=0 - tst=np.array(cpu_by_users_sorted)>self.ui.Ncpus*100 - indx=cpu_by_users_sorted>self.ui.Ncpus*100 + cpu_by_users_sorted=[0 if x<0 else x for x in cpu_by_users_sorted] + tst=np.array(cpu_by_users_sorted)>(self.ui.Ncpus*100) + indx=list(np.array(cpu_by_users_sorted)>self.ui.Ncpus*100) + #check if any users have CPU usage greater than possible number of CPUs and set usage to max CPU usage for those users if sum(tst) > 0: print "cpu_by_users > Ncpus*100: ",sum(indx) - cpu_by_users_sorted[indx]=self.ui.Ncpus*100 + cpu_by_users_sorted=[self.ui.Ncpus*100 if x>self.ui.Ncpus*100 else x for x in cpu_by_users_sorted] tst=np.array(mem_by_users_sorted)<0 - indx=mem_by_users_sorted<0 + indx=list(np.array(mem_by_users_sorted)<0) + #check if any users have less than zero memory usage and set these users to zero usage if sum(tst) > 0: print "mem_by_users < 0: ",sum(indx) - mem_by_users_sorted[indx]=0 + mem_by_users_sorted=[0 if x<0 else x for x in mem_by_users_sorted] tst=np.array(mem_by_users_sorted)>self.ui.totalmem - indx=mem_by_users_sorted>self.ui.totalmem + indx=np.array(mem_by_users_sorted)>self.ui.totalmem + #check if any users have memory usage greater than the total system memory - should never happen... if sum(tst) > 0: - print "mem_by_users > totalmem: ",sum(indx) - mem_by_users_sorted[indx]=self.ui.totalmem + #if true, then need to adjust maximum usage for these users to the total memory possible + #print "mem_by_users > totalmem: ",sum(indx)," indx: ",indx," mem_by_users: ",mem_by_users_sorted + mem_by_users_sorted=[self.ui.totalmem if x>self.ui.totalmem else x for x in mem_by_users_sorted] p=[] #list to contain plot objects for use by the legend ind=np.arange(2) - - + #print "**************" + #print mem_by_users_sorted[0:Nshow] for u in range(Nshow): if u == 0: p.append(plt.bar(ind,(cpu_by_users_sorted[u],mem_by_users_sorted[u]),width,bottom=(0,0),color=colors[u])) else: p.append(plt.bar(ind,(cpu_by_users_sorted[u],mem_by_users_sorted[u]),width,bottom=(sum(cpu_by_users_sorted[0:u]),sum(mem_by_users_sorted[0:u])),color=colors[u])) - plt.title('CPU and Memory Usage by User',fontsize=10,fontweight='bold') + plt.title('Usage by User',fontsize=config.pltFont+1,fontweight='bold') #remove default yaxis ticks then redraw them via ax1 and ax2 below frame=plt.gca() frame.axes.get_yaxis().set_ticks([]) - plt.xticks(np.arange(2)+width/2.,('CPU','Mem'),fontsize=9,fontweight='bold') - ymaxCPU=round(int((sum(cpu_by_users_sorted[0:Nshow])+100)/100)*100) - ymaxMEM=round(int((sum(mem_by_users_sorted[0:Nshow])+100)/100)*100) - ymax=max([ymaxCPU,ymaxMEM,100]) -# plt.ylim([0,ymax]) + plt.xticks(np.arange(2)+width/2.,('CPU','Mem'),fontsize=config.pltFont,fontweight='bold') + ymaxCPU=int((sum(cpu_by_users_sorted)+100)/100)*100 #range ymaxCPU to nearest 100% + ymaxMEM=int(round(sum(mem_by_users_sorted)+10))/10*10 #range ymaxMEM to nearest 10% + + ymaxMAX=max([ymaxCPU,ymaxMEM,100]) + + if sortBy == 'cpu': + ymax=max([ymaxCPU,10]) + auto=False + elif sortBy == 'mem': + ymax=max([ymaxMEM,10]) + auto=False + elif sortBy == 'max': + ymax=max([ymaxMAX,10]) + auto=True +# print 'ymaxCPU: ',ymaxCPU,' ymaxMEM: ',ymaxMEM,' ymaxMAX: ',ymaxMAX,' ymax: ',ymax,' sum(mem_by_users_sorted): ',sum(mem_by_users_sorted) + plt.ylim(0,ymax,auto=auto) + + #compute composite % - ylab=np.arange(6)/5.0*float(ymax)/float(self.ui.Ncpus) - ylab=ylab*10 + sumCPU=sum(cpu_by_users_sorted) + ylab=np.arange(5)/4.0*float(sumCPU)/float(self.ui.Ncpus) + scl=float(ymax)/float(sumCPU) + ylab=ylab*100*scl tmp=ylab.astype('int') tmp1=tmp.astype('float') - tmp1=tmp1/10 + tmp1=tmp1/100 ylab1=tmp1 ax1=plt.twinx() - ax1.set_ylabel('Composite CPU Percent',fontsize=9,fontweight='bold') + ax1.set_ylabel('Composite CPU Percent',fontsize=config.pltFont,fontweight='bold') ax1.yaxis.set_ticks_position('left') ax1.yaxis.set_label_position('left') + ax1.set_ybound(lower=0,upper=max(ylab1)) ax1.set_yticks(ylab1) +# print 'ylab1: ',ylab1 + + #place warnings if MEM or CPU go out of range + if ymax < ymaxCPU: + plt.text(2.7,0.0,'CPU Above Axis',color='red') + if ymax < ymaxMEM: + plt.text(2.7,0.0,'MEM Above Axis',color='green') + usersLegend=users_unique_sorted[0:Nshow] #reverse legend print order to have legend correspond with the order data are placed in the bar chart usersLegend.reverse() p.reverse() - plt.legend(p,usersLegend) - - + #place legend outside of plot to the right + plt.legend(p,usersLegend,bbox_to_anchor=(1.45, 1.1), loc="upper left", borderaxespad=0.1,fontsize=config.pltFont-0.5,title='Users') + #place second y axis label on plot ylab2=np.arange(5)/4.0*float(ymax) ax2=plt.twinx() - ax2.set_ylabel('Percent',fontsize=9,fontweight='bold') + ax2.set_ylabel('Percent',fontsize=config.pltFont,fontweight='bold',position=(0.9,0.5)) ax2.set_yticks(ylab2) #ax2.set_yticks(ylab2) ax2.yaxis.set_ticks_position('right') diff --git a/Code/Mantid/MantidPlot/SysMon/ui_sysmon.py b/Code/Mantid/MantidPlot/SysMon/ui_sysmon.py index cb543a389d72..93cfffe0752b 100644 --- a/Code/Mantid/MantidPlot/SysMon/ui_sysmon.py +++ b/Code/Mantid/MantidPlot/SysMon/ui_sysmon.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file '../../Code/Mantid/MantidPlot/SysMon/ui_sysmon.ui' +# Form implementation generated from reading ui file 'ui_sysmon.ui' # -# Created: Fri Sep 19 12:44:16 2014 -# by: PyQt4 UI code generator 4.10.4 +# Created: Wed Sep 24 16:19:13 2014 +# by: PyQt4 UI code generator 4.8.3 # # WARNING! All changes made in this file will be lost! @@ -12,21 +12,13 @@ try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: - def _fromUtf8(s): - return s - -try: - _encoding = QtGui.QApplication.UnicodeUTF8 - def _translate(context, text, disambig): - return QtGui.QApplication.translate(context, text, disambig, _encoding) -except AttributeError: - def _translate(context, text, disambig): - return QtGui.QApplication.translate(context, text, disambig) + _fromUtf8 = lambda s: s class Ui_Form(object): def setupUi(self, Form): Form.setObjectName(_fromUtf8("Form")) Form.resize(230, 331) + Form.setMinimumSize(QtCore.QSize(230, 331)) Form.setMaximumSize(QtCore.QSize(16777215, 16777215)) self.horizontalLayout = QtGui.QHBoxLayout(Form) self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) @@ -45,7 +37,7 @@ def setupUi(self, Form): self.scrollArea.setWidgetResizable(True) self.scrollArea.setObjectName(_fromUtf8("scrollArea")) self.scrollAreaWidgetContents = QtGui.QWidget() - self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 320, 293)) + self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 186, 267)) self.scrollAreaWidgetContents.setObjectName(_fromUtf8("scrollAreaWidgetContents")) self.verticalLayout_2 = QtGui.QVBoxLayout(self.scrollAreaWidgetContents) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) @@ -115,49 +107,44 @@ def setupUi(self, Form): self.groupBox_5.setSizePolicy(sizePolicy) self.groupBox_5.setMinimumSize(QtCore.QSize(0, 0)) font = QtGui.QFont() - font.setBold(False) - font.setUnderline(False) font.setWeight(50) + font.setUnderline(False) + font.setBold(False) self.groupBox_5.setFont(font) self.groupBox_5.setObjectName(_fromUtf8("groupBox_5")) - self.gridLayout_6 = QtGui.QGridLayout(self.groupBox_5) - self.gridLayout_6.setObjectName(_fromUtf8("gridLayout_6")) + self.verticalLayout_7 = QtGui.QVBoxLayout(self.groupBox_5) + self.verticalLayout_7.setObjectName(_fromUtf8("verticalLayout_7")) self.labelMemUsage = QtGui.QLabel(self.groupBox_5) font = QtGui.QFont() font.setUnderline(False) self.labelMemUsage.setFont(font) self.labelMemUsage.setObjectName(_fromUtf8("labelMemUsage")) - self.gridLayout_6.addWidget(self.labelMemUsage, 0, 0, 1, 1) + self.verticalLayout_7.addWidget(self.labelMemUsage) + self.progressBarStatusMemory = QtGui.QProgressBar(self.groupBox_5) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.progressBarStatusMemory.sizePolicy().hasHeightForWidth()) + self.progressBarStatusMemory.setSizePolicy(sizePolicy) + self.progressBarStatusMemory.setMaximumSize(QtCore.QSize(210, 16777215)) + self.progressBarStatusMemory.setToolTip(_fromUtf8("")) + self.progressBarStatusMemory.setObjectName(_fromUtf8("progressBarStatusMemory")) + self.verticalLayout_7.addWidget(self.progressBarStatusMemory) self.labelCPUCount = QtGui.QLabel(self.groupBox_5) self.labelCPUCount.setObjectName(_fromUtf8("labelCPUCount")) - self.gridLayout_6.addWidget(self.labelCPUCount, 3, 0, 1, 1) - self.labelMaxMem = QtGui.QLabel(self.groupBox_5) - self.labelMaxMem.setObjectName(_fromUtf8("labelMaxMem")) - self.gridLayout_6.addWidget(self.labelMaxMem, 1, 0, 1, 1) - self.label_102 = QtGui.QLabel(self.groupBox_5) - font = QtGui.QFont() - font.setUnderline(False) - self.label_102.setFont(font) - self.label_102.setObjectName(_fromUtf8("label_102")) - self.gridLayout_6.addWidget(self.label_102, 2, 0, 1, 1) + self.verticalLayout_7.addWidget(self.labelCPUCount) self.progressBarStatusCPU = QtGui.QProgressBar(self.groupBox_5) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.progressBarStatusCPU.sizePolicy().hasHeightForWidth()) self.progressBarStatusCPU.setSizePolicy(sizePolicy) - self.progressBarStatusCPU.setProperty("value", 24) + self.progressBarStatusCPU.setMaximumSize(QtCore.QSize(210, 16777215)) + self.progressBarStatusCPU.setToolTip(_fromUtf8("")) + self.progressBarStatusCPU.setStatusTip(_fromUtf8("")) + self.progressBarStatusCPU.setProperty(_fromUtf8("value"), 24) self.progressBarStatusCPU.setObjectName(_fromUtf8("progressBarStatusCPU")) - self.gridLayout_6.addWidget(self.progressBarStatusCPU, 2, 1, 2, 1) - self.progressBarStatusMemory = QtGui.QProgressBar(self.groupBox_5) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.progressBarStatusMemory.sizePolicy().hasHeightForWidth()) - self.progressBarStatusMemory.setSizePolicy(sizePolicy) - self.progressBarStatusMemory.setProperty("value", 24) - self.progressBarStatusMemory.setObjectName(_fromUtf8("progressBarStatusMemory")) - self.gridLayout_6.addWidget(self.progressBarStatusMemory, 0, 1, 2, 1) + self.verticalLayout_7.addWidget(self.progressBarStatusCPU) self.gridLayout_4.addWidget(self.groupBox_5, 1, 0, 1, 1) self.verticalLayout_2.addWidget(self.groupBox_3) self.scrollArea.setWidget(self.scrollAreaWidgetContents) @@ -196,6 +183,8 @@ def setupUi(self, Form): self.tableWidgetProcess.setRowCount(10) self.tableWidgetProcess.setColumnCount(5) self.tableWidgetProcess.setObjectName(_fromUtf8("tableWidgetProcess")) + self.tableWidgetProcess.setColumnCount(5) + self.tableWidgetProcess.setRowCount(10) item = QtGui.QTableWidgetItem() self.tableWidgetProcess.setHorizontalHeaderItem(0, item) item = QtGui.QTableWidgetItem() @@ -252,9 +241,13 @@ def setupUi(self, Form): sizePolicy.setHeightForWidth(self.radioButtonMem.sizePolicy().hasHeightForWidth()) self.radioButtonMem.setSizePolicy(sizePolicy) self.radioButtonMem.setMinimumSize(QtCore.QSize(0, 0)) - self.radioButtonMem.setChecked(True) + self.radioButtonMem.setChecked(False) self.radioButtonMem.setObjectName(_fromUtf8("radioButtonMem")) self.horizontalLayout_6.addWidget(self.radioButtonMem) + self.radioButtonMax = QtGui.QRadioButton(self.groupBox) + self.radioButtonMax.setChecked(True) + self.radioButtonMax.setObjectName(_fromUtf8("radioButtonMax")) + self.horizontalLayout_6.addWidget(self.radioButtonMax) self.verticalLayout_6.addWidget(self.groupBox) self.frameBar = QtGui.QFrame(self.tab_5) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding) @@ -275,7 +268,7 @@ def setupUi(self, Form): self.scrollArea_2.setWidgetResizable(True) self.scrollArea_2.setObjectName(_fromUtf8("scrollArea_2")) self.scrollAreaWidgetContents_2 = QtGui.QWidget() - self.scrollAreaWidgetContents_2.setGeometry(QtCore.QRect(0, 0, 303, 244)) + self.scrollAreaWidgetContents_2.setGeometry(QtCore.QRect(0, 0, 232, 250)) self.scrollAreaWidgetContents_2.setObjectName(_fromUtf8("scrollAreaWidgetContents_2")) self.horizontalLayout_5 = QtGui.QHBoxLayout(self.scrollAreaWidgetContents_2) self.horizontalLayout_5.setObjectName(_fromUtf8("horizontalLayout_5")) @@ -331,47 +324,41 @@ def setupUi(self, Form): QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): - Form.setWindowTitle(_translate("Form", "Form", None)) - self.groupBox_3.setTitle(_translate("Form", "System Info", None)) - self.labelComputerName.setText(_translate("Form", "Computer Name: ", None)) - self.labelOS.setText(_translate("Form", "Operating System:", None)) - self.labelProcFam.setText(_translate("Form", "Processor Family:", None)) - self.labelNUsers.setText(_translate("Form", "Number of Users Logged On:", None)) - self.labelUptime.setText(_translate("Form", "System Uptime: ", None)) - self.groupBox_5.setTitle(_translate("Form", "Composite System Status", None)) - self.labelMemUsage.setText(_translate("Form", "Memory Usage", None)) - self.labelCPUCount.setText(_translate("Form", "CPU count:", None)) - self.labelMaxMem.setText(_translate("Form", "Max Mem:", None)) - self.label_102.setText(_translate("Form", "Composite CPU Usage", None)) - self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("Form", "System", None)) - self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("Form", "History", None)) - self.labelLastUpdate.setText(_translate("Form", "Last Update: ", None)) + Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8)) + self.groupBox_3.setTitle(QtGui.QApplication.translate("Form", "System Info", None, QtGui.QApplication.UnicodeUTF8)) + self.labelComputerName.setText(QtGui.QApplication.translate("Form", "Computer Name: ", None, QtGui.QApplication.UnicodeUTF8)) + self.labelOS.setText(QtGui.QApplication.translate("Form", "Operating System:", None, QtGui.QApplication.UnicodeUTF8)) + self.labelProcFam.setText(QtGui.QApplication.translate("Form", "Processor Family:", None, QtGui.QApplication.UnicodeUTF8)) + self.labelNUsers.setText(QtGui.QApplication.translate("Form", "Number of Users Logged On:", None, QtGui.QApplication.UnicodeUTF8)) + self.labelUptime.setText(QtGui.QApplication.translate("Form", "System Uptime: ", None, QtGui.QApplication.UnicodeUTF8)) + self.groupBox_5.setTitle(QtGui.QApplication.translate("Form", "Composite System Status", None, QtGui.QApplication.UnicodeUTF8)) + self.labelMemUsage.setText(QtGui.QApplication.translate("Form", "Memory Usage", None, QtGui.QApplication.UnicodeUTF8)) + self.labelCPUCount.setText(QtGui.QApplication.translate("Form", "CPU count:", None, QtGui.QApplication.UnicodeUTF8)) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), QtGui.QApplication.translate("Form", "System", None, QtGui.QApplication.UnicodeUTF8)) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), QtGui.QApplication.translate("Form", "History", None, QtGui.QApplication.UnicodeUTF8)) + self.labelLastUpdate.setText(QtGui.QApplication.translate("Form", "Last Update: ", None, QtGui.QApplication.UnicodeUTF8)) self.tableWidgetProcess.setSortingEnabled(True) - item = self.tableWidgetProcess.horizontalHeaderItem(0) - item.setText(_translate("Form", "PID", None)) - item = self.tableWidgetProcess.horizontalHeaderItem(1) - item.setText(_translate("Form", "USER", None)) - item = self.tableWidgetProcess.horizontalHeaderItem(2) - item.setText(_translate("Form", "CPU%", None)) - item = self.tableWidgetProcess.horizontalHeaderItem(3) - item.setText(_translate("Form", "MEM%", None)) - item = self.tableWidgetProcess.horizontalHeaderItem(4) - item.setText(_translate("Form", "NAME", None)) - self.pushButtonUpdate.setText(_translate("Form", "Hold Updates", None)) - self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("Form", "Processes", None)) - self.groupBox.setTitle(_translate("Form", "Sort", None)) - self.radioButtonCPU.setText(_translate("Form", "CPU", None)) - self.radioButtonMem.setText(_translate("Form", "Memory", None)) - self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_5), _translate("Form", "Users", None)) - self.groupBox_6.setTitle(_translate("Form", "Display Period", None)) - self.radioButton60Secs.setText(_translate("Form", "60 Seconds", None)) - self.radioButton300Secs.setText(_translate("Form", "300 Seconds", None)) - self.radioButton600Secs.setText(_translate("Form", "600 Seconds", None)) - self.radioButton3600Secs.setText(_translate("Form", "3600 Seconds", None)) - self.groupBox_4.setTitle(_translate("Form", "Update Rate", None)) - self.radioButton1Sec.setText(_translate("Form", "1 Second", None)) - self.radioButton2Secs.setText(_translate("Form", "2 Seconds", None)) - self.radioButton5Secs.setText(_translate("Form", "5 Seconds", None)) - self.radioButton10Secs.setText(_translate("Form", "10 Seconds", None)) - self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), _translate("Form", "Options", None)) + self.tableWidgetProcess.horizontalHeaderItem(0).setText(QtGui.QApplication.translate("Form", "PID", None, QtGui.QApplication.UnicodeUTF8)) + self.tableWidgetProcess.horizontalHeaderItem(1).setText(QtGui.QApplication.translate("Form", "USER", None, QtGui.QApplication.UnicodeUTF8)) + self.tableWidgetProcess.horizontalHeaderItem(2).setText(QtGui.QApplication.translate("Form", "CPU%", None, QtGui.QApplication.UnicodeUTF8)) + self.tableWidgetProcess.horizontalHeaderItem(3).setText(QtGui.QApplication.translate("Form", "MEM%", None, QtGui.QApplication.UnicodeUTF8)) + self.tableWidgetProcess.horizontalHeaderItem(4).setText(QtGui.QApplication.translate("Form", "NAME", None, QtGui.QApplication.UnicodeUTF8)) + self.pushButtonUpdate.setText(QtGui.QApplication.translate("Form", "Hold Updates", None, QtGui.QApplication.UnicodeUTF8)) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), QtGui.QApplication.translate("Form", "Processes", None, QtGui.QApplication.UnicodeUTF8)) + self.groupBox.setTitle(QtGui.QApplication.translate("Form", "Sort", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButtonCPU.setText(QtGui.QApplication.translate("Form", "CPU", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButtonMem.setText(QtGui.QApplication.translate("Form", "Memory", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButtonMax.setText(QtGui.QApplication.translate("Form", "Max", None, QtGui.QApplication.UnicodeUTF8)) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_5), QtGui.QApplication.translate("Form", "Users", None, QtGui.QApplication.UnicodeUTF8)) + self.groupBox_6.setTitle(QtGui.QApplication.translate("Form", "Display Period", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton60Secs.setText(QtGui.QApplication.translate("Form", "60 Seconds", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton300Secs.setText(QtGui.QApplication.translate("Form", "300 Seconds", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton600Secs.setText(QtGui.QApplication.translate("Form", "600 Seconds", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton3600Secs.setText(QtGui.QApplication.translate("Form", "3600 Seconds", None, QtGui.QApplication.UnicodeUTF8)) + self.groupBox_4.setTitle(QtGui.QApplication.translate("Form", "Update Rate", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton1Sec.setText(QtGui.QApplication.translate("Form", "1 Second", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton2Secs.setText(QtGui.QApplication.translate("Form", "2 Seconds", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton5Secs.setText(QtGui.QApplication.translate("Form", "5 Seconds", None, QtGui.QApplication.UnicodeUTF8)) + self.radioButton10Secs.setText(QtGui.QApplication.translate("Form", "10 Seconds", None, QtGui.QApplication.UnicodeUTF8)) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), QtGui.QApplication.translate("Form", "Options", None, QtGui.QApplication.UnicodeUTF8)) diff --git a/Code/Mantid/MantidPlot/SysMon/ui_sysmon.ui b/Code/Mantid/MantidPlot/SysMon/ui_sysmon.ui index 2dfbc897f680..a793bcc76f91 100644 --- a/Code/Mantid/MantidPlot/SysMon/ui_sysmon.ui +++ b/Code/Mantid/MantidPlot/SysMon/ui_sysmon.ui @@ -10,6 +10,12 @@ 331 + + + 230 + 331 + + 16777215 @@ -36,7 +42,7 @@ System - + true @@ -46,8 +52,8 @@ 0 0 - 320 - 293 + 186 + 267 @@ -168,7 +174,7 @@ - + @@ -192,8 +198,8 @@ Composite System Status - - + + @@ -205,52 +211,51 @@ - - - - CPU count: + + + + + 0 + 0 + - - - - - - Max Mem: + + + 210 + 16777215 + + + + - - - - - false - - + + - Composite CPU Usage + CPU count: - + - + 0 0 - - 24 + + + 210 + 16777215 + - - - - - - - 0 - 0 - + + + + + 24 @@ -491,6 +496,16 @@ Memory + + false + + + + + + + Max + true @@ -532,8 +547,8 @@ 0 0 - 303 - 244 + 232 + 250 From 5742e0719639d0f473b6092c39e00a6137162f5d Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Thu, 4 Dec 2014 20:14:09 +0000 Subject: [PATCH 007/275] Fix bad merge conflict resolution Refs #9843 --- Code/Mantid/MantidPlot/CMakeLists.txt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Code/Mantid/MantidPlot/CMakeLists.txt b/Code/Mantid/MantidPlot/CMakeLists.txt index 652202eec165..6313cc0253a8 100644 --- a/Code/Mantid/MantidPlot/CMakeLists.txt +++ b/Code/Mantid/MantidPlot/CMakeLists.txt @@ -960,16 +960,10 @@ set ( MANTIDPLOT_TEST_PY_FILES MantidPlot2DPlotTest.py MantidPlotProxiesTest.py MantidPlotPythonImportTest.py -<<<<<<< HEAD - MantidPlotFoldersTest.py - MantidPlotMdiSubWindowTest.py - MantidPlotTiledWindowTest.py -======= MantidPlotFoldersTest.py MantidPlotMdiSubWindowTest.py MantidPlotTiledWindowTest.py MantidPlotInputArgsCheck.py ->>>>>>> master ) if ( 0 ) From bc3246d52b2f4e81210c02b73652d420aef061a9 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Wed, 10 Dec 2014 17:31:59 +0000 Subject: [PATCH 008/275] Update SysMon to v0.26 Refs #9843 --- Code/Mantid/MantidPlot/CMakeLists.txt | 1 + Code/Mantid/MantidPlot/SysMon/SysMon.pyw | 10 ++- Code/Mantid/MantidPlot/SysMon/_version.py | 4 + Code/Mantid/MantidPlot/SysMon/sysmon.py | 24 +++++- Code/Mantid/MantidPlot/SysMon/sysmon_tools.py | 82 +++++++++++-------- Code/Mantid/MantidPlot/SysMon/ui_sysmon.py | 32 +++++++- Code/Mantid/MantidPlot/SysMon/ui_sysmon.ui | 54 +++++++++++- 7 files changed, 166 insertions(+), 41 deletions(-) create mode 100644 Code/Mantid/MantidPlot/SysMon/_version.py diff --git a/Code/Mantid/MantidPlot/CMakeLists.txt b/Code/Mantid/MantidPlot/CMakeLists.txt index 620a008c2a18..b10593f4c885 100644 --- a/Code/Mantid/MantidPlot/CMakeLists.txt +++ b/Code/Mantid/MantidPlot/CMakeLists.txt @@ -882,6 +882,7 @@ copy_files_to_dir ( "${IPY_FILES}" # SysMon scripts set( SYSMON_FILES __init__.py + _version.py config.py sysmon.py sysmon_tools.py diff --git a/Code/Mantid/MantidPlot/SysMon/SysMon.pyw b/Code/Mantid/MantidPlot/SysMon/SysMon.pyw index 4fd044de0cbe..638813a2990d 100755 --- a/Code/Mantid/MantidPlot/SysMon/SysMon.pyw +++ b/Code/Mantid/MantidPlot/SysMon/SysMon.pyw @@ -11,6 +11,14 @@ provided to the application. import config import sys +__version__="unknown" +try: + from _version import __version__ +except ImportError: + #_version.py file not found - version not known in this case so use + #the default previously given. + pass + #parse args - doing it here as config structure needs to be filled prior to importing sysmon if ['--nompl'] == [s for s in sys.argv if '--nompl' in s]: #case to not use matplotlib @@ -72,7 +80,7 @@ class SysMonMainWindow(QtGui.QMainWindow): def About(self): dialog=QtGui.QMessageBox(self) - dialog.setText("PyQt4 System Monitoring Application V0.02") + dialog.setText("PyQt4 System Monitoring Application "+__version__) info='Application Info: \n\r * Changing the Update Rate Clears plots \n\r * It may take one full new update cycle for changes to take effect \n\r * Update rate shown in History plot xaxis label \n\r * Process tab CPU percentage can be greater than 100 when more than a single core is involved' dialog.setDetailedText(info) #give full info in detailed text dialog.exec_() diff --git a/Code/Mantid/MantidPlot/SysMon/_version.py b/Code/Mantid/MantidPlot/SysMon/_version.py new file mode 100644 index 000000000000..bad294c0f517 --- /dev/null +++ b/Code/Mantid/MantidPlot/SysMon/_version.py @@ -0,0 +1,4 @@ +#File to identify the current version of the software +#Note that this file must be manually updated to contain the same +#version number as the git tag for the check-in. +__version__="v0.26" \ No newline at end of file diff --git a/Code/Mantid/MantidPlot/SysMon/sysmon.py b/Code/Mantid/MantidPlot/SysMon/sysmon.py index d62254f7cff0..967442b50c65 100644 --- a/Code/Mantid/MantidPlot/SysMon/sysmon.py +++ b/Code/Mantid/MantidPlot/SysMon/sysmon.py @@ -3,7 +3,14 @@ import sys, os, time import re import config #application constants and variables +#suppress deprecation warnings that can occur when importing psutil version 2 +#note - all deprecation warnings will probably be suppressed using this filterwarnings +#as specifying the psutil module specifically in filterwarnings did not suppress +#these warnings +import warnings +warnings.filterwarnings('ignore',category=DeprecationWarning) import psutil + #check psutil version as command syntax changes between version 1 and version 2 ver=psutil.__version__ verChk1=re.match('1.[0-9].[0-9]',ver) #latest psutil version 1 is 1.2.1 - using positional numeric wildcards to check sub versions @@ -26,6 +33,15 @@ except AttributeError: _fromUtf8 = lambda s: s +#import application version information +__version__="unknown" +try: + from _version import __version__ +except ImportError: + #_version.py file not found - version not known in this case so use + #the default previously given. + pass + class SysMon(QtGui.QWidget): def __init__(self, parent=None): @@ -102,7 +118,9 @@ def __init__(self, parent=None): #create drawing canvas # a figure instance to plot on - matplotlib.rc_context({'toolbar':False}) + if not re.match('1.[0-1]',matplotlib.__version__): + #if not an old version of matplotlib, then use the following command + matplotlib.rc_context({'toolbar':False}) #initialize figure 1 and its canvas for cpu and memory history plots self.ui.figure = plt.figure(1) # the Canvas Widget displays the `figure` @@ -142,6 +160,9 @@ def __init__(self, parent=None): #upon initialization completion, set System tab (first tab on left) as the visible tab self.ui.tabWidget.setCurrentIndex(config.SYST_TAB) + + #initialize version label + self.ui.labelVersion.setText("Version: "+__version__) def constantUpdate(self): #redirct to global function @@ -211,7 +232,6 @@ def updateProcesses(self): self.ui.pushButtonUpdate.setText('Hold Updates') def resizeEvent(self,resizeEvent): - print "resizing" sz=self.ui.tableWidgetProcess.size() w=sz.width() wmin=self.ui.parent.minimumSize().width() #establish minimum table size based upon parent widget minimum size diff --git a/Code/Mantid/MantidPlot/SysMon/sysmon_tools.py b/Code/Mantid/MantidPlot/SysMon/sysmon_tools.py index 0fe4e1f87ad7..6c2e0f6dfaca 100644 --- a/Code/Mantid/MantidPlot/SysMon/sysmon_tools.py +++ b/Code/Mantid/MantidPlot/SysMon/sysmon_tools.py @@ -1,10 +1,18 @@ +#suppress deprecation warnings that can occur when importing psutil version 2 +#note - all deprecation warnings will probably be suppressed using this filterwarnings +#as specifying the psutil module specifically in filterwarnings did not suppress +#these warnings +import warnings +warnings.filterwarnings('ignore',category=DeprecationWarning) import psutil + from PyQt4 import Qt, QtCore, QtGui import datetime import numpy as np import config import math import getpass +import re #check if command line flag --nompl set to disable matplotlib if not(config.nompl): @@ -27,31 +35,14 @@ def constantUpdateActor(self,config): - #check duration + #set duration number Ndur=self.duration - #update global variables - - #mode to show status in percentage - if self.update < 3: - #use averaging if using faster update rates - Navg=1 - else: - #Don't need averaging in longer acquisition cases - Navg=1 - busy_avg=0 + #get current CPU stats cpu_stats = psutil.cpu_times_percent(interval=0,percpu=False) #syntax seems to be same for psutil versions 1 and 2 - - tmpsum=cpu_stats.system+cpu_stats.user - if sum(self.ui.cpu[0:Navg-2+1]) == 0: - #avoid initial zeros in the array pulling down the average - just use the value measured in this case. - busy_avg=tmpsum - else: - #case to average - busy_avg=(tmpsum+sum(self.ui.cpu[0:Navg-2+1]))/Navg - - percentcpubusy = busy_avg - self.ui.progressBarStatusCPU.setValue(round(percentcpubusy)) + #determine total busy percentage based upon system and users + percentcpubusy=cpu_stats.system+cpu_stats.user + percentmembusy=psutil.virtual_memory().percent self.ui.progressBarStatusMemory.setValue(round(percentmembusy)) Ncpus=len(psutil.cpu_percent(percpu=True)) @@ -108,7 +99,10 @@ def constantUpdateActor(self,config): except: uname='' except: - pass #skip process - case where process no longer exists + #skip process - case where process no longer exists + cpupct=0 + memVal=0 + uname='' cpupctTot+=cpupct memValTot+=memVal #print "uname: ",uname," Me: ",Me @@ -117,16 +111,34 @@ def constantUpdateActor(self,config): cpupctMe+=cpupct memValMe+=memVal #print "cpupctMe: ",cpupctMe," memValMe: ",memValMe - if config.mplLoaded: - #update first position with most recent value overwriting oldest value which has been shifted to first position - self.ui.cpu=np.roll(self.ui.cpu,1) - self.ui.cpu[0]=percentcpubusy #percentcpubusy seems to agree better with system System Monitor than cpupctTot/Ncpus - self.ui.mem=np.roll(self.ui.mem,1) - self.ui.mem[0]=percentmembusy - self.ui.cpuMe=np.roll(self.ui.cpuMe,1) + + #update first position with most recent value overwriting oldest value which has been shifted to first position + self.ui.cpu=np.roll(self.ui.cpu,1) + #check if CPU smoothing to be applied + sm=int(str(self.ui.comboBoxCPUHistSmooth.currentText())) + if sm == 1: + self.ui.cpu[0]=percentcpubusy + elif sm >1: + self.ui.cpu[0]=(percentcpubusy+np.sum(self.ui.cpu[1:sm]))/sm + else: + #unknown case - default to no smoothing + self.ui.cpu[0]=percentcpubusy + #update progress bar with (potentially) smoothed cpu percentage + self.ui.progressBarStatusCPU.setValue(round(self.ui.cpu[0])) + self.ui.mem=np.roll(self.ui.mem,1) + self.ui.mem[0]=percentmembusy + self.ui.cpuMe=np.roll(self.ui.cpuMe,1) + #check if CPU smoothing to be applied + if sm == 1: + self.ui.cpuMe[0]=cpupctMe/(Ncpus) + elif sm>1: + self.ui.cpuMe[0]=(cpupctMe/(Ncpus)+np.sum(self.ui.cpuMe[1:sm]))/sm + else: + #use no filtering in case sm is unknown (should never happen...) self.ui.cpuMe[0]=cpupctMe/(Ncpus) - self.ui.memMe=np.roll(self.ui.memMe,1) - self.ui.memMe[0]=memValMe + self.ui.memMe=np.roll(self.ui.memMe,1) + self.ui.memMe[0]=memValMe + #update the history plot if self.ui.tabWidget.currentIndex() == config.HIST_TAB: @@ -475,7 +487,11 @@ def updateUserChart(self,config): usersLegend.reverse() p.reverse() #place legend outside of plot to the right - plt.legend(p,usersLegend,bbox_to_anchor=(1.45, 1.1), loc="upper left", borderaxespad=0.1,fontsize=config.pltFont-0.5,title='Users') + if not re.match('1.[0-1]',matplotlib.__version__): + #if not an old version of matplotlib, then use the following command + plt.legend(p,usersLegend,bbox_to_anchor=(1.45, 1.1), loc="upper left", borderaxespad=0.1,fontsize=config.pltFont-0.5,title='Users') + else: + plt.legend(p,usersLegend,bbox_to_anchor=(1.45, 1.1), loc="upper left", borderaxespad=0.1,title='Users') #place second y axis label on plot ylab2=np.arange(5)/4.0*float(ymax) diff --git a/Code/Mantid/MantidPlot/SysMon/ui_sysmon.py b/Code/Mantid/MantidPlot/SysMon/ui_sysmon.py index 93cfffe0752b..351c80dd4287 100644 --- a/Code/Mantid/MantidPlot/SysMon/ui_sysmon.py +++ b/Code/Mantid/MantidPlot/SysMon/ui_sysmon.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'ui_sysmon.ui' # -# Created: Wed Sep 24 16:19:13 2014 +# Created: Fri Dec 05 09:55:29 2014 # by: PyQt4 UI code generator 4.8.3 # # WARNING! All changes made in this file will be lost! @@ -37,7 +37,7 @@ def setupUi(self, Form): self.scrollArea.setWidgetResizable(True) self.scrollArea.setObjectName(_fromUtf8("scrollArea")) self.scrollAreaWidgetContents = QtGui.QWidget() - self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 186, 267)) + self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 179, 267)) self.scrollAreaWidgetContents.setObjectName(_fromUtf8("scrollAreaWidgetContents")) self.verticalLayout_2 = QtGui.QVBoxLayout(self.scrollAreaWidgetContents) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) @@ -268,7 +268,7 @@ def setupUi(self, Form): self.scrollArea_2.setWidgetResizable(True) self.scrollArea_2.setObjectName(_fromUtf8("scrollArea_2")) self.scrollAreaWidgetContents_2 = QtGui.QWidget() - self.scrollAreaWidgetContents_2.setGeometry(QtCore.QRect(0, 0, 232, 250)) + self.scrollAreaWidgetContents_2.setGeometry(QtCore.QRect(0, 0, 238, 250)) self.scrollAreaWidgetContents_2.setObjectName(_fromUtf8("scrollAreaWidgetContents_2")) self.horizontalLayout_5 = QtGui.QHBoxLayout(self.scrollAreaWidgetContents_2) self.horizontalLayout_5.setObjectName(_fromUtf8("horizontalLayout_5")) @@ -290,8 +290,27 @@ def setupUi(self, Form): self.radioButton3600Secs = QtGui.QRadioButton(self.groupBox_6) self.radioButton3600Secs.setObjectName(_fromUtf8("radioButton3600Secs")) self.verticalLayout_5.addWidget(self.radioButton3600Secs) + self.line = QtGui.QFrame(self.groupBox_6) + self.line.setFrameShape(QtGui.QFrame.HLine) + self.line.setFrameShadow(QtGui.QFrame.Sunken) + self.line.setObjectName(_fromUtf8("line")) + self.verticalLayout_5.addWidget(self.line) + self.label = QtGui.QLabel(self.groupBox_6) + self.label.setObjectName(_fromUtf8("label")) + self.verticalLayout_5.addWidget(self.label) + self.comboBoxCPUHistSmooth = QtGui.QComboBox(self.groupBox_6) + self.comboBoxCPUHistSmooth.setObjectName(_fromUtf8("comboBoxCPUHistSmooth")) + self.comboBoxCPUHistSmooth.addItem(_fromUtf8("")) + self.comboBoxCPUHistSmooth.addItem(_fromUtf8("")) + self.comboBoxCPUHistSmooth.addItem(_fromUtf8("")) + self.comboBoxCPUHistSmooth.addItem(_fromUtf8("")) + self.comboBoxCPUHistSmooth.addItem(_fromUtf8("")) + self.verticalLayout_5.addWidget(self.comboBoxCPUHistSmooth) spacerItem1 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.verticalLayout_5.addItem(spacerItem1) + self.labelVersion = QtGui.QLabel(self.groupBox_6) + self.labelVersion.setObjectName(_fromUtf8("labelVersion")) + self.verticalLayout_5.addWidget(self.labelVersion) self.horizontalLayout_5.addWidget(self.groupBox_6) self.groupBox_4 = QtGui.QGroupBox(self.scrollAreaWidgetContents_2) self.groupBox_4.setMinimumSize(QtCore.QSize(0, 0)) @@ -355,6 +374,13 @@ def retranslateUi(self, Form): self.radioButton300Secs.setText(QtGui.QApplication.translate("Form", "300 Seconds", None, QtGui.QApplication.UnicodeUTF8)) self.radioButton600Secs.setText(QtGui.QApplication.translate("Form", "600 Seconds", None, QtGui.QApplication.UnicodeUTF8)) self.radioButton3600Secs.setText(QtGui.QApplication.translate("Form", "3600 Seconds", None, QtGui.QApplication.UnicodeUTF8)) + self.label.setText(QtGui.QApplication.translate("Form", "CPU History Smooth", None, QtGui.QApplication.UnicodeUTF8)) + self.comboBoxCPUHistSmooth.setItemText(0, QtGui.QApplication.translate("Form", "1", None, QtGui.QApplication.UnicodeUTF8)) + self.comboBoxCPUHistSmooth.setItemText(1, QtGui.QApplication.translate("Form", "2", None, QtGui.QApplication.UnicodeUTF8)) + self.comboBoxCPUHistSmooth.setItemText(2, QtGui.QApplication.translate("Form", "5", None, QtGui.QApplication.UnicodeUTF8)) + self.comboBoxCPUHistSmooth.setItemText(3, QtGui.QApplication.translate("Form", "10", None, QtGui.QApplication.UnicodeUTF8)) + self.comboBoxCPUHistSmooth.setItemText(4, QtGui.QApplication.translate("Form", "15", None, QtGui.QApplication.UnicodeUTF8)) + self.labelVersion.setText(QtGui.QApplication.translate("Form", "Version: ", None, QtGui.QApplication.UnicodeUTF8)) self.groupBox_4.setTitle(QtGui.QApplication.translate("Form", "Update Rate", None, QtGui.QApplication.UnicodeUTF8)) self.radioButton1Sec.setText(QtGui.QApplication.translate("Form", "1 Second", None, QtGui.QApplication.UnicodeUTF8)) self.radioButton2Secs.setText(QtGui.QApplication.translate("Form", "2 Seconds", None, QtGui.QApplication.UnicodeUTF8)) diff --git a/Code/Mantid/MantidPlot/SysMon/ui_sysmon.ui b/Code/Mantid/MantidPlot/SysMon/ui_sysmon.ui index a793bcc76f91..265c066807af 100644 --- a/Code/Mantid/MantidPlot/SysMon/ui_sysmon.ui +++ b/Code/Mantid/MantidPlot/SysMon/ui_sysmon.ui @@ -52,7 +52,7 @@ 0 0 - 186 + 179 267 @@ -547,7 +547,7 @@ 0 0 - 232 + 238 250 @@ -595,6 +595,49 @@ + + + + Qt::Horizontal + + + + + + + CPU History Smooth + + + + + + + + 1 + + + + + 2 + + + + + 5 + + + + + 10 + + + + + 15 + + + + @@ -608,6 +651,13 @@ + + + + Version: + + + From 9ef4c184dab259455877c208c878fcac04c1f101 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Thu, 11 Dec 2014 10:15:02 +0000 Subject: [PATCH 009/275] Add psutil as package dependency for Linux packages. Refs #9843 --- Code/Mantid/CMakeLists.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Code/Mantid/CMakeLists.txt b/Code/Mantid/CMakeLists.txt index 6b42d63df1a0..b70b46f929b1 100644 --- a/Code/Mantid/CMakeLists.txt +++ b/Code/Mantid/CMakeLists.txt @@ -197,8 +197,8 @@ if ( ENABLE_CPACK ) set ( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES},poco-crypto,poco-data,poco-mysql,poco-sqlite,poco-odbc,poco-util,poco-xml,poco-zip,poco-net,poco-netssl,poco-foundation,PyQt4,sip" ) set ( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES},python-ipython >= 1.1.0" ) - # scipy & matplotlib - set ( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES},scipy,python-matplotlib" ) + # scipy, matplotlib, psutil + set ( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES},scipy,python-matplotlib,python-psutil" ) set ( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES},mxml,hdf,hdf5" ) if( "${UNIX_CODENAME}" MATCHES "Santiago" ) @@ -226,19 +226,19 @@ if ( ENABLE_CPACK ) set ( PERFTOOLS_DEB_PACKAGE "libgoogle-perftools0 (>= 1.7)" ) if( "${UNIX_CODENAME}" MATCHES "lucid" ) list ( APPEND DEPENDS_LIST ",libqscintilla2-5," - "libopencascade-foundation-6.3.0 (>= 6.3.0),libopencascade-modeling-6.3.0 (>= 6.3.0)," + "libopencascade-foundation-6.3.0 (>= 6.3.0),libopencascade-modeling-6.3.0 (>= 6.3.0),python-psutil," "libmuparser0,libpocofoundation9,libpocoutil9,libpoconet9,libpoconetssl9,libpococrypto9,libpocoxml9" ) elseif( "${UNIX_CODENAME}" MATCHES "precise" ) list ( APPEND DEPENDS_LIST ",libqscintilla2-8," "libopencascade-foundation-6.5.0 (>= 6.5.0),libopencascade-modeling-6.5.0 (>= 6.5.0)," "libmuparser0debian1," - "ipython-qtconsole (>= 1.1),python-matplotlib,python-scipy," + "ipython-qtconsole (>= 1.1),python-matplotlib,python-scipy,python-psutil," "libpocofoundation9,libpocoutil9,libpoconet9,libpoconetssl9,libpococrypto9,libpocoxml9") elseif( "${UNIX_CODENAME}" STREQUAL "trusty" ) list ( APPEND DEPENDS_LIST ",libqscintilla2-11," "liboce-foundation8,liboce-modeling8," "libmuparser2," - "ipython-qtconsole (>= 1.1),python-matplotlib,python-scipy," + "ipython-qtconsole (>= 1.1),python-matplotlib,python-scipy,python-psutil," "libpocofoundation11,libpocoutil11,libpoconet11,libpoconetssl11,libpococrypto11,libpocoxml11") set ( PERFTOOLS_DEB_PACKAGE "libgoogle-perftools4 (>= 1.7)" ) else() From 4f9e81639e8219fbf3ee5384c513571ae2f0112c Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Mon, 22 Dec 2014 09:26:27 +0000 Subject: [PATCH 010/275] Updated to SysMon v0.27 Refs #9843 --- Code/Mantid/MantidPlot/SysMon/_version.py | 2 +- Code/Mantid/MantidPlot/SysMon/sysmon_tools.py | 216 +++++++++++++++--- README.md | 32 ++- 3 files changed, 205 insertions(+), 45 deletions(-) diff --git a/Code/Mantid/MantidPlot/SysMon/_version.py b/Code/Mantid/MantidPlot/SysMon/_version.py index bad294c0f517..649c677e799e 100644 --- a/Code/Mantid/MantidPlot/SysMon/_version.py +++ b/Code/Mantid/MantidPlot/SysMon/_version.py @@ -1,4 +1,4 @@ #File to identify the current version of the software #Note that this file must be manually updated to contain the same #version number as the git tag for the check-in. -__version__="v0.26" \ No newline at end of file +__version__="v0.27" \ No newline at end of file diff --git a/Code/Mantid/MantidPlot/SysMon/sysmon_tools.py b/Code/Mantid/MantidPlot/SysMon/sysmon_tools.py index 6c2e0f6dfaca..108f6e58c456 100644 --- a/Code/Mantid/MantidPlot/SysMon/sysmon_tools.py +++ b/Code/Mantid/MantidPlot/SysMon/sysmon_tools.py @@ -13,6 +13,8 @@ import math import getpass import re +import sys +import time #check if command line flag --nompl set to disable matplotlib if not(config.nompl): @@ -190,6 +192,9 @@ def constantUpdateActor(self,config): def updateProcTable(self,config): if self.doUpdates==True: + + Ncpus=len(psutil.cpu_percent(percpu=True)) + table=self.ui.tableWidgetProcess #first remove all rows Nrows=table.rowCount() @@ -221,25 +226,93 @@ def updateProcTable(self,config): d_cpu={} d_mem={} d_name={} + d_cpuTimes={} + d_procTimes={} #fill the dictionaries - seems to need to be done faster than within loop which also fills the table...not sure why... + + try: + #check if this dictionary exists or not + self.ui.d_procTimes + self.ui.d_cpuTimes + #if so, move on + pass + except: + #case to initialize the dictionary + for proc in psutil.process_iter(): + try: + #check if acess denied + pname=proc.name + proctime=proc.get_cpu_times() #get + cputime=psutil.cpu_times() + d_procTimes.update({proc.pid:proctime}) + d_cpuTimes.update({proc.pid:cputime}) + except: + #case we skip a process + pass + self.ui.d_cpuTimes=d_cpuTimes + self.ui.d_procTimes=d_procTimes + d_cpuTimes={} + d_procTimes={} + + updateInterval=float(self.update) #timer interval in seconds for proc in psutil.process_iter(): - try: + #try: + if psutil.Process(proc.pid).is_running(): + #if proc.pid == 37196: #check if process still exists, if so, update dictionaries - cpupct=proc.get_cpu_percent(interval=0) if config.psutilVer == 1 else proc.cpu_percent(interval=0) - memVal=float(int(float(proc.get_memory_percent())*100.0))/100.0 if config.psutilVer == 1 else float(int(float(proc.memory_percent())*100.0))/100.0 try: - #don't update dictionaries if name gives an access denied error when checking process name - pname=proc.name if config.psutilVer == 1 else proc.name() - d_user.update({proc.pid:proc.username}) if config.psutilVer == 1 else d_user.update({proc.pid:proc.username()}) - d_cpu.update({proc.pid:cpupct}) - d_mem.update({proc.pid:memVal}) - d_name.update({proc.pid:pname}) + #check if process previously existed - if so we can calculate a cpupct + proctimeHold=self.ui.d_procTimes[proc.pid] + proctime=proc.get_cpu_times() #get + deltaProcTime=(proctime.user+proctime.system) - (proctimeHold.user+proctimeHold.system) + + cputimeHold=self.ui.d_cpuTimes[proc.pid] + cputime=psutil.cpu_times() + deltaCPUTime=(cputime.user+cputime.system+cputime.idle) - (cputimeHold.user+cputimeHold.system+cputimeHold.idle) + + if deltaProcTime > 0: + if deltaCPUTime < updateInterval: + deltaCPUTime=updateInterval + else: + pass + cpupct=float(deltaProcTime)/float(deltaCPUTime)*100.0 + + else: + cpupct=0 + + if cpupct < 0: + cpupct=0 + + cpupct=float(int(float(cpupct)*100))/100 #only keep two decimal places + memVal=float(int(float(proc.get_memory_percent())*100.0))/100.0 if config.psutilVer == 1 else float(int(float(proc.memory_percent())*100.0))/100.0 + + try: + #don't update dictionaries if name gives an access denied error when checking process name + #print "Updating" + pname=proc.name if config.psutilVer == 1 else proc.name() + d_user.update({proc.pid:proc.username}) if config.psutilVer == 1 else d_user.update({proc.pid:proc.username()}) + d_cpu.update({proc.pid:cpupct}) + d_mem.update({proc.pid:memVal}) + d_name.update({proc.pid:pname}) + d_cpuTimes.update({proc.pid:cputime}) + d_procTimes.update({proc.pid:proctime}) + + except: + #print "psutil General Error: ",sys.exc_info()[0] + pass + except: - pass #place holder - except: - pass #skip this process - case where it no longer exists + #else process did not previously exist and we cannot give an update this iteration + #print "except - pid: ",proc.pid + pass + + + #once the dictionarys are updated, update cpu times for next loop + self.ui.d_cpuTimes=d_cpuTimes + self.ui.d_procTimes=d_procTimes + #now fill the table for display for proc in d_user.keys(): #print "proc: ",proc," type: ",type(proc) @@ -295,25 +368,98 @@ def updateUserChart(self,config): d_cpu={} d_mem={} d_name={} - #fill the dictionaries - seems to need to be done faster than within loop which also fills the table...not sure why... + d_cpuTimes={} + d_procTimes={} + + try: + #check if this dictionary exists or not + self.ui.d_procTimes + self.ui.d_cpuTimes + #if so, move on + pass + except: + #case to initialize the dictionary + for proc in psutil.process_iter(): + try: + #check if acess denied + pname=proc.name + proctime=proc.get_cpu_times() #get + cputime=psutil.cpu_times() + d_procTimes.update({proc.pid:proctime}) + d_cpuTimes.update({proc.pid:cputime}) + except: + #case we skip a process + pass + self.ui.d_cpuTimes=d_cpuTimes + self.ui.d_procTimes=d_procTimes + d_cpuTimes={} + d_procTimes={} + + updateInterval=float(self.update) #timer interval in seconds + totcpupct=0 for proc in psutil.process_iter(): try: + psutil.Process(proc.pid).is_running() + #if proc.pid == 37196: #check if process still exists, if so, update dictionaries - cpupct=proc.get_cpu_percent(interval=0) if config.psutilVer == 1 else proc.cpu_percent(interval=0) - memVal=float(int(float(proc.get_memory_percent())*100.0))/100.0 if config.psutilVer == 1 else float(int(float(proc.memory_percent())*100.0))/100.0 try: - #don't update dictionaries if name gives an access denied error when checking process name - pname=proc.name if config.psutilVer == 1 else proc.name() - d_user.update({proc.pid:proc.username}) if config.psutilVer == 1 else d_user.update({proc.pid:proc.username()}) - d_cpu.update({proc.pid:cpupct}) - d_mem.update({proc.pid:memVal}) - d_name.update({proc.pid:pname}) + #check if process previously existed - if so we can calculate a cpupct + proctimeHold=self.ui.d_procTimes[proc.pid] + proctime=proc.get_cpu_times() #get + deltaProcTime=(proctime.user+proctime.system) - (proctimeHold.user+proctimeHold.system) + + cputimeHold=self.ui.d_cpuTimes[proc.pid] + cputime=psutil.cpu_times() + deltaCPUTime=(cputime.user+cputime.system+cputime.idle) - (cputimeHold.user+cputimeHold.system+cputimeHold.idle) + + if deltaProcTime > 0: + if deltaCPUTime < updateInterval: + deltaCPUTime=updateInterval + else: + pass + cpupct=float(deltaProcTime)/float(deltaCPUTime)*100.0 + + else: + cpupct=0 + + if cpupct < 0: + cpupct=0 + + cpupct=float(int(float(cpupct)*100))/100 #only keep two decimal places + totcpupct+=cpupct + memVal=float(int(float(proc.get_memory_percent())*100.0))/100.0 if config.psutilVer == 1 else float(int(float(proc.memory_percent())*100.0))/100.0 + + try: + #don't update dictionaries if name gives an access denied error when checking process name + #print "Updating" + pname=proc.name if config.psutilVer == 1 else proc.name() + d_user.update({proc.pid:proc.username}) if config.psutilVer == 1 else d_user.update({proc.pid:proc.username()}) + #System Idle process should not be listed in users cpu totals so set it to zero + if pname =="System Idle Process": + cpupct=0 + d_cpu.update({proc.pid:cpupct}) + d_mem.update({proc.pid:memVal}) + d_name.update({proc.pid:pname}) + d_cpuTimes.update({proc.pid:cputime}) + d_procTimes.update({proc.pid:proctime}) + + except: + #print "psutil General Error: ",sys.exc_info()[0] + pass + except: - #print "access denied" - pass #place holder + #else process did not previously exist and we cannot give an update this iteration + #print "except - pid: ",proc.pid + + pass except: - #print "skipped process" - pass #skip this process as it no longer exists + #process no longer exists - do nothing + pass + + + self.ui.d_cpuTimes=d_cpuTimes + self.ui.d_procTimes=d_procTimes + #print "** Total Mem Used: ",sum(d_mem.values()) users=d_user.values() users_unique=list(set(users)) #use set() to find unique users then convert the resulting set to a list via list() @@ -335,7 +481,7 @@ def updateUserChart(self,config): user=d_user[pid] cpu_by_users[user]=cpu_by_users[user] + d_cpu[pid] mem_by_users[user]=mem_by_users[user] + d_mem[pid] - + #print d_cpu[35296],d_cpu[37196],d_cpu[35296]+d_cpu[37196] #now convert to a list which we can index cpu_by_users_lst=cpu_by_users.values() mem_by_users_lst=mem_by_users.values() @@ -370,6 +516,7 @@ def updateUserChart(self,config): indx=sorted(range(len(mem_by_users_lst)), key=mem_by_users_lst.__getitem__,reverse=True) else: print 'Incorrect sort parameter' + #sort lists cpu_by_users_sorted=[cpu_by_users_lst[x] for x in indx] mem_by_users_sorted=[mem_by_users_lst[x] for x in indx] @@ -438,10 +585,10 @@ def updateUserChart(self,config): frame=plt.gca() frame.axes.get_yaxis().set_ticks([]) plt.xticks(np.arange(2)+width/2.,('CPU','Mem'),fontsize=config.pltFont,fontweight='bold') - ymaxCPU=int((sum(cpu_by_users_sorted)+100)/100)*100 #range ymaxCPU to nearest 100% + ymaxCPU=int(round(sum(cpu_by_users_sorted)+10))/10*10 #range ymaxCPU to nearest 10% ymaxMEM=int(round(sum(mem_by_users_sorted)+10))/10*10 #range ymaxMEM to nearest 10% - ymaxMAX=max([ymaxCPU,ymaxMEM,100]) + ymaxMAX=max([ymaxCPU,ymaxMEM]) if sortBy == 'cpu': ymax=max([ymaxCPU,10]) @@ -452,20 +599,23 @@ def updateUserChart(self,config): elif sortBy == 'max': ymax=max([ymaxMAX,10]) auto=True -# print 'ymaxCPU: ',ymaxCPU,' ymaxMEM: ',ymaxMEM,' ymaxMAX: ',ymaxMAX,' ymax: ',ymax,' sum(mem_by_users_sorted): ',sum(mem_by_users_sorted) - plt.ylim(0,ymax,auto=auto) + #print 'ymaxCPU: ',ymaxCPU,' ymaxMEM: ',ymaxMEM,' ymaxMAX: ',ymaxMAX,' ymax: ',ymax + #print 'sum(cpu_by_users_sorted): ',sum(cpu_by_users_sorted),'sum(mem_by_users_sorted): ',sum(mem_by_users_sorted) + #print cpu_by_users + plt.ylim(0,ymax,auto=True) #compute composite % sumCPU=sum(cpu_by_users_sorted) - ylab=np.arange(5)/4.0*float(sumCPU)/float(self.ui.Ncpus) + sumCPU=float(int(sumCPU*100))/100 #use two digits + ylab=np.arange(5)/4.0*float(sumCPU)#/float(self.ui.Ncpus) scl=float(ymax)/float(sumCPU) ylab=ylab*100*scl tmp=ylab.astype('int') tmp1=tmp.astype('float') tmp1=tmp1/100 - ylab1=tmp1 + ylab1=np.round(tmp1) ax1=plt.twinx() ax1.set_ylabel('Composite CPU Percent',fontsize=config.pltFont,fontweight='bold') @@ -496,7 +646,7 @@ def updateUserChart(self,config): #place second y axis label on plot ylab2=np.arange(5)/4.0*float(ymax) ax2=plt.twinx() - ax2.set_ylabel('Percent',fontsize=config.pltFont,fontweight='bold',position=(0.9,0.5)) + ax2.set_ylabel('Memory Percent',fontsize=config.pltFont,fontweight='bold',position=(0.9,0.5)) ax2.set_yticks(ylab2) #ax2.set_yticks(ylab2) ax2.yaxis.set_ticks_position('right') diff --git a/README.md b/README.md index 71a05dea8d76..8ef2ab770d04 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,25 @@ -Mantid +SysMon ====== -The Mantid project provides a framework that supports high-performance computing and visualisation of scientific data. Mantid has been created to manipulate and analyse Neutron and Muon scattering data, but could be applied to many other techniques. The framework is open source and supported on multiple target platforms (Windows, Linux, Mac OS X). +Python qt system monitor which utilizes the Python psutil and platform modules to provide system information for display. -Useful links ------------- - * Homepage: http://www.mantidproject.org - * Download: http://download.mantidproject.org - * Asking for help: http://download.mantidproject.org/webmailer/index.php - * Issue tracking: http://trac.mantidproject.org/mantid/ - * Build server: http://builds.mantidproject.org - * Developer site: http://developer.mantidproject.org +This application has been adapted to work with psutil version 1 and version 2 modules as there are some command syntax changes between these two versions. + +The SysMon user interface has been divided into a main window which imports the tabs to make a standalone application, or the tabs can be imported into other applications as a QWidget. Thus there are separate .ui files corresponding to each. + +The code which imports the tabs into the main program resides in SysMon.pyw. This is where to look to see how to include the tabs into your own application. All files except SysMon.pyw and ui_sysmonMainWindow.* will be required when tabs are incorporated in other applications. + +The following command line arguments have been added: + --help to print out the help message. + --nompl to run the application minus matplotlib in support of the current MantidPlot (removes those tabs requiring matplotlib). + --custom to enable the custom menubar item in the standalone application (currently supports checking Matlab license status on SNS analysis computers). + +To run as a standalone application via the corresponding command lines: + *Change to the folder containing the Sysmon software, then: + *DOS: python SysMon.pyw + *Linux: ./SysMon.pyw + +The standalone application been tested on Windows and RHEL Linux, but not on Mac yet. + +Note that configuration and global constants and variables now reside in config.py. -[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/mantidproject/mantid/trend.png)](https://bitdeli.com/free "Bitdeli Badge") From 5fa5b77c5c91ab8e29de62bc92836db7a4b89bc6 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Mon, 5 Jan 2015 10:07:26 +0000 Subject: [PATCH 011/275] Update SysMon to version 0.28 Refs #9843 --- Code/Mantid/MantidPlot/SysMon/_version.py | 2 +- Code/Mantid/MantidPlot/SysMon/sysmon.py | 11 ++++++----- Code/Mantid/MantidPlot/SysMon/sysmon_tools.py | 6 ++---- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Code/Mantid/MantidPlot/SysMon/_version.py b/Code/Mantid/MantidPlot/SysMon/_version.py index 649c677e799e..83dec484891b 100644 --- a/Code/Mantid/MantidPlot/SysMon/_version.py +++ b/Code/Mantid/MantidPlot/SysMon/_version.py @@ -1,4 +1,4 @@ #File to identify the current version of the software #Note that this file must be manually updated to contain the same #version number as the git tag for the check-in. -__version__="v0.27" \ No newline at end of file +__version__="v0.28" \ No newline at end of file diff --git a/Code/Mantid/MantidPlot/SysMon/sysmon.py b/Code/Mantid/MantidPlot/SysMon/sysmon.py index 967442b50c65..6e9336ee8c49 100644 --- a/Code/Mantid/MantidPlot/SysMon/sysmon.py +++ b/Code/Mantid/MantidPlot/SysMon/sysmon.py @@ -13,12 +13,13 @@ #check psutil version as command syntax changes between version 1 and version 2 ver=psutil.__version__ -verChk1=re.match('1.[0-9].[0-9]',ver) #latest psutil version 1 is 1.2.1 - using positional numeric wildcards to check sub versions -#thus the check is for version 1 as version 2 and following versions are still evolving -#match returns a string if a match is found else returns NoneType -if verChk1 != None: +#using positional numeric wildcards for re.match() to check sub versions +#match returns a match object if a match is found else returns NoneType +if re.match('0.[0-9].[0-9]',ver) or re.match('1.[0-9].[0-9]',ver) != None: + #set flag to version 1 if either version 0 or version 1 psutil imported config.psutilVer=1 else: + #set flat to version 2 for any versions higher than version 1 config.psutilVer=2 from ui_sysmon import * @@ -162,7 +163,7 @@ def __init__(self, parent=None): self.ui.tabWidget.setCurrentIndex(config.SYST_TAB) #initialize version label - self.ui.labelVersion.setText("Version: "+__version__) + self.ui.labelVersion.setText("Version: "+__version__+"_"+psutil.__version__) def constantUpdate(self): #redirct to global function diff --git a/Code/Mantid/MantidPlot/SysMon/sysmon_tools.py b/Code/Mantid/MantidPlot/SysMon/sysmon_tools.py index 108f6e58c456..e0dc66da4615 100644 --- a/Code/Mantid/MantidPlot/SysMon/sysmon_tools.py +++ b/Code/Mantid/MantidPlot/SysMon/sysmon_tools.py @@ -40,10 +40,8 @@ def constantUpdateActor(self,config): #set duration number Ndur=self.duration - #get current CPU stats - cpu_stats = psutil.cpu_times_percent(interval=0,percpu=False) #syntax seems to be same for psutil versions 1 and 2 - #determine total busy percentage based upon system and users - percentcpubusy=cpu_stats.system+cpu_stats.user + #get current CPU percent busy + percentcpubusy = psutil.cpu_percent() percentmembusy=psutil.virtual_memory().percent self.ui.progressBarStatusMemory.setValue(round(percentmembusy)) From c15e56ff853c09ee3976a04e7a1fcb6addeda54e Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Thu, 8 Jan 2015 09:29:07 +0000 Subject: [PATCH 012/275] Update SysMon to version 0.29 Refs #9843 --- Code/Mantid/MantidPlot/SysMon/_version.py | 2 +- Code/Mantid/MantidPlot/SysMon/sysmon.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Code/Mantid/MantidPlot/SysMon/_version.py b/Code/Mantid/MantidPlot/SysMon/_version.py index 83dec484891b..b88b26dd7c4b 100644 --- a/Code/Mantid/MantidPlot/SysMon/_version.py +++ b/Code/Mantid/MantidPlot/SysMon/_version.py @@ -1,4 +1,4 @@ #File to identify the current version of the software #Note that this file must be manually updated to contain the same #version number as the git tag for the check-in. -__version__="v0.28" \ No newline at end of file +__version__="v0.29" \ No newline at end of file diff --git a/Code/Mantid/MantidPlot/SysMon/sysmon.py b/Code/Mantid/MantidPlot/SysMon/sysmon.py index 6e9336ee8c49..33249856c52c 100644 --- a/Code/Mantid/MantidPlot/SysMon/sysmon.py +++ b/Code/Mantid/MantidPlot/SysMon/sysmon.py @@ -119,7 +119,8 @@ def __init__(self, parent=None): #create drawing canvas # a figure instance to plot on - if not re.match('1.[0-1]',matplotlib.__version__): + #rc_context in matplotlib requires version 1.2.0 or later, so check we don't have an older version of matplotlib + if not re.match('1.[0-1]',matplotlib.__version__) and not re.match('0.',matplotlib.__version__): #if not an old version of matplotlib, then use the following command matplotlib.rc_context({'toolbar':False}) #initialize figure 1 and its canvas for cpu and memory history plots @@ -163,7 +164,7 @@ def __init__(self, parent=None): self.ui.tabWidget.setCurrentIndex(config.SYST_TAB) #initialize version label - self.ui.labelVersion.setText("Version: "+__version__+"_"+psutil.__version__) + self.ui.labelVersion.setText("Version: "+__version__+"_"+matplotlib.__version__+"_"+psutil.__version__) def constantUpdate(self): #redirct to global function From ad2c3d421a4fdae7857db665509f6e4da395331e Mon Sep 17 00:00:00 2001 From: Owen Arnold Date: Mon, 12 Jan 2015 09:43:26 +0000 Subject: [PATCH 013/275] refs #10875. Better docs. Changed algorithm documentation as well as documentation in the source code. --- Code/Mantid/Framework/MDEvents/src/Integrate3DEvents.cpp | 8 +++++++- .../docs/source/algorithms/IntegrateEllipsoids-v1.rst | 4 +++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Code/Mantid/Framework/MDEvents/src/Integrate3DEvents.cpp b/Code/Mantid/Framework/MDEvents/src/Integrate3DEvents.cpp index 43069e08714c..826834330a38 100644 --- a/Code/Mantid/Framework/MDEvents/src/Integrate3DEvents.cpp +++ b/Code/Mantid/Framework/MDEvents/src/Integrate3DEvents.cpp @@ -185,11 +185,17 @@ int Integrate3DEvents::numInEllipsoid(std::vector const &events, /** * Given a list of events, associated with a particular peak - * and SHIFTED to be centered at (0,0,0), calculate the 3x3 + * and already SHIFTED to be centered at (0,0,0), calculate the 3x3 * covariance matrix for finding the principal axes of that * local event data. Only events within the specified radius * of (0,0,0) will be used. * + * The covariance matrix can be easily constructed. X, Y, Z of each peak position are the variables we wish to determine + * the covariance. The mean position in each dimension has already been calculated on subtracted, since this corresponds to the centre position of each + * peak, which we knew aprori. The expected values of each correlation test X,X X,Y X,Z e.t.c form the elements of this 3 by 3 matrix, but since the + * probabilities are equal, we can remove them from the sums of the expected values, and simply divide by the number of events for each matrix element. + * Note that the diagonal elements form the variance X,X, Y,Y, Z,Z + * * @param events Vector of V3D objects containing the * Q vectors for a peak, with mean at (0,0,0). * @param matrix A 3x3 matrix that will be filled out with diff --git a/Code/Mantid/docs/source/algorithms/IntegrateEllipsoids-v1.rst b/Code/Mantid/docs/source/algorithms/IntegrateEllipsoids-v1.rst index ef8e0f5483f0..c64b003e7668 100644 --- a/Code/Mantid/docs/source/algorithms/IntegrateEllipsoids-v1.rst +++ b/Code/Mantid/docs/source/algorithms/IntegrateEllipsoids-v1.rst @@ -110,7 +110,7 @@ added to the list of events for a peak provided that the fractional :math:`Q` -vector) is closer to the :math:`h,k,l` of that peak, than to the :math:`h,k,l` of any other peak AND the :math:`Q` -vector for that event is within the specified -radius of the :math:`Q` -vector for that peak. +radius of the :math:`Q` -vector for that peak. This technique makes the algorithm suitable for nuclear peaks, but may not be suitable for magnetic peaks. When the lists of events near the peaks have been built, the three principal axes of the set of events near each peak are found, and the @@ -155,6 +155,8 @@ ellipsoid. The outer surface of the background ellipsoidal shell is an ellipsoidal surface with the same relative axis lengths as the inner surface. +This algorithm uses principle component analysis to determine the principle axis for each peak. For the event list (QLab) associated with each peak, the algorithm determines a covariance matrix, and uses that to establish eigenvectors corresponding to the principle axis (all orthogonal). The sizes of each principle axis are used define the region of which events will be counted/integrated from those already associated with each peak. + Usage ------ From 3b3d8e7e97f3592083becaeb21b69472a42638af Mon Sep 17 00:00:00 2001 From: Anton Piccardo-Selg Date: Mon, 24 Nov 2014 17:20:09 +0000 Subject: [PATCH 014/275] Refs #10627 Adding custom auto color scaling for multiple workspaces --- .../ScaleWorkspace/vtkScaleWorkspace.cxx | 2 +- .../SplatterPlot/SplatterPlot.xml | 22 ++ .../SplatterPlot/vtkSplatterPlot.cxx | 63 ++++++ .../SplatterPlot/vtkSplatterPlot.h | 7 +- .../ParaViewSources/MDEWSource/MDEWSource.xml | 22 ++ .../MDEWSource/vtkMDEWSource.cxx | 63 ++++++ .../MDEWSource/vtkMDEWSource.h | 6 + .../ParaViewSources/MDHWSource/MDHWSource.xml | 22 ++ .../MDHWSource/vtkMDHWSource.cxx | 64 +++++- .../MDHWSource/vtkMDHWSource.h | 6 + .../PeaksSource/PeaksSource.xml | 6 + .../PeaksSource/vtkPeaksSource.cxx | 10 + .../PeaksSource/vtkPeaksSource.h | 5 + Code/Mantid/Vates/VatesAPI/CMakeLists.txt | 4 +- .../MDEWInMemoryLoadingPresenter.h | 10 + .../inc/MantidVatesAPI/MDEWLoadingPresenter.h | 5 +- .../MDHWInMemoryLoadingPresenter.h | 10 + .../inc/MantidVatesAPI/MDHWLoadingPresenter.h | 4 +- .../inc/MantidVatesAPI/MDLoadingPresenter.h | 71 ++++-- .../MantidVatesAPI/MetaDataExtractorUtils.h | 73 ++++++ .../inc/MantidVatesAPI/vtkPeakMarkerFactory.h | 1 - .../MantidVatesAPI/vtkSplatterPlotFactory.h | 26 ++- .../src/MDEWEventNexusLoadingPresenter.cpp | 2 +- .../src/MDEWInMemoryLoadingPresenter.cpp | 32 ++- .../VatesAPI/src/MDEWLoadingPresenter.cpp | 12 +- .../src/MDHWInMemoryLoadingPresenter.cpp | 56 +++-- .../VatesAPI/src/MDHWLoadingPresenter.cpp | 12 +- .../Vates/VatesAPI/src/MDLoadingPresenter.cpp | 164 ++++++++++++++ .../VatesAPI/src/MetaDataExtractorUtils.cpp | 173 ++++++++++++++ .../VatesAPI/src/vtkSplatterPlotFactory.cpp | 42 +++- .../VatesSimpleGui/ViewWidgets/CMakeLists.txt | 2 + .../AutoScaleRangeGenerator.h | 96 ++++++++ .../ColorSelectionWidget.h | 4 +- .../ColorUpdater.h | 18 +- .../MdViewerWidget.h | 2 + .../ViewBase.h | 18 +- .../src/AutoScaleRangeGenerator.cpp | 212 ++++++++++++++++++ .../ViewWidgets/src/ColorSelectionWidget.cpp | 14 +- .../ViewWidgets/src/ColorUpdater.cpp | 136 +++++++---- .../ViewWidgets/src/MdViewerWidget.cpp | 57 ++++- .../ViewWidgets/src/SplatterPlotView.cpp | 2 +- .../ViewWidgets/src/ViewBase.cpp | 79 ++++--- 42 files changed, 1489 insertions(+), 146 deletions(-) create mode 100644 Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetaDataExtractorUtils.h create mode 100644 Code/Mantid/Vates/VatesAPI/src/MDLoadingPresenter.cpp create mode 100644 Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp create mode 100644 Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h create mode 100644 Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx index 3ada6d341793..24296a3f08b3 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx @@ -88,4 +88,4 @@ void vtkScaleWorkspace::SetZScaling(double zScaling) this->Modified(); m_zScaling = zScaling; } -} +} \ No newline at end of file diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/SplatterPlot.xml b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/SplatterPlot.xml index e346b5cc539e..7c4dd4196794 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/SplatterPlot.xml +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/SplatterPlot.xml @@ -29,6 +29,28 @@ The set the viewing limit to the top percentile of the denses boxes. + + + Minimum value of the data set. + + + + + Maximum value of the data set. + + + + diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx index 0b7fae96504e..10113d1ccb9d 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx @@ -168,3 +168,66 @@ void vtkSplatterPlot::updateAlgorithmProgress(double progress, const std::string this->SetProgress(progress); this->SetProgressText(message.c_str()); } + +/** + * Gets the minimum value of the data associated with the + * workspace. + * @return The minimum value of the workspace data. + */ +double vtkSplatterPlot::GetMinValue() +{ + if (NULL == m_presenter) + { + return 0.0; + } + try + { + return m_presenter->getMinValue(); + } + catch (std::runtime_error &) + { + return 0.0; + } +} + +/** + * Gets the maximum value of the data associated with the + * workspace. + * @return The maximum value of the workspace data. + */ +double vtkSplatterPlot::GetMaxValue() +{ + if (NULL == m_presenter) + { + return 0.0; + } + try + { + return m_presenter->getMaxValue(); + } + catch (std::runtime_error &) + { + return 0.0; + } +} + +/** + * Gets the (first) instrument which is associated with the workspace. + * @return The name of the instrument. + */ +const char* vtkSplatterPlot::GetInstrument() +{ + if (NULL == m_presenter) + { + return ""; + } + try + { + return m_presenter->getInstrument().c_str(); + } + catch (std::runtime_error &) + { + return ""; + } +} + diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.h index 48a03de3de4a..ff3c7117e90e 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.h +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.h @@ -23,8 +23,13 @@ class VTK_EXPORT vtkSplatterPlot : public vtkUnstructuredGridAlgorithm void SetNumberOfPoints(int nPoints); void SetTopPercentile(double topPercentile); void updateAlgorithmProgress(double progress, const std::string& message); + /// Getter for the minimum value of the workspace data + double GetMinValue(); + /// Getter for the maximum value of the workspace data + double GetMaxValue(); + /// Getter for the maximum value of the workspace data + const char* GetInstrument(); protected: - vtkSplatterPlot(); ~vtkSplatterPlot(); int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *); diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/MDEWSource.xml b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/MDEWSource.xml index cbe9b98b5ac9..28fb60f14409 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/MDEWSource.xml +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/MDEWSource.xml @@ -56,6 +56,28 @@ information_only="1" si_class="vtkSITimeLabelProperty"> + + + Minimum value of the data set. + + + + + Maximum value of the data set. + + + + diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.cxx index 5e52879c339f..fb147413c482 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.cxx @@ -102,6 +102,69 @@ int vtkMDEWSource::GetSpecialCoordinates() } } +/** + * Gets the minimum value of the data associated with the + * workspace. + * @return The minimum value of the workspace data. + */ +double vtkMDEWSource::GetMinValue() +{ + if (NULL == m_presenter) + { + return 0.0; + } + try + { + return m_presenter->getMinValue(); + } + catch (std::runtime_error &) + { + return 0; + } +} + +/** + * Gets the maximum value of the data associated with the + * workspace. + * @return The maximum value of the workspace data. + */ +double vtkMDEWSource::GetMaxValue() +{ + if (NULL == m_presenter) + { + return 0.0; + } + try + { + return m_presenter->getMaxValue(); + } + catch (std::runtime_error &) + { + return 0; + } +} + +/** + * Gets the (first) instrument which is associated with the workspace. + * @return The name of the instrument. + */ +const char* vtkMDEWSource::GetInstrument() +{ + if (NULL == m_presenter) + { + return ""; + } + try + { + return m_presenter->getInstrument().c_str(); + } + catch (std::runtime_error &) + { + return ""; + } +} + + int vtkMDEWSource::RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *outputVector) { if(m_presenter->canReadFile()) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.h index 80256e24ce89..7716a6d7871a 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.h +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.h @@ -67,6 +67,12 @@ class VTK_EXPORT vtkMDEWSource : public vtkUnstructuredGridAlgorithm const char* GetWorkspaceName(); /// Getter for the workspace type char* GetWorkspaceTypeName(); + /// Getter for the minimum value of the workspace data + double GetMinValue(); + /// Getter for the maximum value of the workspace data + double GetMaxValue(); + /// Getter for the maximum value of the workspace data + const char* GetInstrument(); protected: vtkMDEWSource(); diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/MDHWSource.xml b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/MDHWSource.xml index 2a604e05d04d..14f349f1b176 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/MDHWSource.xml +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/MDHWSource.xml @@ -50,6 +50,28 @@ information_only="1" si_class="vtkSITimeLabelProperty"> + + + Minimum value of the data set. + + + + + Maximum value of the data set. + + + + diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.cxx index a62e1163babb..94f87c99f5f6 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.cxx @@ -88,6 +88,68 @@ int vtkMDHWSource::GetSpecialCoordinates() } } +/** + * Gets the minimum value of the data associated with the + * workspace. + * @return The minimum value of the workspace data. + */ +double vtkMDHWSource::GetMinValue() +{ + if (NULL == m_presenter) + { + return 0.0; + } + try + { + return m_presenter->getMinValue(); + } + catch (std::runtime_error &) + { + return 0.0; + } +} + +/** + * Gets the maximum value of the data associated with the + * workspace. + * @return The maximum value of the workspace data. + */ +double vtkMDHWSource::GetMaxValue() +{ + if (NULL == m_presenter) + { + return 0.0; + } + try + { + return m_presenter->getMaxValue(); + } + catch (std::runtime_error &) + { + return 0.0; + } +} + +/** + * Gets the (first) instrument which is associated with the workspace. + * @return The name of the instrument. + */ +const char* vtkMDHWSource::GetInstrument() +{ + if (NULL == m_presenter) + { + return ""; + } + try + { + return m_presenter->getInstrument().c_str(); + } + catch (std::runtime_error &) + { + return ""; + } +} + int vtkMDHWSource::RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *outputVector) { if(m_presenter->canReadFile()) @@ -136,7 +198,7 @@ int vtkMDHWSource::RequestData(vtkInformation *, vtkInformationVector **, vtkInf } catch (std::invalid_argument &e) { - std::string error = e.what(); + std::string error = e.what(); vtkDebugMacro(<< "Workspace does not have correct information to " << "plot non-orthogonal axes. " << error); } diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.h index e0ed85ed91c8..e5e2c5c366ae 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.h +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.h @@ -65,6 +65,12 @@ class VTK_EXPORT vtkMDHWSource : public vtkUnstructuredGridAlgorithm const char* GetWorkspaceName(); /// Getter for the workspace type char* GetWorkspaceTypeName(); + /// Getter for the minimum value of the workspace data + double GetMinValue(); + /// Getter for the maximum value of the workspace data + double GetMaxValue(); + /// Getter for the maximum value of the workspace data + const char* GetInstrument(); protected: vtkMDHWSource(); diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/PeaksSource.xml b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/PeaksSource.xml index fdded6696b1a..3687d8aa20c7 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/PeaksSource.xml +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/PeaksSource.xml @@ -45,6 +45,12 @@ Set the size of the unintegrated peak markers. + + diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.cxx index 1e831cb6618b..198d57ad75e1 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.cxx @@ -140,6 +140,7 @@ int vtkPeaksSource::RequestInformation(vtkInformation *vtkNotUsed(request), Workspace_sptr result = AnalysisDataService::Instance().retrieve(m_wsName); m_PeakWS = boost::dynamic_pointer_cast(result); m_wsTypeName = m_PeakWS->id(); + m_instrument = m_PeakWS->getInstrument()->getName(); } return 1; } @@ -168,3 +169,12 @@ const char* vtkPeaksSource::GetWorkspaceName() { return m_wsName.c_str(); } + +/** + * Gets the (first) instrument which is associated with the workspace. + * @return The name of the instrument. + */ +const char* vtkPeaksSource::GetInstrument() +{ + return m_instrument.c_str(); +} \ No newline at end of file diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.h index af789cea7f53..88023cc0e2df 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.h +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.h @@ -52,6 +52,8 @@ class VTK_EXPORT vtkPeaksSource : public vtkPolyDataAlgorithm const char* GetWorkspaceName(); /// Getter for the workspace type char* GetWorkspaceTypeName(); + /// Getter for the instrument associated with the workspace + const char* GetInstrument(); protected: vtkPeaksSource(); @@ -75,6 +77,9 @@ class VTK_EXPORT vtkPeaksSource : public vtkPolyDataAlgorithm /// Cached workspace. Mantid::API::IPeaksWorkspace_sptr m_PeakWS; + /// Instrument name. + std::string m_instrument; + vtkPeaksSource(const vtkPeaksSource&); void operator = (const vtkPeaksSource&); }; diff --git a/Code/Mantid/Vates/VatesAPI/CMakeLists.txt b/Code/Mantid/Vates/VatesAPI/CMakeLists.txt index 52ad4171b987..e2c4ed26c1db 100644 --- a/Code/Mantid/Vates/VatesAPI/CMakeLists.txt +++ b/Code/Mantid/Vates/VatesAPI/CMakeLists.txt @@ -16,13 +16,14 @@ src/IMDDimensionComparitor.cpp src/LoadVTK.cpp src/MDEWEventNexusLoadingPresenter.cpp src/MDEWRebinningPresenter.cpp -src/MDEWLoadingPresenter.cpp src/MDEWInMemoryLoadingPresenter.cpp +src/MDEWLoadingPresenter.cpp src/MDHWInMemoryLoadingPresenter.cpp src/MDHWLoadingPresenter.cpp src/MDHWNexusLoadingPresenter.cpp src/MedianAndBelowThresholdRange.cpp src/MetadataToFieldData.cpp +src/MetaDataExtractorUtils.cpp src/NoThresholdRange.cpp src/NullRebinningPresenter.cpp src/ProgressAction.cpp @@ -79,6 +80,7 @@ inc/MantidVatesAPI/MDRebinningPresenter.h inc/MantidVatesAPI/MDRebinningView.h inc/MantidVatesAPI/MDRebinningViewAdapter.h inc/MantidVatesAPI/MedianAndBelowThresholdRange.h +inc/MantidVatesAPI/MetaDataExtractorUtils.h inc/MantidVatesAPI/IgnoreZerosThresholdRange.h inc/MantidVatesAPI/IMDDimensionComparitor.h inc/MantidVatesAPI/MetadataToFieldData.h diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWInMemoryLoadingPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWInMemoryLoadingPresenter.h index 2cf5a0824414..9042a5c9e07a 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWInMemoryLoadingPresenter.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWInMemoryLoadingPresenter.h @@ -37,8 +37,10 @@ namespace Mantid */ class MDLoadingView; + class MetaDataExtractorUtils; class WorkspaceProvider; class vtkDataSetFactory; + class DLLExport MDEWInMemoryLoadingPresenter : public MDEWLoadingPresenter { public: @@ -49,6 +51,10 @@ namespace Mantid virtual bool canReadFile() const; virtual std::string getWorkspaceTypeName(); virtual int getSpecialCoordinates(); + virtual double getMinValue(); + virtual double getMaxValue(); + + private: /// Repository for accessing workspaces. At this level, does not specify how or where from. boost::scoped_ptr m_repository; @@ -56,6 +62,10 @@ namespace Mantid const std::string m_wsName; std::string m_wsTypeName; int m_specialCoords; + double m_minValue; + double m_maxValue; + /// Meta data extractor + boost::scoped_ptr m_metaDataExtractor; }; } } diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWLoadingPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWLoadingPresenter.h index 691239f00f95..b1f8c25142bc 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWLoadingPresenter.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWLoadingPresenter.h @@ -48,6 +48,7 @@ namespace Mantid virtual std::string getTimeStepLabel() const; virtual void setAxisLabels(vtkDataSet* visualDataSet); virtual ~MDEWLoadingPresenter(); + virtual const std::string& getInstrument(); protected: /*--------------------------------------------------------------------------- Common/shared operations and members for all MDEW file-type loading. @@ -66,10 +67,8 @@ namespace Mantid size_t m_recursionDepth; bool m_loadInMemory; bool m_firstLoad; + std::string m_instrument; }; - - - } } diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWInMemoryLoadingPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWInMemoryLoadingPresenter.h index d89fb1df7d36..6bf48b7a0583 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWInMemoryLoadingPresenter.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWInMemoryLoadingPresenter.h @@ -37,7 +37,9 @@ namespace Mantid class MDLoadingView; class WorkspaceProvider; + class MetaDataExtractorUtils; class vtkDataSetFactory; + class DLLExport MDHWInMemoryLoadingPresenter : public MDHWLoadingPresenter { public: @@ -48,6 +50,10 @@ namespace Mantid virtual bool canReadFile() const; virtual std::string getWorkspaceTypeName(); virtual int getSpecialCoordinates(); + virtual double getMinValue(); + virtual double getMaxValue(); + + private: /// Repository for accessing workspaces. At this level, does not specify how or where from. boost::scoped_ptr m_repository; @@ -55,6 +61,10 @@ namespace Mantid const std::string m_wsName; std::string m_wsTypeName; int m_specialCoords; + double m_minValue; + double m_maxValue; + /// Meta data extractor + boost::scoped_ptr m_metaDataExtractor; }; } } diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWLoadingPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWLoadingPresenter.h index 9503fcb7af89..561beda64483 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWLoadingPresenter.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWLoadingPresenter.h @@ -49,6 +49,8 @@ namespace Mantid virtual void setAxisLabels(vtkDataSet* visualDataSet); virtual void makeNonOrthogonal(vtkDataSet* visualDataSet); virtual ~MDHWLoadingPresenter(); + virtual const std::string& getInstrument(); + protected: /*--------------------------------------------------------------------------- Common/shared operations and members for all MDHW file-type loading. @@ -68,8 +70,8 @@ namespace Mantid double m_time; bool m_loadInMemory; bool m_firstLoad; + std::string m_instrument; }; - } } diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDLoadingPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDLoadingPresenter.h index ba96a23e793e..fed7260ca46a 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDLoadingPresenter.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDLoadingPresenter.h @@ -42,31 +42,54 @@ namespace Mantid */ class DLLExport MDLoadingPresenter { - public: - virtual vtkDataSet* execute(vtkDataSetFactory* factory, ProgressAction& rebinningProgressUpdate, ProgressAction& drawingProgressUpdate) = 0; - virtual void executeLoadMetadata() = 0; - virtual bool hasTDimensionAvailable() const = 0; - virtual std::vector getTimeStepValues() const = 0; - virtual std::string getTimeStepLabel() const = 0; - virtual void setAxisLabels(vtkDataSet* visualDataSet) = 0; - virtual void makeNonOrthogonal(vtkDataSet* visualDataSet) - { - // This is a no-op function for most loaders. - UNUSED_ARG(visualDataSet); - } - virtual bool canReadFile() const = 0; - virtual const std::string& getGeometryXML() const = 0; - virtual ~MDLoadingPresenter(){} - virtual std::string getWorkspaceTypeName() - { - return "NotSet"; - } - virtual int getSpecialCoordinates() - { - return API::None; - } - }; + public: + virtual vtkDataSet* execute(vtkDataSetFactory* factory, ProgressAction& rebinningProgressUpdate, ProgressAction& drawingProgressUpdate) = 0; + virtual void executeLoadMetadata() = 0; + virtual bool hasTDimensionAvailable() const = 0; + virtual std::vector getTimeStepValues() const = 0; + virtual std::string getTimeStepLabel() const = 0; + virtual void setAxisLabels(vtkDataSet* visualDataSet) = 0; + virtual void makeNonOrthogonal(vtkDataSet* visualDataSet) + { + // This is a no-op function for most loaders. + UNUSED_ARG(visualDataSet); + } + virtual bool canReadFile() const = 0; + virtual const std::string& getGeometryXML() const = 0; + virtual ~MDLoadingPresenter(){} + virtual std::string getWorkspaceTypeName() + { + return "NotSet"; + } + virtual int getSpecialCoordinates() + { + return API::None; + } + + /** + * Gets the minimum value. + * @returns The minimum value of the dataset or 0.0 + */ + virtual double getMinValue() + { + return 0.0; + }; + /** + * Gets the maximum value. + * @returns The maximum value of the dataset or 0.0 + */ + virtual double getMaxValue() + { + return 0.0; + }; + + /** + * Gets the instrument associated with the dataset. + * @returns The instrument associated with the dataset. + */ + virtual const std::string& getInstrument() = 0; + }; } } diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetaDataExtractorUtils.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetaDataExtractorUtils.h new file mode 100644 index 000000000000..126e4746f410 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetaDataExtractorUtils.h @@ -0,0 +1,73 @@ +#ifndef MANTID_VATES_METADATAEXTRACTORUTILS_H_ +#define MANTID_VATES_METADATAEXTRACTORUTILS_H_ + +#include "MantidAPI/IMDWorkspace.h" +#include "MantidAPI/IMDIterator.h" +#include "qwt/qwt_double_interval.h" +#include +#include + + +/** + * Class with utility methdos to extract meta data information from a IMDWorkspace. + * + * @date November 21, 2014 + * + * Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + * + * This file is part of Mantid. + * + * Mantid is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Mantid is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * File change history is stored at: + * Code Documentation is available at: + */ +namespace Mantid +{ + namespace VATES + { + + class DLLExport MetaDataExtractorUtils + { + public: + + MetaDataExtractorUtils(); + + ~MetaDataExtractorUtils(); + + /** + * Get the minimum, maximum pair from the workspace + * @param workspace A pointer to the workspace + * @return A pair of minimum and maximum values. + */ + QwtDoubleInterval getMinAndMax(Mantid::API::IMDWorkspace_sptr workspace); + + /** + * Extracts the instrument from the workspace. + * @param A pointer to a workspace. + * @returns The instrument. + */ + std::string extractInstrument(Mantid::API::IMDWorkspace_sptr workspace); + + private: + /** + * Get the range of data values from an MD iterator + * @param it Iterator for a general MD workspace. + * @retunrs A maximum and minimum pair. + */ + QwtDoubleInterval getRange(Mantid::API::IMDIterator* it); + }; + } +} +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkPeakMarkerFactory.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkPeakMarkerFactory.h index b941d0d7af0f..c523a6859d83 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkPeakMarkerFactory.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkPeakMarkerFactory.h @@ -104,7 +104,6 @@ class DLLExport vtkPeakMarkerFactory /// peak radius value. double m_peakRadius; - }; } } diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h index 0a94fd622734..3ad5c3ef481d 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h @@ -2,14 +2,17 @@ #define MANTID_VATES_vtkSplatterPlotFactory_H_ #include "MantidAPI/IMDEventWorkspace.h" -#include "MantidAPI/IMDHistoWorkspace.h" +#include "MantidVatesAPI/MetaDataExtractorUtils.h" #include "MantidAPI/IMDNode.h" +#include "MantidAPI/IMDHistoWorkspace.h" #include "MantidMDEvents/MDEventFactory.h" #include "MantidMDEvents/MDEventWorkspace.h" #include "MantidVatesAPI/ThresholdRange.h" #include "MantidVatesAPI/vtkDataSetFactory.h" #include #include +#include + using Mantid::MDEvents::MDEventWorkspace; @@ -79,6 +82,15 @@ class DLLExport vtkSplatterPlotFactory : public vtkDataSetFactory /// Set the time value. void setTime(double timeStep); + /// Get the max value of the data set + virtual double getMinValue(); + + /// Get the min value of the data set + virtual double getMaxValue(); + + /// Getter for the instrument + virtual const std::string& getInstrument(); + private: template @@ -134,6 +146,18 @@ class DLLExport vtkSplatterPlotFactory : public vtkDataSetFactory /// Time value. double m_time; + + /// Min data value + mutable double m_minValue; + + /// Max data value; + mutable double m_maxValue; + + /// Instrument + mutable std::string m_instrument; + + /// Meta data extractor + boost::scoped_ptr m_metaDataExtractor; }; } diff --git a/Code/Mantid/Vates/VatesAPI/src/MDEWEventNexusLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDEWEventNexusLoadingPresenter.cpp index b2536117f9cb..dd443643d899 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDEWEventNexusLoadingPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDEWEventNexusLoadingPresenter.cpp @@ -15,7 +15,7 @@ namespace Mantid namespace VATES { - /* + /* Constructor @param view : MVP view @param filename : name of file to load diff --git a/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp index 8c184f7c557a..6845b9da896e 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp @@ -1,9 +1,11 @@ #include "MantidVatesAPI/MDEWInMemoryLoadingPresenter.h" #include "MantidVatesAPI/MDLoadingView.h" +#include "MantidVatesAPI/MetaDataExtractorUtils.h" #include "MantidVatesAPI/ProgressAction.h" #include "MantidVatesAPI/vtkDataSetFactory.h" #include "MantidVatesAPI/WorkspaceProvider.h" #include "MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h" +#include "qwt/qwt_double_interval.h" #include namespace Mantid @@ -20,7 +22,8 @@ namespace Mantid @throw invalid_argument if the repository is null @throw invalid_arument if view is null */ - MDEWInMemoryLoadingPresenter::MDEWInMemoryLoadingPresenter(MDLoadingView* view, WorkspaceProvider* repository, std::string wsName) : MDEWLoadingPresenter(view), m_repository(repository), m_wsName(wsName), m_wsTypeName(""), m_specialCoords(-1) + MDEWInMemoryLoadingPresenter::MDEWInMemoryLoadingPresenter(MDLoadingView* view, WorkspaceProvider* repository, std::string wsName) : MDEWLoadingPresenter(view), + m_repository(repository), m_wsName(wsName), m_wsTypeName(""), m_specialCoords(-1), m_metaDataExtractor(new MetaDataExtractorUtils()) { if(m_wsName.empty()) { @@ -98,6 +101,15 @@ namespace Mantid IMDEventWorkspace_sptr eventWs = boost::dynamic_pointer_cast(ws); m_wsTypeName = eventWs->id(); m_specialCoords = eventWs->getSpecialCoordinateSystem(); + + // Set the minimum and maximum of the workspace data. + QwtDoubleInterval minMaxContainer = m_metaDataExtractor->getMinAndMax(eventWs); + m_minValue = minMaxContainer.minValue(); + m_maxValue = minMaxContainer.maxValue(); + + // Set the instrument which is associated with the workspace. + m_instrument = m_metaDataExtractor->extractInstrument(eventWs); + //Call base-class extraction method. this->extractMetadata(eventWs); } @@ -125,5 +137,23 @@ namespace Mantid { return m_specialCoords; } + + /** + * Getter for the minimum value; + * @return The minimum value of the data set. + */ + double MDEWInMemoryLoadingPresenter::getMinValue() + { + return m_minValue; + } + + /** + * Getter for the maximum value; + * @return The maximum value of the data set. + */ + double MDEWInMemoryLoadingPresenter::getMaxValue() + { + return m_maxValue; + } } } diff --git a/Code/Mantid/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp index a53babad7b30..6ac8974bdb2e 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp @@ -23,7 +23,8 @@ namespace Mantid m_time(-1), m_recursionDepth(0), m_loadInMemory(false), - m_firstLoad(true) + m_firstLoad(true), + m_instrument("") { Mantid::API::FrameworkManager::Instance(); } @@ -231,5 +232,14 @@ namespace Mantid } return tDimension->getName() + " (" + tDimension->getUnits().ascii() + ")"; } + + /** + * Getter for the instrument. + * @returns The name of the instrument which is associated with the workspace. + */ + const std::string& MDEWLoadingPresenter::getInstrument() + { + return m_instrument; + } } } diff --git a/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp index e14427e1d4dd..56f674edb02a 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp @@ -1,9 +1,11 @@ #include "MantidVatesAPI/MDHWInMemoryLoadingPresenter.h" #include "MantidVatesAPI/MDLoadingView.h" +#include "MantidVatesAPI/MetaDataExtractorUtils.h" #include "MantidVatesAPI/ProgressAction.h" #include "MantidVatesAPI/vtkDataSetFactory.h" #include "MantidVatesAPI/WorkspaceProvider.h" #include "MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h" +#include "qwt/qwt_double_interval.h" #include namespace Mantid @@ -20,21 +22,22 @@ namespace Mantid @throw invalid_argument if the repository is null @throw invalid_arument if view is null */ - MDHWInMemoryLoadingPresenter::MDHWInMemoryLoadingPresenter(MDLoadingView* view, WorkspaceProvider* repository, std::string wsName) : MDHWLoadingPresenter(view), m_repository(repository), m_wsName(wsName), m_wsTypeName(""), m_specialCoords(-1) + MDHWInMemoryLoadingPresenter::MDHWInMemoryLoadingPresenter(MDLoadingView* view, WorkspaceProvider* repository, std::string wsName) : MDHWLoadingPresenter(view), + m_repository(repository), m_wsName(wsName), m_wsTypeName(""), m_specialCoords(-1), m_metaDataExtractor(new MetaDataExtractorUtils()) + { + if(m_wsName.empty()) { - if(m_wsName.empty()) - { - throw std::invalid_argument("The workspace name is empty."); - } - if(NULL == repository) - { - throw std::invalid_argument("The repository is NULL"); - } - if(NULL == m_view) - { - throw std::invalid_argument("View is NULL."); - } + throw std::invalid_argument("The workspace name is empty."); + } + if(NULL == repository) + { + throw std::invalid_argument("The repository is NULL"); + } + if(NULL == m_view) + { + throw std::invalid_argument("View is NULL."); } + } /* Indicates whether this presenter is capable of handling the type of file that is attempted to be loaded. @@ -98,6 +101,15 @@ namespace Mantid IMDHistoWorkspace_sptr histoWs = boost::dynamic_pointer_cast(ws); m_wsTypeName = histoWs->id(); m_specialCoords = histoWs->getSpecialCoordinateSystem(); + + // Set the minimum and maximum of the workspace data. + QwtDoubleInterval minMaxContainer = m_metaDataExtractor->getMinAndMax(histoWs); + m_minValue = minMaxContainer.minValue(); + m_maxValue = minMaxContainer.maxValue(); + + // Set the instrument which is associated with the workspace. + m_instrument =m_metaDataExtractor->extractInstrument(histoWs); + //Call base-class extraction method. this->extractMetadata(histoWs); } @@ -125,5 +137,23 @@ namespace Mantid { return m_specialCoords; } + + /** + * Getter for the minimum value; + * @return The minimum value of the data set. + */ + double MDHWInMemoryLoadingPresenter::getMinValue() + { + return m_minValue; + } + + /** + * Getter for the maximum value; + * @return The maximum value of the data set. + */ + double MDHWInMemoryLoadingPresenter::getMaxValue() + { + return m_maxValue; + } } } diff --git a/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp index 07cb4bd2a61d..4cc2951dca03 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp @@ -24,7 +24,8 @@ namespace Mantid m_isSetup(false), m_time(-1), m_loadInMemory(false), - m_firstLoad(true) + m_firstLoad(true), + m_instrument("") { Mantid::API::FrameworkManager::Instance(); } @@ -236,5 +237,14 @@ namespace Mantid } return tDimension->getName() + " (" + tDimension->getUnits().ascii() + ")"; } + + /** + * Getter for the instrument. + * @returns The name of the instrument which is associated with the workspace. + */ + const std::string& MDHWLoadingPresenter::getInstrument() + { + return m_instrument; + } } } diff --git a/Code/Mantid/Vates/VatesAPI/src/MDLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDLoadingPresenter.cpp new file mode 100644 index 000000000000..45d07bd3cc5c --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/MDLoadingPresenter.cpp @@ -0,0 +1,164 @@ +#include "MantidVatesAPI/MDLoadingPresenter.h" +#include "qwt/qwt_double_interval.h" +#include "MantidAPI/IMDIterator.h" +#include "MantidAPI/IMDEventWorkspace.h" +#include "MantidAPI/IMDHistoWorkspace.h" +#include "MantidAPI/IPeaksWorkspace.h" +#include "MantidAPI/IMDWorkspace.h" +#include "MantidKernel/Logger.h" +#include "boost/pointer_cast.hpp" + +namespace Mantid +{ + namespace VATES + { + namespace + { + /// Static logger + Kernel::Logger g_log("MDLoadingPresenter"); + } + /** + * Extract the instrument information from the workspace. If there + * is more than one instrument involved, then extract the first instrument + * from the list. + * @param workspace A shared pointer to the workspace. + * @returns The instrument name or an empty string. + */ + std::string MDLoadingPresenter::extractInstrument(Mantid::API::IMDWorkspace_sptr workspace) + { + Mantid::API::IMDEventWorkspace_sptr eventWorkspace = boost::dynamic_pointer_cast(workspace); + Mantid::API::IMDHistoWorkspace_sptr histoWorkspace = boost::dynamic_pointer_cast(workspace); + + std::string instrument; + + // Check which workspace is currently used and that it contains at least one instrument. + if (eventWorkspace) + { + if (eventWorkspace->getNumExperimentInfo() > 0) + { + instrument = eventWorkspace->getExperimentInfo(0)->getInstrument()->getName(); + } else + { + g_log.warning() << "The event workspace does not have any instruments. \n"; + + instrument = ""; + } + } else if (histoWorkspace) + { + if (histoWorkspace->getNumExperimentInfo() > 0) + { + instrument = histoWorkspace->getExperimentInfo(0)->getInstrument()->getName(); + } else + { + g_log.warning() << "The histo workspace does not have any instruments. \n"; + + instrument = ""; + } + } else + { + g_log.warning() << "The workspace does not seem to be either event or histo. \n"; + instrument = ""; + } + + return instrument; + } + + /** + * Set the minimum and maximum of the workspace data. Code essentially copied from SignalRange.cpp + * @param histWs A reference to an IMD workspace + * @returns The minimum and maximum value of the workspace dataset. + */ + QwtDoubleInterval MDLoadingPresenter::getMinAndMax(Mantid::API::IMDWorkspace_sptr workspace) + { + auto iterators = workspace->createIterators(PARALLEL_GET_MAX_THREADS, 0); + + std::vector intervals(iterators.size()); + // cppcheck-suppress syntaxError + PRAGMA_OMP( parallel for schedule(dynamic, 1)) + for (int i=0; i < int(iterators.size()); i++) + { + Mantid::API::IMDIterator * it = iterators[i]; + QwtDoubleInterval range = this->getRange(it); + intervals[i] = range; + // don't delete iterator in parallel. MSVC doesn't like it + // when the iterator points to a mock object. + } + + // Combine the overall min/max + double minSignal = DBL_MAX; + double maxSignal = -DBL_MAX; + auto inf = std::numeric_limits::infinity(); + for (size_t i=0; i < iterators.size(); i++) + { + delete iterators[i]; + + double signal; + signal = intervals[i].minValue(); + if (signal != inf && signal < minSignal) minSignal = signal; + + signal = intervals[i].maxValue(); + if (signal != inf && signal > maxSignal) maxSignal = signal; + } + + if (minSignal == DBL_MAX) + { + minSignal = 0.0; + maxSignal = 1.0; + } + + QwtDoubleInterval minMaxContainer; + + if (minSignal < maxSignal) + minMaxContainer = QwtDoubleInterval(minSignal, maxSignal); + else + { + if (minSignal != 0) + // Possibly only one value in range + minMaxContainer = QwtDoubleInterval(minSignal*0.5, minSignal*1.5); + else + // Other default value + minMaxContainer = QwtDoubleInterval(0., 1.0); + } + + return minMaxContainer; + } + + /** + * Get the range of a workspace dataset for a single iterator. Code the same as in SignalRange.cpp + * @param it :: IMDIterator of what to find + * @return the min/max range, or INFINITY if not found + */ + QwtDoubleInterval MDLoadingPresenter::getRange(Mantid::API::IMDIterator * it) + { + if (!it) + return QwtDoubleInterval(0., 1.0); + if (!it->valid()) + return QwtDoubleInterval(0., 1.0); + + // Use no normalization + it->setNormalization(Mantid::API::VolumeNormalization); + + double minSignal = DBL_MAX; + double maxSignal = -DBL_MAX; + auto inf = std::numeric_limits::infinity(); + do + { + double signal = it->getNormalizedSignal(); + // Skip any 'infs' as it screws up the color scale + if (signal != inf) + { + if (signal < minSignal) minSignal = signal; + if (signal > maxSignal) maxSignal = signal; + } + } while (it->next()); + + + if (minSignal == DBL_MAX) + { + minSignal = inf; + maxSignal = inf; + } + return QwtDoubleInterval(minSignal, maxSignal); + } + } +} \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp b/Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp new file mode 100644 index 000000000000..1be903ba7458 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp @@ -0,0 +1,173 @@ +#include "MantidVatesAPI/MetaDataExtractorUtils.h" +#include "qwt/qwt_double_interval.h" +#include "MantidAPI/IMDIterator.h" +#include "MantidAPI/IMDEventWorkspace.h" +#include "MantidAPI/IMDHistoWorkspace.h" +#include "MantidAPI/IPeaksWorkspace.h" +#include "MantidAPI/IMDWorkspace.h" +#include "MantidKernel/Logger.h" +#include "boost/pointer_cast.hpp" + +namespace Mantid +{ + namespace VATES + { + namespace + { + /// Static logger + Kernel::Logger g_log("MetaDataExtractorUtils"); + } + + MetaDataExtractorUtils::MetaDataExtractorUtils() + { + } + + MetaDataExtractorUtils::~MetaDataExtractorUtils() + { + } + + /** + * Extract the instrument information from the workspace. If there + * is more than one instrument involved, then extract the first instrument + * from the list. + * @param workspace A shared pointer to the workspace. + * @returns The instrument name or an empty string. + */ + std::string MetaDataExtractorUtils::extractInstrument(Mantid::API::IMDWorkspace_sptr workspace) + { + Mantid::API::IMDEventWorkspace_sptr eventWorkspace = boost::dynamic_pointer_cast(workspace); + Mantid::API::IMDHistoWorkspace_sptr histoWorkspace = boost::dynamic_pointer_cast(workspace); + + std::string instrument; + + // Check which workspace is currently used and that it contains at least one instrument. + if (eventWorkspace) + { + if (eventWorkspace->getNumExperimentInfo() > 0) + { + instrument = eventWorkspace->getExperimentInfo(0)->getInstrument()->getName(); + } else + { + g_log.warning() << "The event workspace does not have any instruments. \n"; + + instrument = ""; + } + } else if (histoWorkspace) + { + if (histoWorkspace->getNumExperimentInfo() > 0) + { + instrument = histoWorkspace->getExperimentInfo(0)->getInstrument()->getName(); + } else + { + g_log.warning() << "The histo workspace does not have any instruments. \n"; + + instrument = ""; + } + } else + { + g_log.warning() << "The workspace does not seem to be either event or histo. \n"; + instrument = ""; + } + + return instrument; + } + + /** + * Set the minimum and maximum of the workspace data. Code essentially copied from SignalRange.cpp + * @param histWs A reference to an IMD workspace + * @returns The minimum and maximum value of the workspace dataset. + */ + QwtDoubleInterval MetaDataExtractorUtils::getMinAndMax(Mantid::API::IMDWorkspace_sptr workspace) + { + auto iterators = workspace->createIterators(PARALLEL_GET_MAX_THREADS, 0); + + std::vector intervals(iterators.size()); + // cppcheck-suppress syntaxError + PRAGMA_OMP( parallel for schedule(dynamic, 1)) + for (int i=0; i < int(iterators.size()); i++) + { + Mantid::API::IMDIterator * it = iterators[i]; + QwtDoubleInterval range = this->getRange(it); + intervals[i] = range; + // don't delete iterator in parallel. MSVC doesn't like it + // when the iterator points to a mock object. + } + + // Combine the overall min/max + double minSignal = DBL_MAX; + double maxSignal = -DBL_MAX; + auto inf = std::numeric_limits::infinity(); + for (size_t i=0; i < iterators.size(); i++) + { + delete iterators[i]; + + double signal; + signal = intervals[i].minValue(); + if (signal != inf && signal < minSignal) minSignal = signal; + + signal = intervals[i].maxValue(); + if (signal != inf && signal > maxSignal) maxSignal = signal; + } + + if (minSignal == DBL_MAX) + { + minSignal = 0.0; + maxSignal = 1.0; + } + + QwtDoubleInterval minMaxContainer; + + if (minSignal < maxSignal) + minMaxContainer = QwtDoubleInterval(minSignal, maxSignal); + else + { + if (minSignal != 0) + // Possibly only one value in range + minMaxContainer = QwtDoubleInterval(minSignal*0.5, minSignal*1.5); + else + // Other default value + minMaxContainer = QwtDoubleInterval(0., 1.0); + } + + return minMaxContainer; + } + + /** + * Get the range of a workspace dataset for a single iterator. Code the same as in SignalRange.cpp + * @param it :: IMDIterator of what to find + * @return the min/max range, or INFINITY if not found + */ + QwtDoubleInterval MetaDataExtractorUtils::getRange(Mantid::API::IMDIterator * it) + { + if (!it) + return QwtDoubleInterval(0., 1.0); + if (!it->valid()) + return QwtDoubleInterval(0., 1.0); + + // Use no normalization + it->setNormalization(Mantid::API::VolumeNormalization); + + double minSignal = DBL_MAX; + double maxSignal = -DBL_MAX; + auto inf = std::numeric_limits::infinity(); + do + { + double signal = it->getNormalizedSignal(); + // Skip any 'infs' as it screws up the color scale + if (signal != inf) + { + if (signal < minSignal) minSignal = signal; + if (signal > maxSignal) maxSignal = signal; + } + } while (it->next()); + + + if (minSignal == DBL_MAX) + { + minSignal = inf; + maxSignal = inf; + } + return QwtDoubleInterval(minSignal, maxSignal); + } + } +} \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp index 8e74701ced55..6efbe8065e92 100644 --- a/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp @@ -1,10 +1,12 @@ #include "MantidVatesAPI/vtkSplatterPlotFactory.h" +#include "MantidVatesAPI/MetaDataExtractorUtils.h" #include "MantidAPI/IMDEventWorkspace.h" #include "MantidAPI/IMDHistoWorkspace.h" #include "MantidKernel/CPUTimer.h" #include "MantidKernel/ReadLock.h" #include "MantidMDEvents/MDEventFactory.h" +#include "MantidGeometry/MDGeometry/MDHistoDimension.h" #include "MantidVatesAPI/ProgressAction.h" #include "MantidVatesAPI/Common.h" @@ -19,6 +21,7 @@ #include #include +#include "qwt/qwt_double_interval.h" using namespace Mantid::API; using namespace Mantid::MDEvents; @@ -55,7 +58,8 @@ namespace VATES m_numPoints(numPoints), m_percentToUse(percentToUse), m_buildSortedList(true), m_wsName(""), dataSet(NULL), slice(false), sliceMask(NULL), sliceImplicitFunction(NULL), - m_time(0.0) + m_time(0.0), + m_metaDataExtractor(new MetaDataExtractorUtils()) { } @@ -526,10 +530,18 @@ namespace VATES this->slice = false; } + // Set the bounds + QwtDoubleInterval minMaxValue = m_metaDataExtractor->getMinAndMax(m_workspace); + m_minValue = minMaxValue.minValue(); + m_maxValue = minMaxValue.maxValue(); + + // Set the instrument + m_instrument = m_metaDataExtractor->extractInstrument(m_workspace); + // Check for the workspace type, i.e. if it is MDHisto or MDEvent IMDEventWorkspace_sptr eventWorkspace = boost::dynamic_pointer_cast(m_workspace); IMDHistoWorkspace_sptr histoWorkspace = boost::dynamic_pointer_cast(m_workspace); - + if (eventWorkspace) { // Macro to call the right instance of the @@ -636,5 +648,31 @@ namespace VATES m_time = time; } + /** + * Getter for the minimum value; + * @return The minimum value of the data set. + */ + double vtkSplatterPlotFactory::getMinValue() + { + return m_minValue; + } + + /** + * Getter for the maximum value; + * @return The maximum value of the data set. + */ + double vtkSplatterPlotFactory::getMaxValue() + { + return m_maxValue; + } + + /** + * Getter for the instrument. + * @returns The name of the instrument which is associated with the workspace. + */ + const std::string& vtkSplatterPlotFactory::getInstrument() + { + return m_instrument; + } } } diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt index 8a8ec6d7f638..df45ab427a9f 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt @@ -2,6 +2,7 @@ project( MantidVatesSimpleGuiViewWidgets ) # These are the C++ files to be compiled. set( INCLUDE_FILES + inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h inc/MantidVatesSimpleGuiViewWidgets/ColorUpdater.h inc/MantidVatesSimpleGuiViewWidgets/LibHelper.h @@ -17,6 +18,7 @@ set( INCLUDE_FILES ) set( SOURCE_FILES + src/AutoScaleRangeGenerator.cpp src/ColorSelectionWidget.cpp src/ColorUpdater.cpp src/MdViewerWidget.cpp diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h new file mode 100644 index 000000000000..ccc897cbeaa3 --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h @@ -0,0 +1,96 @@ +#ifndef AUTOSCALERANGEGENERATOR_H +#define AUTOSCALERANGEGENERATOR_H + +/** + Generates information for the color scale, e.g. minimum level, maximum level, + log scale. + + @date 18/11/2014 + + Copyright © 2007-11 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: . + Code Documentation is available at: + +*/ +#include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h" +#include + +class pqPipelineSource; + +namespace Mantid +{ +namespace Vates +{ +namespace SimpleGui +{ + +typedef struct VsiColorScale +{ + double maxValue; + + double minValue; + + bool useLogScale; +} VsiColorScale; + +class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS AutoScaleRangeGenerator +{ + public: + AutoScaleRangeGenerator(); + + virtual ~AutoScaleRangeGenerator() {}; + + /// Creates a color scale entity. + VsiColorScale getColorScale(); + + /// Enum for different modes + typedef enum COLORSCALEMODE{STANDARD, TECHNIQUEDEPENDENT, OFFSET} COLORSCALEMODE; + + private: + /// Selected color scale mode. + COLORSCALEMODE mode; + + /// Default value for the color scale + double defaultValue; + + /// Get the color scale for the standard selection. + VsiColorScale getStandardColorScale(); + + /// Get all ParaView sources from the active server. + QList getAllPVSources(); + + /// Make sure that the color scale is valid. + void sanityCheck(VsiColorScale& colorscale); + + /** + * Extract the min and max values of a source. If we are dealing with a filter which does not + * have the information then look upstream for the information + * @param source A pointer to a source + * @param minValueBuffer A reference to a min value. + * @param maxValueBuffer A reference to a max value. + */ + void AutoScaleRangeGenerator::setMinBufferAndMaxBuffer(pqPipelineSource* source, double& minValue, double& maxValue); + +}; + +} +} +} +#endif + diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h index c212743b1126..4316c0cd0a04 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h @@ -75,7 +75,7 @@ public slots: /** * Signal to let views know that autoscaling is on. */ - void autoScale(); + void autoScale(ColorSelectionWidget*); /** * Signal to pass on information about a change to the color map. * @param model the color map to send @@ -103,6 +103,8 @@ protected slots: void loadPreset(); /// Set log color scaling. void useLogScaling(int state); + /// Set log scaling button + void onSetLogScale(bool state); private: /// Add color maps from XML files. diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorUpdater.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorUpdater.h index f9991a5fa8c7..4c9d74f9e69f 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorUpdater.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorUpdater.h @@ -2,10 +2,11 @@ #define COLORUPDATER_H_ #include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h" - +#include "MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h" #include class pqColorMapModel; +class pqDataRepresentation; class pqPipelineRepresentation; namespace Mantid @@ -54,10 +55,9 @@ class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS ColorUpdater /** * Set the color scale back to the original bounds. - * @param repr the representation to auto color scale - * @return the minimum and maximum values for the representation data range + * @return A struct with minimum, maximum and if log scale is used. */ - QPair autoScale(pqPipelineRepresentation *repr); + VsiColorScale autoScale(); /** * Set the requested color map on the data. * @param repr the representation to change the color map on @@ -67,12 +67,10 @@ class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS ColorUpdater const pqColorMapModel *model); /** * Set the data color scale range to the requested bounds. - * @param repr the representation to change the color scale on * @param min the minimum bound for the color scale * @param max the maximum bound for the color scale */ - void colorScaleChange(pqPipelineRepresentation *repr, double min, - double max); + void colorScaleChange(double min, double max); /// Get the auto scaling state. bool isAutoScale(); /// Get the logarithmic scaling state. @@ -81,22 +79,24 @@ class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS ColorUpdater double getMaximumRange(); /// Get the minimum color scaling range value. double getMinimumRange(); + /** * Set logarithmic color scaling on the data. - * @param repr the representation to set logarithmic color scale * @param state flag to determine whether or not to use log color scaling */ - void logScale(pqPipelineRepresentation *repr, int state); + void logScale(int state); /// Print internal information. void print(); /// Update the internal state. void updateState(ColorSelectionWidget *cs); private: + void updateLookupTable(pqDataRepresentation* representation); ///< Updates the lookup tables. bool autoScaleState; ///< Holder for the auto scaling state bool logScaleState; ///< Holder for the log scaling state double minScale; ///< Holder for the minimum color range state double maxScale; ///< Holder for the maximum color range state + AutoScaleRangeGenerator autoScaleRangeGenerator; ///< Holds a range generator for auto scale. }; } diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h index c103e5173430..2ea0f5bd9198 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h @@ -175,6 +175,8 @@ protected slots: bool checkIfTechniqueContainsKeyword(const std::set& techniques, const std::string& keyword) const; /// Reset the current view to the appropriate initial view. void resetCurrentView(int workspaceType, const std::string& instrumentName); + /// Set visibility listener + void setVisibilityListener(); }; } // SimpleGui diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h index 401dd2de5efc..3e44d4cd43ed 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h @@ -10,6 +10,7 @@ #include class pqColorMapModel; +class pqDataRepresentation; class pqObjectBuilder; class pqPipelineSource; class pqPipelineRepresentation; @@ -123,7 +124,7 @@ class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS ViewBase : public QWidget public slots: /// Set the color scale back to the original bounds. - void onAutoScale(); + void onAutoScale(ColorSelectionWidget* colorSelectionWidget); /// Set the requested color map on the data. void onColorMapChange(const pqColorMapModel *model); /// Set the data color scale range to the requested bounds. @@ -137,13 +138,15 @@ public slots: /// Reset center of rotation to given point. void onResetCenterToPoint(double x, double y, double z); /// Set color scaling for a view. - void setColorsForView(); + void setColorsForView(ColorSelectionWidget *colorScale); /// Setup the animation controls. void updateAnimationControls(); /// Provide updates to UI. virtual void updateUI(); /// Provide updates to View virtual void updateView(); + /// React when the visibility of a representation changes + virtual void onVisibilityChanged(pqPipelineSource *source, pqDataRepresentation *representation); signals: /** @@ -185,6 +188,17 @@ public slots: * @param state Whether or not to enable to view mode buttons. */ void setViewsStatus(ModeControlWidget::Views view, bool state); + /** + * Singal to tell other elements that the log scale was altered programatically + * @param State flag wheter or not to enable the + */ + void setLogScale(bool state); + +protected: + /** + * Set the color scale for auto color scaling. + */ + void ViewBase::setAutoColorScale(); private: Q_DISABLE_COPY(ViewBase) diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp new file mode 100644 index 000000000000..8d4a7fa821f9 --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp @@ -0,0 +1,212 @@ +#include "MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h" + +// Have to deal with ParaView warnings and Intel compiler the hard way. +#if defined(__INTEL_COMPILER) + #pragma warning disable 1170 +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Mantid +{ +namespace Vates +{ +namespace SimpleGui +{ + /** + * Note that the mode is currently set to standard. + */ + AutoScaleRangeGenerator::AutoScaleRangeGenerator() : mode(STANDARD), defaultValue(1e-2) {}; + + /** + * Get the auto color scale which depends on the mode setting. + * @retruns A VsiColorScale data structure which contains information + * regarding the min and max value as well as if the log + * scale is being used. + */ + VsiColorScale AutoScaleRangeGenerator::getColorScale() + { + VsiColorScale colorScaleContainer; + + // Select a colorscale depending on the selected mode + switch(mode) + { + case(STANDARD): + colorScaleContainer = getStandardColorScale(); + break; + + case(TECHNIQUEDEPENDENT): + // Implement technique-dependence here + case(OFFSET): + // Implement color scale which accounts for noise floor here. + default: + colorScaleContainer.maxValue = 1.0; + colorScaleContainer.minValue = 0.0; + colorScaleContainer.useLogScale= FALSE; + + break; + } + + // Make sure that the color scale is valid, and if not set default values. + sanityCheck(colorScaleContainer); + + return colorScaleContainer; + } + + /** + * The standard way of creating a colorscale entity. The minimum + * and maxiumum data value of all sources is obtained. The minimum + * color scale value is set to the minimum data value. The maximum + * color scale value is set to 10% of the maximum data value. The + * scale is set to be logarithmic. + * + * @returns A color scale entity. + */ + VsiColorScale AutoScaleRangeGenerator::getStandardColorScale() + { + // Select any number larger than 1 to start with + double maxValue= this->defaultValue; + double maxValueBuffer = this->defaultValue; + + double minValue = this->defaultValue; + double minValueBuffer = this->defaultValue; + + bool initialSetting = TRUE; + + QList sources = getAllPVSources(); + + pqView* activeView = pqActiveObjects::instance().activeView(); + + // Check all sources for the maximum and minimum value + for (QList::iterator source = sources.begin(); + source != sources.end(); ++source) + { + // Check if the pipeline representation of the source for the active view is visible + pqDataRepresentation* representation = (*source)->getRepresentation(activeView); + + if (representation) + { + bool isVisible = representation->isVisible(); + + if (isVisible) + { + setMinBufferAndMaxBuffer((*source), minValueBuffer, maxValueBuffer); + + if (initialSetting || maxValueBuffer > maxValue) + { + maxValue = maxValueBuffer; + } + + if (initialSetting || minValueBuffer < minValue) + { + minValue = minValueBuffer; + } + + initialSetting = FALSE; + } + } + } + + // Set the color scale output + VsiColorScale vsiColorScale; + + vsiColorScale.minValue = minValue; + vsiColorScale.maxValue = minValue + 0.1*(maxValue - minValue); + vsiColorScale.useLogScale = TRUE; + + return vsiColorScale; + } + + /** + * Extract the min and max values of a source. If we are dealing with a filter, + * then look further upstream for the information. At the end of the pipeline + * we have to encounter a source with the desired properties. + * Note that this assumes a unique source. + * @param source A pointer to a source. + * @param minValueBuffer A reference to a min value buffer. + * @param maxValueBuffer A reference to a max value buffer. + */ + void AutoScaleRangeGenerator::setMinBufferAndMaxBuffer(pqPipelineSource* source, double& minValue, double& maxValue) + { + pqPipelineSource* pqSource = source; + + bool isFilter = true; + + while(isFilter) + { + // If we are dealing with a filter, we can cast it. + pqPipelineFilter* filter = qobject_cast(pqSource); + + if (!filter) + { + isFilter = false; + + minValue = vtkSMPropertyHelper(pqSource->getProxy(), + "MinValue").GetAsDouble(); + + maxValue = vtkSMPropertyHelper(pqSource->getProxy(), + "MaxValue").GetAsDouble(); + } + else + { + // We expect one input, if not provide defailt values + if (filter->getInputCount() != 1) + { + minValue = this->defaultValue; + maxValue = this->defaultValue; + isFilter = false; + } + else + { + QList outputPorts = filter->getAllInputs(); + + pqSource = outputPorts[0]->getSource(); + } + } + } + } + + /** + * Get all sources from the PV server + */ + QList AutoScaleRangeGenerator::getAllPVSources() + { + pqServer *server = pqActiveObjects::instance().activeServer(); + + pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel(); + + QList sources; + + sources = smModel->findItems(server); + + return sources; + } + + /** + * Sanity check for the color scale, e.g. no 0 for logarithmic scaling. + * @param colorscale A colorscale container + * @returns A colorscale container + */ + void AutoScaleRangeGenerator::sanityCheck(VsiColorScale& colorscale) + { + // Make sure that the min value is larger than 0 for log scales + if (colorscale.useLogScale && colorscale.minValue <= 0.0) + { + colorscale.minValue = this->defaultValue; + } + + // Make sure that the min value is larger than 0 for log scales + if (colorscale.useLogScale && colorscale.maxValue <= 0.0) + { + colorscale.maxValue = this->defaultValue; + } + } +} +} +} \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionWidget.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionWidget.cpp index 7a40f780f4f7..492b169c0054 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionWidget.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionWidget.cpp @@ -159,12 +159,15 @@ void ColorSelectionWidget::autoOrManualScaling(int state) { case Qt::Unchecked: this->setEditorStatus(true); + emit this->autoScale(this); break; case Qt::Checked: this->setEditorStatus(false); - emit this->autoScale(); + emit this->autoScale(this); break; } + + } /** @@ -233,6 +236,15 @@ void ColorSelectionWidget::useLogScaling(int state) emit this->logScale(state); } +/** + * Slot to set the checkbox if the logscaling behaviour has been set programatically + * @param state Flag whether the checkbox should be checked or not + */ +void ColorSelectionWidget::onSetLogScale(bool state) +{ + ui.useLogScaleCheckBox->setChecked(state); +} + /** * This function sets the state for all of the controls on the color selection * widget. diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp index 9258fb3cc5ea..93d1dae03a45 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp @@ -1,15 +1,20 @@ #include "MantidVatesSimpleGuiViewWidgets/ColorUpdater.h" #include "MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h" +#include "MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h" // Have to deal with ParaView warnings and Intel compiler the hard way. #if defined(__INTEL_COMPILER) #pragma warning disable 1170 #endif +#include +#include #include #include +#include #include #include +#include #include #include @@ -29,7 +34,7 @@ namespace Vates { namespace SimpleGui { - + ColorUpdater::ColorUpdater() : autoScaleState(true), logScaleState(false), @@ -42,26 +47,24 @@ ColorUpdater::~ColorUpdater() { } -QPair ColorUpdater::autoScale(pqPipelineRepresentation *repr) +/** + * Set the lookup table to the autoscale values. + * @returns A struct which contains the parameters of the looup table. + */ +VsiColorScale ColorUpdater::autoScale() { - QPair range = repr->getColorFieldRange(); - if (0 == range.first && 1 == range.second) - { - throw std::invalid_argument("Bad color scale given"); - } - pqScalarsToColors *stc = repr->getLookupTable(); - if (NULL != stc) - { - stc->setScalarRange(range.first, range.second); - this->minScale = range.first; - this->maxScale = range.second; - } - else - { - throw std::invalid_argument("Cannot get LUT for representation"); - } - repr->getProxy()->UpdateVTKObjects(); - return range; + // Get the custom auto scale. + VsiColorScale vsiColorScale = this->autoScaleRangeGenerator.getColorScale(); + + // Set the color scale for all sources + this->minScale = vsiColorScale.minValue; + this->maxScale = vsiColorScale.maxValue; + this->logScaleState = vsiColorScale.useLogScale; + + // Update the lookup tables, i.e. react to a color scale change + colorScaleChange(this->minScale, this->maxScale); + + return vsiColorScale; } void ColorUpdater::colorMapChange(pqPipelineRepresentation *repr, @@ -101,41 +104,88 @@ void ColorUpdater::colorMapChange(pqPipelineRepresentation *repr, lutProxy->UpdateVTKObjects(); } -void ColorUpdater::colorScaleChange(pqPipelineRepresentation *repr, - double min, double max) +/** + * React to a change of the color scale settings. + * @param min The lower end of the color scale. + * @param max The upper end of the color scale. + */ +void ColorUpdater::colorScaleChange(double min, double max) { - if (NULL == repr) + this->minScale = min; + this->maxScale = max; + + try { - return; + // Update for all sources and all reps + pqServer *server = pqActiveObjects::instance().activeServer(); + pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel(); + QList sources = smModel->findItems(server); + QList::Iterator source; + + // For all sources + for(QList::iterator source = sources.begin(); source != sources.end(); ++source) + { + QList views = (*source)->getViews(); + + // For all views + for (QList::iterator view = views.begin(); view != views.end(); ++view) + { + QList reps = (*source)->getRepresentations((*view)); + + // For all representations + for (QList::iterator rep = reps.begin(); rep != reps.end(); ++rep) + { + this->updateLookupTable(*rep); + } + } + } } - pqScalarsToColors *stc = repr->getLookupTable(); - if (NULL != stc) + catch(std::invalid_argument &) { - stc->setScalarRange(min, max); - repr->getProxy()->UpdateVTKObjects(); - this->minScale = min; - this->maxScale = max; + + return; } } -void ColorUpdater::logScale(pqPipelineRepresentation *repr, int state) +/** + * Update the lookup table. + * @param representation The representation for which the lookup table is updated. + */ +void ColorUpdater::updateLookupTable(pqDataRepresentation* representation) { - pqScalarsToColors *lut = repr->getLookupTable(); - if (NULL == lut) + pqScalarsToColors* lookupTable = representation->getLookupTable(); + + if (NULL != lookupTable) { - // Got a bad proxy, so just return - return; - } - QPair bounds = lut->getScalarRange(); - // Handle "bug" with lower limit being dropped. - if (bounds.first != this->minScale) + // Set the scalar range values + lookupTable->setScalarRange(this->minScale, this->maxScale); + + // Set the logarithmic scale + pqSMAdaptor::setElementProperty(lookupTable->getProxy()->GetProperty("UseLogScale"), + this->logScaleState); + + // Need to set a lookup table lock here. This does not affect setScalarRange, + // but blocks setWholeScalarRange which gets called by ParaView overrides our + // setting when a workspace is loaded for the first time. + lookupTable->setScalarRangeLock(TRUE); + + representation->getProxy()->UpdateVTKObjects(); + representation->renderViewEventually(); + } else { - lut->setScalarRange(this->minScale, this->maxScale); + throw std::invalid_argument("Cannot get LUT for representation"); } - pqSMAdaptor::setElementProperty(lut->getProxy()->GetProperty("UseLogScale"), - state); - lut->getProxy()->UpdateVTKObjects(); +} + +/** + * React to changing the log scale option + * @param The state to which the log scale is being changed. + */ +void ColorUpdater::logScale(int state) +{ this->logScaleState = state; + + this->colorScaleChange(this->minScale, this->maxScale); } /** diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp index 3c7dcdf465c5..fcc0bc19a952 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -60,15 +61,19 @@ #include //#include #include +#include //#include //#include #include #include #include +#include +#include #include #include #include #include +#include #include #include #include @@ -450,6 +455,11 @@ void MdViewerWidget::setParaViewComponentsForView() SLOT(onParallelProjection(bool))); } + + + + + /** * This function loads and renders data from the given source for the * standalone mode. @@ -471,7 +481,7 @@ void MdViewerWidget::renderingDone() if (this->viewSwitched) { this->viewSwitched = false; - this->currentView->setColorsForView(); + this->currentView->setColorsForView(this->ui.colorSelectionWidget); } } @@ -713,9 +723,10 @@ void MdViewerWidget::setupPluginMode() void MdViewerWidget::renderAndFinalSetup() { this->currentView->render(); - this->currentView->setColorsForView(); + this->currentView->setColorsForView(this->ui.colorSelectionWidget); this->currentView->checkView(this->initialView); this->currentView->updateAnimationControls(); + this->setVisibilityListener(); } /** @@ -734,7 +745,7 @@ void MdViewerWidget::checkForUpdates() if (strcmp(proxy->GetXMLName(), "MDEWRebinningCutter") == 0) { - this->currentView->onAutoScale(); + this->currentView->onAutoScale(this->ui.colorSelectionWidget); this->currentView->updateAnimationControls(); this->currentView->updateView(); this->currentView->updateUI(); @@ -780,10 +791,11 @@ void MdViewerWidget::switchViews(ModeControlWidget::Views v) this->hiddenView->destroyView(); delete this->hiddenView; this->currentView->render(); - this->currentView->setColorsForView(); + this->currentView->setColorsForView(this->ui.colorSelectionWidget); this->currentView->checkViewOnSwitch(); this->updateAppState(); this->initialView = v; + this->setVisibilityListener(); } /** @@ -959,7 +971,7 @@ void MdViewerWidget::disconnectDialogs() */ void MdViewerWidget::connectColorSelectionWidget() { - // Set color selection widget <-> view signals/slots + // Set the color selection widget signal -> view slot connection QObject::connect(this->ui.colorSelectionWidget, SIGNAL(colorMapChanged(const pqColorMapModel *)), this->currentView, @@ -968,16 +980,22 @@ void MdViewerWidget::connectColorSelectionWidget() SIGNAL(colorScaleChanged(double, double)), this->currentView, SLOT(onColorScaleChange(double, double))); + + + // Set the view signal -> color selection widget slot connection QObject::connect(this->currentView, SIGNAL(dataRange(double, double)), this->ui.colorSelectionWidget, SLOT(setColorScaleRange(double, double))); - QObject::connect(this->ui.colorSelectionWidget, SIGNAL(autoScale()), - this->currentView, SLOT(onAutoScale())); + QObject::connect(this->ui.colorSelectionWidget, SIGNAL(autoScale(ColorSelectionWidget*)), + this->currentView, SLOT(onAutoScale(ColorSelectionWidget*))); QObject::connect(this->ui.colorSelectionWidget, SIGNAL(logScale(int)), this->currentView, SLOT(onLogScale(int))); QObject::connect(this->currentView, SIGNAL(lockColorControls(bool)), this->ui.colorSelectionWidget, SLOT(enableControls(bool))); + + QObject::connect(this->currentView,SIGNAL(setLogScale(bool)), + this->ui.colorSelectionWidget, SLOT(onSetLogScale(bool))); } /** @@ -1060,7 +1078,7 @@ void MdViewerWidget::afterReplaceHandle(const std::string &wsName, srcProxy->UpdatePipelineInformation(); src->updatePipeline(); - this->currentView->setColorsForView(); + this->currentView->setColorsForView(this->ui.colorSelectionWidget); this->currentView->renderAll();; } } @@ -1093,6 +1111,29 @@ void MdViewerWidget::preDeleteHandle(const std::string &wsName, } } +/** + * Set the listener for the visibility of the representations + */ +void MdViewerWidget::setVisibilityListener() +{ + // Set the connection to listen to a visibility change of the representation. + pqServer *server = pqActiveObjects::instance().activeServer(); + pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel(); + QList sources; + sources = smModel->findItems(server); + + pqView* activeView = pqActiveObjects::instance().activeView(); + + // Attach the visibilityChanged signal for all sources. + for (QList::iterator source = sources.begin(); source != sources.end(); ++source) + { + QObject::connect((*source), SIGNAL(visibilityChanged(pqPipelineSource*, pqDataRepresentation*)), + this->currentView, SLOT(onVisibilityChanged(pqPipelineSource*, pqDataRepresentation*)), + Qt::UniqueConnection); + } +} + + } // namespace SimpleGui } // namespace Vates } // namespace Mantid diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp index 737334d77f85..10a445ef2e9d 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp @@ -184,7 +184,7 @@ void SplatterPlotView::render() this->resetDisplay(); if (this->peaksSource.isEmpty()) { - this->onAutoScale(); + this->setAutoColorScale(); } else { diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp index d265a0acffda..e83eebd884f0 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp @@ -14,8 +14,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -105,30 +107,43 @@ void ViewBase::destroyFilter(pqObjectBuilder *builder, const QString &name) /** * This function is responsible for setting the color scale range from the * full extent of the data. + * @param colorSelectionWidget Pointer to the color selection widget. */ -void ViewBase::onAutoScale() +void ViewBase::onAutoScale(ColorSelectionWidget* colorSelectionWidget) { - pqPipelineRepresentation *rep = this->getRep(); - if (NULL == rep) + // Update the colorUpdater + this->colorUpdater.updateState(colorSelectionWidget); + + if (this->colorUpdater.isAutoScale()) { - // Can't get a good rep, just return - //qDebug() << "Bad rep for auto scale"; - return; + this->setAutoColorScale(); } - QPair range; +} + +/** + * Set the color scale for auto color scaling. + * + */ +void ViewBase::setAutoColorScale() +{ + VsiColorScale colorScale; + try { - range = this->colorUpdater.autoScale(rep); + colorScale = this->colorUpdater.autoScale(); } catch (std::invalid_argument &) { // Got a bad proxy or color scale range, so do nothing return; } - rep->renderViewEventually(); - emit this->dataRange(range.first, range.second); + + // Set the color scale widget + emit this->dataRange(colorScale.minValue, colorScale.maxValue); + emit this->setLogScale(colorScale.useLogScale); } + /** * This function sets the requested color map on the data. * @param model the color map to use @@ -146,13 +161,13 @@ void ViewBase::onColorMapChange(const pqColorMapModel *model) bool logStateChanged = false; if (this->colorUpdater.isLogScale()) { - this->colorUpdater.logScale(rep, false); + this->colorUpdater.logScale(false); logStateChanged = true; } this->colorUpdater.colorMapChange(rep, model); if (logStateChanged) { - this->colorUpdater.logScale(rep, true); + this->colorUpdater.logScale(true); } rep->renderViewEventually(); } @@ -164,13 +179,7 @@ void ViewBase::onColorMapChange(const pqColorMapModel *model) */ void ViewBase::onColorScaleChange(double min, double max) { - pqPipelineRepresentation *rep = this->getRep(); - if (NULL == rep) - { - return; - } - this->colorUpdater.colorScaleChange(rep, min, max); - rep->renderViewEventually(); + this->colorUpdater.colorScaleChange(min, max); } /** @@ -179,13 +188,7 @@ void ViewBase::onColorScaleChange(double min, double max) */ void ViewBase::onLogScale(int state) { - pqPipelineRepresentation *rep = this->getRep(); - if (NULL == rep) - { - return; - } - this->colorUpdater.logScale(rep, state); - rep->renderViewEventually(); + this->colorUpdater.logScale(state); } /** @@ -201,12 +204,16 @@ void ViewBase::setColorScaleState(ColorSelectionWidget *cs) /** * This function checks the current state from the color updater and * processes the necessary color changes. + * @param A pointer to the colorscale widget. */ -void ViewBase::setColorsForView() +void ViewBase::setColorsForView(ColorSelectionWidget *colorScale) { + // Update the colorupdater with the settings of the colorSelectionWidget + setColorScaleState(colorScale); + if (this->colorUpdater.isAutoScale()) { - this->onAutoScale(); + this->onAutoScale(colorScale); } else { @@ -681,6 +688,22 @@ bool ViewBase::hasWorkspaceType(const QString &wsTypeName) return hasWsType; } +/** + * React to a change of the visibility of a representation of a source. + * This can be a change of the status if the "eye" symbol in the PipelineBrowserWidget + * as well as the addition or removal of a representation. + * @param source The pipeleine source assoicated with the call. + * @param representation The representation associatied with the call + */ +void ViewBase::onVisibilityChanged(pqPipelineSource *source, pqDataRepresentation *representation) +{ + // Reset the colorscale if it is set to autoscale + if (colorUpdater.isAutoScale()) + { + this->setAutoColorScale(); + } +} + } // namespace SimpleGui } // namespace Vates } // namespace Mantid From 35325da1c54f1f82dc5efb289f3a5e874cfe38d9 Mon Sep 17 00:00:00 2001 From: Anton Piccardo-Selg Date: Wed, 3 Dec 2014 15:26:07 +0000 Subject: [PATCH 015/275] Refs #10627 Adding functionality to auto color scaling in VSI --- .../ScaleWorkspace/ScaleWorkspace.xml | 3 + .../ScaleWorkspace/vtkScaleWorkspace.cxx | 55 ++++++- .../ScaleWorkspace/vtkScaleWorkspace.h | 17 +++ .../MDEWSource/vtkMDEWSource.h | 6 +- .../MDHWSource/vtkMDHWSource.cxx | 7 +- Code/Mantid/Vates/VatesAPI/CMakeLists.txt | 6 + .../MDEWInMemoryLoadingPresenter.h | 7 - .../inc/MantidVatesAPI/MDEWLoadingPresenter.h | 16 ++- .../MDHWInMemoryLoadingPresenter.h | 7 - .../inc/MantidVatesAPI/MDHWLoadingPresenter.h | 13 +- .../MantidVatesAPI/MetaDataExtractorUtils.h | 4 +- .../inc/MantidVatesAPI/MetadataJsonManager.h | 66 +++++++++ .../inc/MantidVatesAPI/VatesConfigurations.h | 58 ++++++++ .../src/MDEWInMemoryLoadingPresenter.cpp | 37 ++--- .../VatesAPI/src/MDEWLoadingPresenter.cpp | 32 ++++- .../src/MDHWInMemoryLoadingPresenter.cpp | 44 +++--- .../VatesAPI/src/MDHWLoadingPresenter.cpp | 33 ++++- .../VatesAPI/src/MetaDataExtractorUtils.cpp | 49 +++++-- .../VatesAPI/src/MetadataJsonManager.cpp | 136 ++++++++++++++++++ .../VatesAPI/src/VatesConfigurations.cpp | 52 +++++++ .../VatesAPI/src/vtkSplatterPlotFactory.cpp | 23 ++- .../test/EventNexusLoadingPresenterTest.h | 2 +- .../test/MDEWEventNexusLoadingPresenterTest.h | 2 +- .../test/MDEWInMemoryLoadingPresenterTest.h | 4 +- .../test/MDHWInMemoryLoadingPresenterTest.h | 8 +- .../test/MDHWNexusLoadingPresenterTest.h | 2 +- .../test/MetaDataExtractorUtilsTest.h | 85 +++++++++++ .../VatesAPI/test/MetadataJsonManagerTest.h | 108 ++++++++++++++ .../VatesAPI/test/SQWLoadingPresenterTest.h | 2 +- .../AutoScaleRangeGenerator.h | 4 +- .../src/AutoScaleRangeGenerator.cpp | 50 +++++-- .../ViewWidgets/src/MdViewerWidget.cpp | 6 +- .../UsageData/INES_Definition.vtp | 22 +++ 33 files changed, 845 insertions(+), 121 deletions(-) create mode 100644 Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetadataJsonManager.h create mode 100644 Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/VatesConfigurations.h create mode 100644 Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp create mode 100644 Code/Mantid/Vates/VatesAPI/src/VatesConfigurations.cpp create mode 100644 Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h create mode 100644 Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h create mode 100644 Test/AutoTestData/UsageData/INES_Definition.vtp diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/ScaleWorkspace.xml b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/ScaleWorkspace.xml index 04b8c10edbb3..5b1454980a20 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/ScaleWorkspace.xml +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/ScaleWorkspace.xml @@ -16,6 +16,9 @@ + + + diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx index 24296a3f08b3..ad8a531fa1c0 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx @@ -1,7 +1,9 @@ #include "vtkScaleWorkspace.h" #include "MantidVatesAPI/vtkDataSetToScaledDataSet.h" - +#include "MantidVatesAPI/FieldDataToMetadata.h" +#include "MantidVatesAPI/MetadataJsonManager.h" +#include "MantidVatesAPI/VatesConfigurations.h" #include #include #include @@ -16,7 +18,9 @@ using namespace Mantid::VATES; vtkScaleWorkspace::vtkScaleWorkspace() : m_xScaling(1), m_yScaling(1), - m_zScaling(1) + m_zScaling(1), + m_metadataJsonManager(new MetadataJsonManager()), + m_vatesConfigurations(new VatesConfigurations()) { this->SetNumberOfInputPorts(1); this->SetNumberOfOutputPorts(1); @@ -41,8 +45,24 @@ int vtkScaleWorkspace::RequestData(vtkInformation*, vtkInformationVector **input return 1; } -int vtkScaleWorkspace::RequestInformation(vtkInformation*, vtkInformationVector**, vtkInformationVector*) +int vtkScaleWorkspace::RequestInformation(vtkInformation*, vtkInformationVector** inputVector, vtkInformationVector*) { + // Set the meta data + vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); + vtkUnstructuredGrid *inputDataSet = vtkUnstructuredGrid::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT())); + + vtkFieldData* fieldData = inputDataSet->GetFieldData(); + + // Extract information for meta data in Json format. + FieldDataToMetadata fieldDataToMetadata; + + std::string jsonString = fieldDataToMetadata(fieldData, m_vatesConfigurations->getMetadataIdJson()); + m_metadataJsonManager->readInSerializedJson(jsonString); + + m_minValue = m_metadataJsonManager->getMinValue(); + m_maxValue = m_metadataJsonManager->getMaxValue(); + m_instrument = m_metadataJsonManager->getInstrument(); + return 1; } @@ -88,4 +108,33 @@ void vtkScaleWorkspace::SetZScaling(double zScaling) this->Modified(); m_zScaling = zScaling; } +} + +/** + * Gets the minimum value of the data associated with the + * workspace. + * @return The minimum value of the workspace data. + */ +double vtkScaleWorkspace::GetMinValue() +{ + return m_minValue; +} + +/** + * Gets the maximum value of the data associated with the + * workspace. + * @return The maximum value of the workspace data. + */ +double vtkScaleWorkspace::GetMaxValue() +{ + return m_maxValue; +} + +/** + * Gets the (first) instrument which is associated with the workspace. + * @return The name of the instrument. + */ +const char* vtkScaleWorkspace::GetInstrument() +{ + return m_instrument.c_str(); } \ No newline at end of file diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.h index 71d4d36fa0c6..7dcb2cd3e881 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.h +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.h @@ -1,6 +1,10 @@ #ifndef _vtkScaleWorkspace_h #define _vtkScaleWorkspace_h #include "vtkUnstructuredGridAlgorithm.h" +#include "MantidVatesAPI/MetadataJsonManager.h" +#include "MantidVatesAPI/VatesConfigurations.h" +#include + // cppcheck-suppress class_X_Y class VTK_EXPORT vtkScaleWorkspace : public vtkUnstructuredGridAlgorithm { @@ -11,6 +15,12 @@ class VTK_EXPORT vtkScaleWorkspace : public vtkUnstructuredGridAlgorithm void SetXScaling(double xScaling); void SetYScaling(double yScaling); void SetZScaling(double zScaling); + /// Getter for the minimum value of the workspace data + double GetMinValue(); + /// Getter for the maximum value of the workspace data + double GetMaxValue(); + /// Getter for the instrument associated with the instrument. + const char* GetInstrument(); protected: vtkScaleWorkspace(); @@ -24,5 +34,12 @@ class VTK_EXPORT vtkScaleWorkspace : public vtkUnstructuredGridAlgorithm double m_xScaling; double m_yScaling; double m_zScaling; + + double m_minValue; + double m_maxValue; + std::string m_instrument; + + boost::scoped_ptr m_metadataJsonManager; + boost::scoped_ptr m_vatesConfigurations; }; #endif diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.h index 7716a6d7871a..abe5da855e30 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.h +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.h @@ -67,11 +67,11 @@ class VTK_EXPORT vtkMDEWSource : public vtkUnstructuredGridAlgorithm const char* GetWorkspaceName(); /// Getter for the workspace type char* GetWorkspaceTypeName(); - /// Getter for the minimum value of the workspace data + /// Getter for the minimum value of the workspace data. double GetMinValue(); - /// Getter for the maximum value of the workspace data + /// Getter for the maximum value of the workspace data. double GetMaxValue(); - /// Getter for the maximum value of the workspace data + /// Getter for the instrument associated with the workspace data. const char* GetInstrument(); protected: diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.cxx index 94f87c99f5f6..26ed4e7eba59 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.cxx @@ -177,7 +177,7 @@ int vtkMDHWSource::RequestData(vtkInformation *, vtkInformationVector **, vtkInf factory->SetSuccessor(successor); vtkDataSet* product = m_presenter->execute(factory, loadingProgressUpdate, drawingProgressUpdate); - + //-------------------------------------------------------- Corrects problem whereby boundaries not set propertly in PV. vtkBox* box = vtkBox::New(); box->SetBounds(product->GetBounds()); @@ -192,6 +192,7 @@ int vtkMDHWSource::RequestData(vtkInformation *, vtkInformationVector **, vtkInf vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast( outInfo->Get(vtkDataObject::DATA_OBJECT())); output->ShallowCopy(clipperOutput); + try { m_presenter->makeNonOrthogonal(output); @@ -213,7 +214,9 @@ int vtkMDHWSource::RequestInformation(vtkInformation *vtkNotUsed(request), vtkIn { if(m_presenter == NULL && !m_wsName.empty()) { - m_presenter = new MDHWInMemoryLoadingPresenter(new MDLoadingViewAdapter(this), new ADSWorkspaceProvider, m_wsName); + m_presenter = new MDHWInMemoryLoadingPresenter(new MDLoadingViewAdapter(this), + new ADSWorkspaceProvider, + m_wsName); if(!m_presenter->canReadFile()) { vtkErrorMacro(<<"Cannot fetch the specified workspace from Mantid ADS."); diff --git a/Code/Mantid/Vates/VatesAPI/CMakeLists.txt b/Code/Mantid/Vates/VatesAPI/CMakeLists.txt index e2c4ed26c1db..630971b8a1a0 100644 --- a/Code/Mantid/Vates/VatesAPI/CMakeLists.txt +++ b/Code/Mantid/Vates/VatesAPI/CMakeLists.txt @@ -24,6 +24,7 @@ src/MDHWNexusLoadingPresenter.cpp src/MedianAndBelowThresholdRange.cpp src/MetadataToFieldData.cpp src/MetaDataExtractorUtils.cpp +src/MetadataJsonManager.cpp src/NoThresholdRange.cpp src/NullRebinningPresenter.cpp src/ProgressAction.cpp @@ -33,6 +34,7 @@ src/SynchronisingGeometryPresenter.cpp src/TimeStepToTimeStep.cpp src/TimeToTimeStep.cpp src/UserDefinedThresholdRange.cpp +src/VatesConfigurations.cpp src/vtkDataSetFactory.cpp src/vtkDataSetToGeometry.cpp src/vtkDataSetToImplicitFunction.cpp @@ -81,6 +83,7 @@ inc/MantidVatesAPI/MDRebinningView.h inc/MantidVatesAPI/MDRebinningViewAdapter.h inc/MantidVatesAPI/MedianAndBelowThresholdRange.h inc/MantidVatesAPI/MetaDataExtractorUtils.h +inc/MantidVatesAPI/MetadataJsonManager.h inc/MantidVatesAPI/IgnoreZerosThresholdRange.h inc/MantidVatesAPI/IMDDimensionComparitor.h inc/MantidVatesAPI/MetadataToFieldData.h @@ -96,6 +99,7 @@ inc/MantidVatesAPI/ThresholdRange.h inc/MantidVatesAPI/TimeStepToTimeStep.h inc/MantidVatesAPI/TimeToTimeStep.h inc/MantidVatesAPI/UserDefinedThresholdRange.h +inc/MantidVatesAPI/VatesConfigurations.h inc/MantidVatesAPI/vtkDataSetFactory.h inc/MantidVatesAPI/vtkDataSetToGeometry.h inc/MantidVatesAPI/vtkDataSetToImplicitFunction.h @@ -146,6 +150,8 @@ test/MDEWRebinningPresenterTest.h test/MDHWInMemoryLoadingPresenterTest.h test/MDHWLoadingPresenterTest.h test/MDHWNexusLoadingPresenterTest.h +test/MetaDataExtractorUtilsTest.h +test/MetadataJsonManagerTest.h test/NullRebinningPresenterTest.h test/MetadataToFieldDataTest.h test/RebinningKnowledgeSerializerTest.h diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWInMemoryLoadingPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWInMemoryLoadingPresenter.h index 9042a5c9e07a..831690601406 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWInMemoryLoadingPresenter.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWInMemoryLoadingPresenter.h @@ -51,9 +51,6 @@ namespace Mantid virtual bool canReadFile() const; virtual std::string getWorkspaceTypeName(); virtual int getSpecialCoordinates(); - virtual double getMinValue(); - virtual double getMaxValue(); - private: /// Repository for accessing workspaces. At this level, does not specify how or where from. @@ -62,10 +59,6 @@ namespace Mantid const std::string m_wsName; std::string m_wsTypeName; int m_specialCoords; - double m_minValue; - double m_maxValue; - /// Meta data extractor - boost::scoped_ptr m_metaDataExtractor; }; } } diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWLoadingPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWLoadingPresenter.h index b1f8c25142bc..e5cc9cb0066f 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWLoadingPresenter.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWLoadingPresenter.h @@ -2,10 +2,15 @@ #define MANTID_VATES_MDEW_LOADING_PRESENTER #include "MantidVatesAPI/MDLoadingPresenter.h" +#include "MantidVatesAPI/MetadataJsonManager.h" +#include "MantidVatesAPI/MetaDataExtractorUtils.h" +#include "MantidVatesAPI/VatesConfigurations.h" #include "MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h" #include "MantidGeometry/MDGeometry/IMDDimension.h" #include "MantidAPI/IMDEventWorkspace.h" +#include + namespace Mantid { namespace VATES @@ -49,14 +54,22 @@ namespace Mantid virtual void setAxisLabels(vtkDataSet* visualDataSet); virtual ~MDEWLoadingPresenter(); virtual const std::string& getInstrument(); + virtual double getMinValue(); + virtual double getMaxValue(); + protected: /*--------------------------------------------------------------------------- Common/shared operations and members for all MDEW file-type loading. ---------------------------------------------------------------------------*/ MDLoadingView* m_view; - Mantid::Geometry::MDGeometryBuilderXML xmlBuilder; + + boost::scoped_ptr m_metadataJsonManager; + boost::scoped_ptr m_metaDataExtractor; + boost::scoped_ptr m_vatesConfigurations; + Mantid::Geometry::IMDDimension_sptr tDimension; + std::vector axisLabels; virtual void appendMetadata(vtkDataSet* visualDataSet, const std::string& wsName) ; virtual void extractMetadata(Mantid::API::IMDEventWorkspace_sptr eventWs); @@ -67,7 +80,6 @@ namespace Mantid size_t m_recursionDepth; bool m_loadInMemory; bool m_firstLoad; - std::string m_instrument; }; } } diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWInMemoryLoadingPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWInMemoryLoadingPresenter.h index 6bf48b7a0583..534d88220135 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWInMemoryLoadingPresenter.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWInMemoryLoadingPresenter.h @@ -50,9 +50,6 @@ namespace Mantid virtual bool canReadFile() const; virtual std::string getWorkspaceTypeName(); virtual int getSpecialCoordinates(); - virtual double getMinValue(); - virtual double getMaxValue(); - private: /// Repository for accessing workspaces. At this level, does not specify how or where from. @@ -61,10 +58,6 @@ namespace Mantid const std::string m_wsName; std::string m_wsTypeName; int m_specialCoords; - double m_minValue; - double m_maxValue; - /// Meta data extractor - boost::scoped_ptr m_metaDataExtractor; }; } } diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWLoadingPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWLoadingPresenter.h index 561beda64483..52869be877a6 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWLoadingPresenter.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWLoadingPresenter.h @@ -2,10 +2,15 @@ #define MANTID_VATES_MDHW_LOADING_PRESENTER #include "MantidVatesAPI/MDLoadingPresenter.h" +#include "MantidVatesAPI/MetadataJsonManager.h" +#include "MantidVatesAPI/MetaDataExtractorUtils.h" +#include "MantidVatesAPI/VatesConfigurations.h" #include "MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h" #include "MantidGeometry/MDGeometry/IMDDimension.h" #include "MantidAPI/IMDHistoWorkspace.h" +#include + namespace Mantid { namespace VATES @@ -50,6 +55,8 @@ namespace Mantid virtual void makeNonOrthogonal(vtkDataSet* visualDataSet); virtual ~MDHWLoadingPresenter(); virtual const std::string& getInstrument(); + virtual double getMinValue(); + virtual double getMaxValue(); protected: /*--------------------------------------------------------------------------- @@ -58,6 +65,11 @@ namespace Mantid MDLoadingView* m_view; Mantid::Geometry::MDGeometryBuilderXML xmlBuilder; + + boost::scoped_ptr m_metadataJsonManager; + boost::scoped_ptr m_metaDataExtractor; + boost::scoped_ptr m_vatesConfigurations; + Mantid::Geometry::IMDDimension_sptr tDimension; std::vector axisLabels; virtual void appendMetadata(vtkDataSet* visualDataSet, @@ -70,7 +82,6 @@ namespace Mantid double m_time; bool m_loadInMemory; bool m_firstLoad; - std::string m_instrument; }; } } diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetaDataExtractorUtils.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetaDataExtractorUtils.h index 126e4746f410..da624794e995 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetaDataExtractorUtils.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetaDataExtractorUtils.h @@ -5,7 +5,6 @@ #include "MantidAPI/IMDIterator.h" #include "qwt/qwt_double_interval.h" #include -#include /** @@ -67,6 +66,9 @@ namespace Mantid * @retunrs A maximum and minimum pair. */ QwtDoubleInterval getRange(Mantid::API::IMDIterator* it); + + double defaultMin; + double defaultMax; }; } } diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetadataJsonManager.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetadataJsonManager.h new file mode 100644 index 000000000000..fe03a51c5dd5 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetadataJsonManager.h @@ -0,0 +1,66 @@ +#ifndef METADATA_JSON_MANAGER_H +#define METADATA_JSON_MANAGER_H + +#include "jsoncpp/json/json.h" +#include "MantidKernel/System.h" +#include +namespace Mantid +{ + namespace VATES + { + /** Metadata container and handler to handle json data which is passed between filters and sources through + VTK field data + + @date 31/11/2014 + + Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + + class DLLExport MetadataJsonManager + { + public: + MetadataJsonManager(); + + ~MetadataJsonManager(); + + std::string getSerializedJson(); + + void readInSerializedJson(std::string serializedJson); + + void setInstrument(std::string instrument); + std::string& getInstrument(); + + void setMinValue(double minValue); + double getMinValue(); + + void setMaxValue(double maxValue); + double getMaxValue(); + + private: + Json::Value metadataContainer; + + std::string instrument; + double minValue; + double maxValue; + }; + } +} +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/VatesConfigurations.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/VatesConfigurations.h new file mode 100644 index 000000000000..f6d9f32e33fe --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/VatesConfigurations.h @@ -0,0 +1,58 @@ +#ifndef VATES_CONFIGURATION_H +#define VATES_CONFIGURATION_H + + +#include "MantidKernel/System.h" +#include + +namespace Mantid +{ + namespace VATES + { + /** Metadata container and handler to handle json data which is passed between filters and sources through + VTK field data + + @date 1/12/2014 + + Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + + class DLLExport VatesConfigurations + { + public: + VatesConfigurations(); + + ~VatesConfigurations(); + + int getMaxRecursionDepth(); + + std::string getMetadataIdJson(); + + private: + // The maximum recursion depth when going through the box tree. + const int maxRecursionDepth; + + // Meta data field flag + const std::string metaDataId; + }; + } +} +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp index 6845b9da896e..24f19ce4c898 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp @@ -1,6 +1,5 @@ #include "MantidVatesAPI/MDEWInMemoryLoadingPresenter.h" #include "MantidVatesAPI/MDLoadingView.h" -#include "MantidVatesAPI/MetaDataExtractorUtils.h" #include "MantidVatesAPI/ProgressAction.h" #include "MantidVatesAPI/vtkDataSetFactory.h" #include "MantidVatesAPI/WorkspaceProvider.h" @@ -23,7 +22,7 @@ namespace Mantid @throw invalid_arument if view is null */ MDEWInMemoryLoadingPresenter::MDEWInMemoryLoadingPresenter(MDLoadingView* view, WorkspaceProvider* repository, std::string wsName) : MDEWLoadingPresenter(view), - m_repository(repository), m_wsName(wsName), m_wsTypeName(""), m_specialCoords(-1), m_metaDataExtractor(new MetaDataExtractorUtils()) + m_repository(repository), m_wsName(wsName), m_wsTypeName(""), m_specialCoords(-1) { if(m_wsName.empty()) { @@ -84,6 +83,16 @@ namespace Mantid /*extractMetaData needs to be re-run here because the first execution of this from ::executeLoadMetadata will not have ensured that all dimensions have proper range extents set. */ + + // Update the meta data min and max values with the values of the visual data set. This is necessary since we want the full data range of the visual + // data set and not of the actual underlying data set. + double* range = visualDataSet->GetScalarRange(); + if (range) + { + this->m_metadataJsonManager->setMinValue(range[0]); + this->m_metadataJsonManager->setMaxValue(range[1]); + } + this->extractMetadata(eventWs); this->appendMetadata(visualDataSet, eventWs->getName()); @@ -104,11 +113,11 @@ namespace Mantid // Set the minimum and maximum of the workspace data. QwtDoubleInterval minMaxContainer = m_metaDataExtractor->getMinAndMax(eventWs); - m_minValue = minMaxContainer.minValue(); - m_maxValue = minMaxContainer.maxValue(); + m_metadataJsonManager->setMinValue(minMaxContainer.minValue()); + m_metadataJsonManager->setMaxValue(minMaxContainer.maxValue()); // Set the instrument which is associated with the workspace. - m_instrument = m_metaDataExtractor->extractInstrument(eventWs); + m_metadataJsonManager->setInstrument(m_metaDataExtractor->extractInstrument(eventWs)); //Call base-class extraction method. this->extractMetadata(eventWs); @@ -137,23 +146,5 @@ namespace Mantid { return m_specialCoords; } - - /** - * Getter for the minimum value; - * @return The minimum value of the data set. - */ - double MDEWInMemoryLoadingPresenter::getMinValue() - { - return m_minValue; - } - - /** - * Getter for the maximum value; - * @return The maximum value of the data set. - */ - double MDEWInMemoryLoadingPresenter::getMaxValue() - { - return m_maxValue; - } } } diff --git a/Code/Mantid/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp index 6ac8974bdb2e..d8fc623cab0b 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp @@ -4,10 +4,14 @@ #include "MantidGeometry/MDGeometry/NullImplicitFunction.h" #include "MantidVatesAPI/RebinningKnowledgeSerializer.h" +#include "MantidVatesAPI/MetaDataExtractorUtils.h" +#include "MantidVatesAPI/MetadataJsonManager.h" #include "MantidVatesAPI/MetadataToFieldData.h" +#include "MantidVatesAPI/VatesConfigurations.h" #include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" #include "MantidVatesAPI/Common.h" +#include #include #include #include @@ -24,7 +28,9 @@ namespace Mantid m_recursionDepth(0), m_loadInMemory(false), m_firstLoad(true), - m_instrument("") + m_metaDataExtractor(new MetaDataExtractorUtils()), + m_metadataJsonManager(new MetadataJsonManager()), + m_vatesConfigurations(new VatesConfigurations()) { Mantid::API::FrameworkManager::Instance(); } @@ -155,9 +161,13 @@ namespace Mantid serializer.setImplicitFunction( Mantid::Geometry::MDImplicitFunction_sptr(new Mantid::Geometry::NullImplicitFunction())); std::string xmlString = serializer.createXMLString(); + // Serialize Json metadata + std::string jsonString = m_metadataJsonManager->getSerializedJson(); + //Add metadata to dataset. MetadataToFieldData convert; convert(outputFD, xmlString, XMLDefinitions::metaDataId().c_str()); + convert(outputFD, jsonString, m_vatesConfigurations->getMetadataIdJson().c_str()); visualDataSet->SetFieldData(outputFD); outputFD->Delete(); } @@ -239,7 +249,25 @@ namespace Mantid */ const std::string& MDEWLoadingPresenter::getInstrument() { - return m_instrument; + return m_metadataJsonManager->getInstrument(); + } + + /** + * Getter for the minimum value; + * @return The minimum value of the data set. + */ + double MDEWLoadingPresenter::getMinValue() + { + return m_metadataJsonManager->getMinValue(); + } + + /** + * Getter for the maximum value; + * @return The maximum value of the data set. + */ + double MDEWLoadingPresenter::getMaxValue() + { + return m_metadataJsonManager->getMaxValue(); } } } diff --git a/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp index 56f674edb02a..c4c138c5b2d0 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp @@ -23,7 +23,7 @@ namespace Mantid @throw invalid_arument if view is null */ MDHWInMemoryLoadingPresenter::MDHWInMemoryLoadingPresenter(MDLoadingView* view, WorkspaceProvider* repository, std::string wsName) : MDHWLoadingPresenter(view), - m_repository(repository), m_wsName(wsName), m_wsTypeName(""), m_specialCoords(-1), m_metaDataExtractor(new MetaDataExtractorUtils()) + m_repository(repository), m_wsName(wsName), m_wsTypeName(""), m_specialCoords(-1) { if(m_wsName.empty()) { @@ -84,6 +84,16 @@ namespace Mantid /*extractMetaData needs to be re-run here because the first execution of this from ::executeLoadMetadata will not have ensured that all dimensions have proper range extents set. */ + + // Update the meta data min and max values with the values of the visual data set. This is necessary since we want the full data range of the visual + // data set and not of the actual underlying data set. + double* range = visualDataSet->GetScalarRange(); + if (range) + { + this->m_metadataJsonManager->setMinValue(range[0]); + this->m_metadataJsonManager->setMaxValue(range[1]); + } + this->extractMetadata(histoWs); this->appendMetadata(visualDataSet, histoWs->getName()); @@ -104,11 +114,11 @@ namespace Mantid // Set the minimum and maximum of the workspace data. QwtDoubleInterval minMaxContainer = m_metaDataExtractor->getMinAndMax(histoWs); - m_minValue = minMaxContainer.minValue(); - m_maxValue = minMaxContainer.maxValue(); + m_metadataJsonManager->setMinValue(minMaxContainer.minValue()); + m_metadataJsonManager->setMaxValue(minMaxContainer.maxValue()); // Set the instrument which is associated with the workspace. - m_instrument =m_metaDataExtractor->extractInstrument(histoWs); + m_metadataJsonManager->setInstrument(m_metaDataExtractor->extractInstrument(histoWs)); //Call base-class extraction method. this->extractMetadata(histoWs); @@ -120,10 +130,10 @@ namespace Mantid delete m_view; } - /* - Getter for the workspace type name. - @return Workspace Type Name - */ + /* + * Getter for the workspace type name. + * @return Workspace Type Name + */ std::string MDHWInMemoryLoadingPresenter::getWorkspaceTypeName() { return m_wsTypeName; @@ -137,23 +147,5 @@ namespace Mantid { return m_specialCoords; } - - /** - * Getter for the minimum value; - * @return The minimum value of the data set. - */ - double MDHWInMemoryLoadingPresenter::getMinValue() - { - return m_minValue; - } - - /** - * Getter for the maximum value; - * @return The maximum value of the data set. - */ - double MDHWInMemoryLoadingPresenter::getMaxValue() - { - return m_maxValue; - } } } diff --git a/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp index 4cc2951dca03..7877f1c570f5 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp @@ -5,12 +5,17 @@ #include "MantidGeometry/MDGeometry/MDHistoDimension.h" #include "MantidGeometry/MDGeometry/NullImplicitFunction.h" #include "MantidVatesAPI/RebinningKnowledgeSerializer.h" +#include "MantidVatesAPI/MetadataExtractorUtils.h" +#include "MantidVatesAPI/MetadataJsonManager.h" #include "MantidVatesAPI/MetadataToFieldData.h" #include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" +#include "MantidVatesAPI/VatesConfigurations.h" #include "MantidVatesAPI/vtkDataSetToNonOrthogonalDataSet.h" #include "MantidVatesAPI/vtkDataSetToWsName.h" #include "MantidVatesAPI/Common.h" +#include + #include #include @@ -25,7 +30,9 @@ namespace Mantid m_time(-1), m_loadInMemory(false), m_firstLoad(true), - m_instrument("") + m_metaDataExtractor(new MetaDataExtractorUtils()), + m_metadataJsonManager(new MetadataJsonManager()), + m_vatesConfigurations(new VatesConfigurations()) { Mantid::API::FrameworkManager::Instance(); } @@ -148,10 +155,14 @@ namespace Mantid serializer.setGeometryXML(xmlBuilder.create()); serializer.setImplicitFunction( Mantid::Geometry::MDImplicitFunction_sptr(new Mantid::Geometry::NullImplicitFunction())); std::string xmlString = serializer.createXMLString(); + + // Serialize Json metadata + std::string jsonString = m_metadataJsonManager->getSerializedJson(); //Add metadata to dataset. MetadataToFieldData convert; convert(outputFD, xmlString, XMLDefinitions::metaDataId().c_str()); + convert(outputFD, jsonString, m_vatesConfigurations->getMetadataIdJson().c_str()); visualDataSet->SetFieldData(outputFD); outputFD->Delete(); } @@ -244,7 +255,25 @@ namespace Mantid */ const std::string& MDHWLoadingPresenter::getInstrument() { - return m_instrument; + return m_metadataJsonManager->getInstrument(); + } + + /** + * Getter for the minimum value; + * @return The minimum value of the data set. + */ + double MDHWLoadingPresenter::getMinValue() + { + return m_metadataJsonManager->getMinValue(); + } + + /** + * Getter for the maximum value; + * @return The maximum value of the data set. + */ + double MDHWLoadingPresenter::getMaxValue() + { + return m_metadataJsonManager->getMaxValue(); } } } diff --git a/Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp b/Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp index 1be903ba7458..59bf8ab51e82 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp @@ -18,7 +18,7 @@ namespace Mantid Kernel::Logger g_log("MetaDataExtractorUtils"); } - MetaDataExtractorUtils::MetaDataExtractorUtils() + MetaDataExtractorUtils::MetaDataExtractorUtils():defaultMin(0.0), defaultMax(1.0) { } @@ -38,7 +38,7 @@ namespace Mantid Mantid::API::IMDEventWorkspace_sptr eventWorkspace = boost::dynamic_pointer_cast(workspace); Mantid::API::IMDHistoWorkspace_sptr histoWorkspace = boost::dynamic_pointer_cast(workspace); - std::string instrument; + std::string instrument = ""; // Check which workspace is currently used and that it contains at least one instrument. if (eventWorkspace) @@ -79,6 +79,13 @@ namespace Mantid */ QwtDoubleInterval MetaDataExtractorUtils::getMinAndMax(Mantid::API::IMDWorkspace_sptr workspace) { + if (!workspace) + { + throw std::invalid_argument("The workspace is empty."); + + return QwtDoubleInterval(defaultMin,defaultMax); + } + auto iterators = workspace->createIterators(PARALLEL_GET_MAX_THREADS, 0); std::vector intervals(iterators.size()); @@ -87,6 +94,7 @@ namespace Mantid for (int i=0; i < int(iterators.size()); i++) { Mantid::API::IMDIterator * it = iterators[i]; + QwtDoubleInterval range = this->getRange(it); intervals[i] = range; // don't delete iterator in parallel. MSVC doesn't like it @@ -96,11 +104,12 @@ namespace Mantid // Combine the overall min/max double minSignal = DBL_MAX; double maxSignal = -DBL_MAX; + auto inf = std::numeric_limits::infinity(); for (size_t i=0; i < iterators.size(); i++) { delete iterators[i]; - + double signal; signal = intervals[i].minValue(); if (signal != inf && signal < minSignal) minSignal = signal; @@ -109,11 +118,12 @@ namespace Mantid if (signal != inf && signal > maxSignal) maxSignal = signal; } + // Set the lowest element to the smallest non-zero element. if (minSignal == DBL_MAX) { - minSignal = 0.0; - maxSignal = 1.0; - } + minSignal = defaultMin; + maxSignal = defaultMax; + } QwtDoubleInterval minMaxContainer; @@ -126,7 +136,7 @@ namespace Mantid minMaxContainer = QwtDoubleInterval(minSignal*0.5, minSignal*1.5); else // Other default value - minMaxContainer = QwtDoubleInterval(0., 1.0); + minMaxContainer = QwtDoubleInterval(defaultMin, defaultMax); } return minMaxContainer; @@ -140,32 +150,43 @@ namespace Mantid QwtDoubleInterval MetaDataExtractorUtils::getRange(Mantid::API::IMDIterator * it) { if (!it) - return QwtDoubleInterval(0., 1.0); + return QwtDoubleInterval(defaultMin, defaultMax); if (!it->valid()) - return QwtDoubleInterval(0., 1.0); + return QwtDoubleInterval(defaultMin, defaultMax); // Use no normalization it->setNormalization(Mantid::API::VolumeNormalization); - + double minSignal = DBL_MAX; + double minSignalZeroCheck = DBL_MAX; double maxSignal = -DBL_MAX; auto inf = std::numeric_limits::infinity(); + do { double signal = it->getNormalizedSignal(); + // Skip any 'infs' as it screws up the color scale if (signal != inf) { - if (signal < minSignal) minSignal = signal; + if (signal == 0.0) minSignalZeroCheck = signal; + if (signal < minSignal && signal >0.0) minSignal = signal; if (signal > maxSignal) maxSignal = signal; } } while (it->next()); - if (minSignal == DBL_MAX) { - minSignal = inf; - maxSignal = inf; + if (minSignalZeroCheck != DBL_MAX) + { + minSignal = defaultMin; + maxSignal = defaultMax; + } + else + { + minSignal = inf; + maxSignal = inf; + } } return QwtDoubleInterval(minSignal, maxSignal); } diff --git a/Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp b/Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp new file mode 100644 index 000000000000..3936f1593467 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp @@ -0,0 +1,136 @@ +#include "MantidVatesAPI/MetadataJsonManager.h" +#include "jsoncpp/json/json.h" +#include "jsoncpp/json/writer.h" +#include "jsoncpp/json/reader.h" + +namespace Mantid +{ + namespace VATES + { + // Note that we need to have a non-empty default string + MetadataJsonManager::MetadataJsonManager() : instrument("_EMPTY_"), minValue(0.0), maxValue(1.0) + { + + } + + MetadataJsonManager::~MetadataJsonManager() + { + } + + /** + * Get the serialized JSON container as a string + * @return The Json container in string format. + */ + std::string MetadataJsonManager::getSerializedJson() + { + Json::FastWriter writer; + metadataContainer.clear(); + + metadataContainer["instrument"] = instrument; + metadataContainer["minValue"] = minValue; + metadataContainer["maxValue"] = maxValue; + + return writer.write(metadataContainer); + } + + /** + * Read in the serialized JSON data and opulate the JSON container + * @param serialzedJson The serialized JSON string. + */ + void MetadataJsonManager::readInSerializedJson(std::string serializedJson) + { + Json::Reader reader; + metadataContainer.clear(); + + bool parseSuccess = reader.parse(serializedJson, metadataContainer, false); + + if (parseSuccess) + { + // Set the max value + if (metadataContainer.isObject() && metadataContainer.isMember("maxValue")) + { + maxValue = metadataContainer["maxValue"].asDouble(); + } + else + { + maxValue = 1.0; + } + + // Set the min value + if (metadataContainer.isObject() && metadataContainer.isMember("minValue")) + { + minValue = metadataContainer["minValue"].asDouble(); + } + else + { + minValue = 0.0; + } + + // Set the instrument + if (metadataContainer.isObject() && metadataContainer.isMember("instrument")) + { + instrument = metadataContainer["instrument"].asString(); + } + else + { + instrument = "_EMPTY_"; + } + } + } + + /** + * Set the max value of the workspace's data range. + * @param maxValue The max value. + */ + void MetadataJsonManager::setMaxValue(double maxValue) + { + this->maxValue = maxValue; + } + + /** + * Get the max value of teh workspace''s data range. + * @return The max value or 0.0. + */ + double MetadataJsonManager::getMaxValue() + { + return maxValue; + } + + /** + * Set the min value of the workspace's data range. + * @param minValue The min value. + */ + void MetadataJsonManager::setMinValue(double minValue) + { + this->minValue = minValue; + } + + /** + * Get the min value of teh workspace's data range. + * @returns The min value or 0.0; + * + */ + double MetadataJsonManager::getMinValue() + { + return minValue; + } + + /** + * Set the instrument. + * @param instrument The instrument associated with the workspace. + */ + void MetadataJsonManager::setInstrument(std::string instrument) + { + this->instrument = instrument; + } + + /** + * Get the instrument. + * @returns The stored instrument or the an empty string. + */ + std::string& MetadataJsonManager::getInstrument() + { + return instrument; + } + } +} \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/src/VatesConfigurations.cpp b/Code/Mantid/Vates/VatesAPI/src/VatesConfigurations.cpp new file mode 100644 index 000000000000..9ae3f8e1a9c7 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/VatesConfigurations.cpp @@ -0,0 +1,52 @@ +#include "MantidVatesAPI/VatesConfigurations.h" + +namespace Mantid +{ + namespace VATES + { + /** Metadata container and handler to handle json data which is passed between filters and sources through + VTK field data + + @date 31/11/2014 + + Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + + + VatesConfigurations::VatesConfigurations() :metaDataId("VATES_Metadata_Json"), maxRecursionDepth(10000) + { + } + + VatesConfigurations::~VatesConfigurations() + { + } + + int VatesConfigurations::getMaxRecursionDepth() + { + return this->maxRecursionDepth; + } + + std::string VatesConfigurations::getMetadataIdJson() + { + return this->metaDataId; + } + } +} \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp index 6efbe8065e92..b789e90a75e2 100644 --- a/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp @@ -211,7 +211,10 @@ namespace VATES saved_signals.reserve(numPoints); saved_centers.reserve(numPoints); saved_n_points_in_cell.reserve(numPoints); - + + double maxSignalScalar = 0; + double minSignalScalar = VTK_DOUBLE_MAX; + size_t pointIndex = 0; size_t box_index = 0; bool done = false; @@ -224,6 +227,8 @@ namespace VATES continue; } float signal_normalized = static_cast(box->getSignalNormalized()); + maxSignalScalar = maxSignalScalar > signal_normalized ? maxSignalScalar:signal_normalized; + minSignalScalar = minSignalScalar > signal_normalized ? signal_normalized : minSignalScalar; size_t newPoints = box->getNPoints(); size_t num_from_this_box = points_per_box; if (num_from_this_box > newPoints) @@ -305,7 +310,7 @@ namespace VATES //points->Squeeze(); signal->Squeeze(); visualDataSet->Squeeze(); - + // Add points and scalars visualDataSet->SetPoints(points); visualDataSet->GetCellData()->SetScalars(signal); @@ -530,13 +535,19 @@ namespace VATES this->slice = false; } - // Set the bounds - QwtDoubleInterval minMaxValue = m_metaDataExtractor->getMinAndMax(m_workspace); - m_minValue = minMaxValue.minValue(); - m_maxValue = minMaxValue.maxValue(); + // Macro to call the right instance of the + CALL_MDEVENT_FUNCTION(this->doCreate, m_workspace); + // Set the instrument m_instrument = m_metaDataExtractor->extractInstrument(m_workspace); + double* range = dataSet->GetScalarRange(); + if (range) + { + m_minValue = range[0]; + m_maxValue = range[1]; + } + // Check for the workspace type, i.e. if it is MDHisto or MDEvent IMDEventWorkspace_sptr eventWorkspace = boost::dynamic_pointer_cast(m_workspace); diff --git a/Code/Mantid/Vates/VatesAPI/test/EventNexusLoadingPresenterTest.h b/Code/Mantid/Vates/VatesAPI/test/EventNexusLoadingPresenterTest.h index 52eb60420c06..f6927da802b4 100644 --- a/Code/Mantid/Vates/VatesAPI/test/EventNexusLoadingPresenterTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/EventNexusLoadingPresenterTest.h @@ -85,7 +85,7 @@ void testExecution() TSM_ASSERT("Should have generated a vtkDataSet", NULL != product); TSM_ASSERT_EQUALS("Wrong type of output generated", "vtkUnstructuredGrid", std::string(product->GetClassName())); TSM_ASSERT("No field data!", NULL != product->GetFieldData()); - TSM_ASSERT_EQUALS("One array expected on field data!", 1, product->GetFieldData()->GetNumberOfArrays()); + TSM_ASSERT_EQUALS("Two arrays expected on field data, one for XML and one for JSON!", 2, product->GetFieldData()->GetNumberOfArrays()); TS_ASSERT_THROWS_NOTHING(presenter.hasTDimensionAvailable()); TS_ASSERT_THROWS_NOTHING(presenter.getGeometryXML()); TS_ASSERT(!presenter.getWorkspaceTypeName().empty()); diff --git a/Code/Mantid/Vates/VatesAPI/test/MDEWEventNexusLoadingPresenterTest.h b/Code/Mantid/Vates/VatesAPI/test/MDEWEventNexusLoadingPresenterTest.h index 5fd35ead5860..619769594eb6 100644 --- a/Code/Mantid/Vates/VatesAPI/test/MDEWEventNexusLoadingPresenterTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/MDEWEventNexusLoadingPresenterTest.h @@ -89,7 +89,7 @@ void testExecution() TSM_ASSERT("Should have generated a vtkDataSet", NULL != product); TSM_ASSERT_EQUALS("Wrong type of output generated", "vtkUnstructuredGrid", std::string(product->GetClassName())); TSM_ASSERT("No field data!", NULL != product->GetFieldData()); - TSM_ASSERT_EQUALS("One array expected on field data!", 1, product->GetFieldData()->GetNumberOfArrays()); + TSM_ASSERT_EQUALS("Two arrays expected on field data, one for XML and one for JSON!", 2, product->GetFieldData()->GetNumberOfArrays()); TS_ASSERT_THROWS_NOTHING(presenter.hasTDimensionAvailable()); TS_ASSERT_THROWS_NOTHING(presenter.getGeometryXML()); TS_ASSERT(!presenter.getWorkspaceTypeName().empty()); diff --git a/Code/Mantid/Vates/VatesAPI/test/MDEWInMemoryLoadingPresenterTest.h b/Code/Mantid/Vates/VatesAPI/test/MDEWInMemoryLoadingPresenterTest.h index 2e25aab7bfec..bbe46dc7f853 100644 --- a/Code/Mantid/Vates/VatesAPI/test/MDEWInMemoryLoadingPresenterTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/MDEWInMemoryLoadingPresenterTest.h @@ -129,6 +129,8 @@ class MDEWInMemoryLoadingPresenterTest: public CxxTest::TestSuite //Test that it does work when setup. presenter.executeLoadMetadata(); TSM_ASSERT("Should export geometry xml metadata on request.", !presenter.getGeometryXML().empty()); + TSM_ASSERT("Should export min value metadata on request.", presenter.getMinValue() <= presenter.getMaxValue()) + TSM_ASSERT("Should export instrument metadata on request", presenter.getInstrument().empty()) } void testExecution() @@ -161,7 +163,7 @@ class MDEWInMemoryLoadingPresenterTest: public CxxTest::TestSuite TSM_ASSERT("Should have generated a vtkDataSet", NULL != product); TSM_ASSERT_EQUALS("Wrong type of output generated", "vtkUnstructuredGrid", std::string(product->GetClassName())); TSM_ASSERT("No field data!", NULL != product->GetFieldData()); - TSM_ASSERT_EQUALS("One array expected on field data!", 1, product->GetFieldData()->GetNumberOfArrays()); + TSM_ASSERT_EQUALS("One array expected on field data, one for XML and one for JSON!", 2, product->GetFieldData()->GetNumberOfArrays()); TS_ASSERT_THROWS_NOTHING(presenter.hasTDimensionAvailable()); TS_ASSERT_THROWS_NOTHING(presenter.getGeometryXML()); TS_ASSERT(!presenter.getWorkspaceTypeName().empty()); diff --git a/Code/Mantid/Vates/VatesAPI/test/MDHWInMemoryLoadingPresenterTest.h b/Code/Mantid/Vates/VatesAPI/test/MDHWInMemoryLoadingPresenterTest.h index c84bc4350e57..0939db358367 100644 --- a/Code/Mantid/Vates/VatesAPI/test/MDHWInMemoryLoadingPresenterTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/MDHWInMemoryLoadingPresenterTest.h @@ -121,11 +121,17 @@ class MDHWInMemoryLoadingPresenterTest: public CxxTest::TestSuite //Test that it does work when setup. presenter.executeLoadMetadata(); + + std::string ins = presenter.getInstrument(); + TSM_ASSERT("Should export geometry xml metadata on request.", !presenter.getGeometryXML().empty()) + TSM_ASSERT("Should export min value metadata on request.", presenter.getMinValue() <= presenter.getMaxValue()) + TSM_ASSERT("Should export instrument metadata on request", presenter.getInstrument().empty()) } void testExecution() { + //Setup view MockMDLoadingView* view = new MockMDLoadingView; EXPECT_CALL(*view, getRecursionDepth()).Times(0); @@ -153,7 +159,7 @@ class MDHWInMemoryLoadingPresenterTest: public CxxTest::TestSuite TSM_ASSERT("Should have generated a vtkDataSet", NULL != product); TSM_ASSERT_EQUALS("Wrong type of output generated", "vtkUnstructuredGrid", std::string(product->GetClassName())); TSM_ASSERT("No field data!", NULL != product->GetFieldData()); - TSM_ASSERT_EQUALS("One array expected on field data!", 1, product->GetFieldData()->GetNumberOfArrays()); + TSM_ASSERT_EQUALS("Two arrays expected on field data, one for XML and one for JSON!", 2, product->GetFieldData()->GetNumberOfArrays()); TS_ASSERT_THROWS_NOTHING(presenter.hasTDimensionAvailable()); TS_ASSERT_THROWS_NOTHING(presenter.getGeometryXML()); TS_ASSERT(!presenter.getWorkspaceTypeName().empty()); diff --git a/Code/Mantid/Vates/VatesAPI/test/MDHWNexusLoadingPresenterTest.h b/Code/Mantid/Vates/VatesAPI/test/MDHWNexusLoadingPresenterTest.h index 27291051dc6a..efab02b5bb7d 100644 --- a/Code/Mantid/Vates/VatesAPI/test/MDHWNexusLoadingPresenterTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/MDHWNexusLoadingPresenterTest.h @@ -86,7 +86,7 @@ void testExecution() TSM_ASSERT("Should have generated a vtkDataSet", NULL != product); TSM_ASSERT_EQUALS("Wrong type of output generated", "vtkUnstructuredGrid", std::string(product->GetClassName())); TSM_ASSERT("No field data!", NULL != product->GetFieldData()); - TSM_ASSERT_EQUALS("One array expected on field data!", 1, product->GetFieldData()->GetNumberOfArrays()); + TSM_ASSERT_EQUALS("Two arrays expected on field data, one for XML and one for JSON!", 2, product->GetFieldData()->GetNumberOfArrays()); TS_ASSERT_THROWS_NOTHING(presenter.hasTDimensionAvailable()); TS_ASSERT_THROWS_NOTHING(presenter.getGeometryXML()); TS_ASSERT(!presenter.getWorkspaceTypeName().empty()); diff --git a/Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h b/Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h new file mode 100644 index 000000000000..0d7a517d46c1 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h @@ -0,0 +1,85 @@ +#ifndef METADATAEXTRACTORUTILS_TEST_H +#define METADATAEXTRACTORUTILS_TEST_H + +#include "MantidVatesAPI/MetaDataExtractorUtils.h" + +#include +#include +#include +#include "MockObjects.h" + +#include "qwt/qwt_double_interval.h" +#include "MantidTestHelpers/MDEventsTestHelper.h" +#include "MantidAPI/FileFinder.h" +#include "boost/pointer_cast.hpp" + +using namespace Mantid::VATES; +using namespace Mantid::API; +using namespace testing; +using Mantid::MDEvents::MDEventsTestHelper::makeFakeMDHistoWorkspace; + +class MetaDataExtractorUtilsTest : public CxxTest::TestSuite +{ + + public: + + // Helper method. Generates and returns a valid IMDEventWorkspace + static Mantid::API::Workspace_sptr getReal4DWorkspace() + { + AnalysisDataService::Instance().remove("MD_EVENT_WS_ID"); + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("LoadMD"); + alg->initialize(); + alg->setRethrows(true); + alg->setPropertyValue("Filename", Mantid::API::FileFinder::Instance().getFullPath("MAPS_MDEW.nxs")); + alg->setPropertyValue("OutputWorkspace", "MD_EVENT_WS_ID"); + alg->setProperty("FileBackEnd", false); + alg->execute(); + return AnalysisDataService::Instance().retrieve("MD_EVENT_WS_ID"); + } + + void testShouldExtractMinAndMaxFromWorkspaceForMDHisto() + { + // Arrange + double maxValue = 1.3; + Mantid::MDEvents::MDHistoWorkspace_sptr histoWorkspace = makeFakeMDHistoWorkspace(1.0, 4, 5, maxValue, 0.1,"MD_HISTO_WS"); + + // Act + MetaDataExtractorUtils extractor; + QwtDoubleInterval minMax = extractor.getMinAndMax(histoWorkspace); + + // Assert + TSM_ASSERT("Should find the a min which is smaller/equal to max ", minMax.minValue() <= minMax.maxValue()) + } + + void testShouldExtractMinAndMaxFromWorkspaceForMDEvent() + { + // Arrange + Mantid::API::Workspace_sptr workspace = getReal4DWorkspace(); + Mantid::API::IMDEventWorkspace_sptr eventWorkspace = boost::dynamic_pointer_cast(workspace); + MetaDataExtractorUtils extractor; + + // Act + QwtDoubleInterval minMax = extractor.getMinAndMax(eventWorkspace); + + // Assert + TSM_ASSERT("Should find the a min which is smaller/equal to max ", minMax.minValue() <= minMax.maxValue()) + } + + void testShouldNotFindInstrumentForBadWorkspace() + { + // Arrange + // Return a table workspace. + Mantid::API::Workspace_sptr workspace = WorkspaceFactory::Instance().createTable(); + Mantid::API::IMDHistoWorkspace_sptr histoWorkspace = boost::dynamic_pointer_cast(workspace); + + MetaDataExtractorUtils extractor; + + // Act + std::string instrument = extractor.extractInstrument(histoWorkspace); + + // Assert + TSM_ASSERT("Should find an empty instrment for invalid workspace", instrument.empty()) + } +}; + +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h b/Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h new file mode 100644 index 000000000000..178af51ed1ba --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h @@ -0,0 +1,108 @@ +#ifndef METADATA_JSON_MANAGER_TEST +#define METADATA_JSON_MANAGER_TEST + +#include +#include "MantidVatesAPI/MetadataJsonManager.h" +#include +#include "jsoncpp/json/reader.h" + +using Mantid::VATES::MetadataJsonManager; + +class MetadataJsonManagerTest: public CxxTest::TestSuite +{ + public: + + void testDefaultValuesAreReturnedWhenContainerIsNotSet() + { + // Arrange + MetadataJsonManager manager; + + // Act + std::string instrument = manager.getInstrument(); + double minValue = manager.getMinValue(); + double maxValue = manager.getMaxValue(); + + // Assert + double expectedMinValue = 0.0; + double expectedMaxValue = 1.0; + std::string expectedInstrument("_EMPTY_"); + + TSM_ASSERT("The instrument string is empty, since it does not exist.", expectedInstrument == instrument); + TSM_ASSERT_EQUALS("The min default value is 0.0.", expectedMinValue, minValue); + TSM_ASSERT_EQUALS("The max default value is 1.0.", expectedMaxValue, maxValue); + } + + void testSetValuesCanBeReadOut() + { + // Arrange + MetadataJsonManager manager; + + std::string instrument = "OSIRIS"; + double minValue = 123.0; + double maxValue = 124234.3; + + // Act + manager.setInstrument(instrument); + manager.setMinValue(minValue); + manager.setMaxValue(maxValue); + + // Assert + TSM_ASSERT_EQUALS("The instrument is read in and out.", instrument, manager.getInstrument()); + TSM_ASSERT_EQUALS("The min value is read in and out.", minValue, manager.getMinValue()); + TSM_ASSERT_EQUALS("The max value is read in and out.", maxValue, manager.getMaxValue()); + } + + void testJsonStringIsReadInAndPopualtesContainer() + { + // Arrange + MetadataJsonManager manager; + std::string jsonString = "{\"instrument\": \"OSIRIS\", \"minValue\":1.0, \"maxValue\": 2.0}"; + + // Act + manager.readInSerializedJson(jsonString); + + // Assert + + TSM_ASSERT("The instrument of the serialized Json string is detected.", manager.getInstrument() == "OSIRIS"); + TSM_ASSERT_EQUALS("The min value of the serialized Json string is detected.", 1.0, manager.getMinValue()); + TSM_ASSERT_EQUALS("The max value of the serialized Json string is detected.", 2.0, manager.getMaxValue()); + } + + void testJsonStringWhichDoesNotHaveFieldsProducesDefaultValues() + { + // Arrange + MetadataJsonManager manager; + std::string jsonString = "{\"myInstrument\": \"OSIRIS\", \"myMinValue\":1.0, \"myMaxValue\": 2.0}"; + + // Act + manager.readInSerializedJson(jsonString); + + // Assert + std::string expectedInstrument ="_EMPTY_"; + TSM_ASSERT("The json object does not find the instrument field and returns default.", manager.getInstrument() == expectedInstrument); + TSM_ASSERT_EQUALS("The json object does not find the max value field and returns default.", 0.0, manager.getMinValue()); + TSM_ASSERT_EQUALS("The json object does not find the min value field and returns default.", 1.0, manager.getMaxValue()); + } + + void testCorrectJsonStringIsProduced() + { + // Arrange + MetadataJsonManager manager; + manager.setInstrument("OSIRIS"); + manager.setMaxValue(3.0); + manager.setMinValue(2.0); + + // Act + std::string jsonString = manager.getSerializedJson(); + Json::Reader reader; + Json::Value container; + reader.parse(jsonString, container, false); + + // Assert + TSM_ASSERT("Json string is being produced", !jsonString.empty()); + TSM_ASSERT_EQUALS("Json string contains inserted instrument.", "OSIRIS", container["instrument"].asString()); + TSM_ASSERT_EQUALS("Json string contains inserted min value.", 2.0, container["minValue"].asDouble()); + TSM_ASSERT_EQUALS("Json string containns inserted max value.", 3.0, container["maxValue"].asDouble()); + } +}; +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/test/SQWLoadingPresenterTest.h b/Code/Mantid/Vates/VatesAPI/test/SQWLoadingPresenterTest.h index bcac5e5db461..5864dac11419 100644 --- a/Code/Mantid/Vates/VatesAPI/test/SQWLoadingPresenterTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/SQWLoadingPresenterTest.h @@ -119,7 +119,7 @@ void testExecutionInMemory() TSM_ASSERT("Should have generated a vtkDataSet", NULL != product); TSM_ASSERT_EQUALS("Wrong type of output generated", "vtkUnstructuredGrid", std::string(product->GetClassName())); TSM_ASSERT("No field data!", NULL != product->GetFieldData()); - TSM_ASSERT_EQUALS("One array expected on field data!", 1, product->GetFieldData()->GetNumberOfArrays()); + TSM_ASSERT_EQUALS("Two arrays expected on field data, one for XML and one for JSON!", 2, product->GetFieldData()->GetNumberOfArrays()); TS_ASSERT_THROWS_NOTHING(presenter.hasTDimensionAvailable()); TS_ASSERT_THROWS_NOTHING(presenter.getGeometryXML()); TS_ASSERT(!presenter.getWorkspaceTypeName().empty()); diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h index ccc897cbeaa3..7e13e15895c7 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h @@ -32,6 +32,7 @@ #include class pqPipelineSource; +class pqDataRepresentation; namespace Mantid { @@ -85,8 +86,7 @@ class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS AutoScaleRangeGenerator * @param minValueBuffer A reference to a min value. * @param maxValueBuffer A reference to a max value. */ - void AutoScaleRangeGenerator::setMinBufferAndMaxBuffer(pqPipelineSource* source, double& minValue, double& maxValue); - + void AutoScaleRangeGenerator::setMinBufferAndMaxBuffer(pqPipelineSource* source, double& minValue, double& maxValue); }; } diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp index 8d4a7fa821f9..f717e09ea452 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp @@ -11,7 +11,10 @@ #include #include #include +#include #include +#include +#include namespace Mantid { @@ -140,32 +143,61 @@ namespace SimpleGui while(isFilter) { - // If we are dealing with a filter, we can cast it. + // Make sure that the pipeline properties are up to date + vtkSMProxy* proxy = pqSource->getProxy(); + proxy->UpdateVTKObjects(); + proxy->UpdatePropertyInformation(); + pqSource->updatePipeline(); + + // If we are dealing with a filter, we can cast it. If it is a source, + // then the cast should result in a NULL, an exception is the splatterplot filter which + // also contains size information pqPipelineFilter* filter = qobject_cast(pqSource); - if (!filter) + if (QString(proxy->GetXMLName()).contains("SplatterPlot")) { - isFilter = false; + minValue = vtkSMPropertyHelper(proxy,"MinValue").GetAsDouble(); + + maxValue = vtkSMPropertyHelper(proxy,"MaxValue").GetAsDouble(); + + isFilter = false; + } + else if (!filter) + { + // Only MDEvent and MDHisto workspaces will provide us with min and max + const char* workspaceTypeName = vtkSMPropertyHelper(proxy,"WorkspaceTypeName").GetAsString(); + std::string workspaceType(workspaceTypeName); + size_t mdEvent = workspaceType.find("MDEventWorkspace"); + size_t mdHisto = workspaceType.find("MDHistoWorkspace"); - minValue = vtkSMPropertyHelper(pqSource->getProxy(), - "MinValue").GetAsDouble(); + if (mdEvent != std::string::npos || mdHisto != std::string::npos) + { + minValue = vtkSMPropertyHelper(proxy,"MinValue").GetAsDouble(); - maxValue = vtkSMPropertyHelper(pqSource->getProxy(), - "MaxValue").GetAsDouble(); + maxValue = vtkSMPropertyHelper(proxy,"MaxValue").GetAsDouble(); + } + else + { + // Peak Source should not produce a color scale range + minValue = DBL_MAX; + maxValue = -DBL_MAX; + } + + isFilter = false; } else { - // We expect one input, if not provide defailt values + // We expect one input, if not provide default values if (filter->getInputCount() != 1) { minValue = this->defaultValue; maxValue = this->defaultValue; + isFilter = false; } else { QList outputPorts = filter->getAllInputs(); - pqSource = outputPorts[0]->getSource(); } } diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp index fcc0bc19a952..015fd3db00ca 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp @@ -455,11 +455,6 @@ void MdViewerWidget::setParaViewComponentsForView() SLOT(onParallelProjection(bool))); } - - - - - /** * This function loads and renders data from the given source for the * standalone mode. @@ -727,6 +722,7 @@ void MdViewerWidget::renderAndFinalSetup() this->currentView->checkView(this->initialView); this->currentView->updateAnimationControls(); this->setVisibilityListener(); + this->currentView->onAutoScale(this->ui.colorSelectionWidget); } /** diff --git a/Test/AutoTestData/UsageData/INES_Definition.vtp b/Test/AutoTestData/UsageData/INES_Definition.vtp new file mode 100644 index 000000000000..23a71effa310 --- /dev/null +++ b/Test/AutoTestData/UsageData/INES_Definition.vtp @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + From 180015e49016326eb97d1ec592e1e97328259cdd Mon Sep 17 00:00:00 2001 From: Anton Piccardo-Selg Date: Wed, 10 Dec 2014 08:32:14 +0000 Subject: [PATCH 016/275] Refs #10627 Added range extraction from filters --- .../MDEWRebinningCutter.xml | 16 ++++ .../vtkMDEWRebinningCutter.cxx | 65 ++++++++++++- .../vtkMDEWRebinningCutter.h | 3 + .../RebinningTransformOperator.xml | 16 ++++ .../vtkRebinningTransformOperator.cxx | 62 ++++++++++++ .../vtkRebinningTransformOperator.h | 7 +- .../ScaleWorkspace/vtkScaleWorkspace.cxx | 4 +- .../ScaleWorkspace/vtkScaleWorkspace.h | 3 - .../MantidVatesAPI/MDEWRebinningPresenter.h | 14 +++ .../inc/MantidVatesAPI/MDRebinningPresenter.h | 3 + .../MantidVatesAPI/NullRebinningPresenter.h | 6 ++ .../VatesAPI/src/MDEWRebinningPresenter.cpp | 61 +++++++++++- .../VatesAPI/src/NullRebinningPresenter.cpp | 15 +++ .../test/MDEWRebinningPresenterTest.h | 70 ++++++++++---- .../test/vtkDataSetToScaledDataSetTest.h | 50 ++++++++++ .../src/AutoScaleRangeGenerator.cpp | 94 ++++++++----------- .../ViewWidgets/src/SplatterPlotView.cpp | 2 +- 17 files changed, 407 insertions(+), 84 deletions(-) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/MDEWRebinningCutter.xml b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/MDEWRebinningCutter.xml index 5320b90ec4de..957ff1acc045 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/MDEWRebinningCutter.xml +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/MDEWRebinningCutter.xml @@ -82,6 +82,22 @@ number_of_elements="1" default_values="--"> + + + + + + diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/vtkMDEWRebinningCutter.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/vtkMDEWRebinningCutter.cxx index 62744484d5ce..8fa8ec34b017 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/vtkMDEWRebinningCutter.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/vtkMDEWRebinningCutter.cxx @@ -430,8 +430,6 @@ unsigned long vtkMDEWRebinningCutter::GetMTime() return mTime; } - - void vtkMDEWRebinningCutter::setTimeRange(vtkInformationVector* outputVector) { if(SetupDone == m_setup) @@ -453,6 +451,69 @@ void vtkMDEWRebinningCutter::setTimeRange(vtkInformationVector* outputVector) } } +/** + * Gets the minimum value of the data associated with the + * workspace. + * @return The minimum value of the workspace data. + */ +double vtkMDEWRebinningCutter::GetMinValue() const +{ + if (NULL == m_presenter) + { + return 0.0; + } + try + { + return m_presenter->getMinValue(); + } + catch (std::runtime_error &) + { + return 0; + } +} + +/** + * Gets the maximum value of the data associated with the + * workspace. + * @return The maximum value of the workspace data. + */ +double vtkMDEWRebinningCutter::GetMaxValue() const +{ + if (NULL == m_presenter) + { + return 0.0; + } + try + { + return m_presenter->getMaxValue(); + } + catch (std::runtime_error &) + { + return 0; + } +} + +/** + * Gets the (first) instrument which is associated with the workspace. + * @return The name of the instrument. + */ +const char* vtkMDEWRebinningCutter::GetInstrument() const +{ + if (NULL == m_presenter) + { + return ""; + } + try + { + return m_presenter->getInstrument().c_str(); + } + catch (std::runtime_error &) + { + return ""; + } +} + + Mantid::Kernel::V3D vtkMDEWRebinningCutter::getOrigin() { throw std::runtime_error("Not implemented on vtkMDEWRebinningCutter."); diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/vtkMDEWRebinningCutter.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/vtkMDEWRebinningCutter.h index f70e0fdc06cd..03315a012f70 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/vtkMDEWRebinningCutter.h +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/vtkMDEWRebinningCutter.h @@ -87,6 +87,9 @@ class VTK_EXPORT vtkMDEWRebinningCutter : public vtkUnstructuredGridAlgorithm//, virtual double getLengthB3() const; virtual bool getForceOrthogonal() const { throw std::runtime_error("Not implemented"); } virtual bool getOutputHistogramWS() const; + virtual double GetMinValue() const; + virtual double GetMaxValue() const; + virtual const char* GetInstrument() const; protected: diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/RebinningTransformOperator.xml b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/RebinningTransformOperator.xml index d3ec151a6e46..80a685aea8cd 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/RebinningTransformOperator.xml +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/RebinningTransformOperator.xml @@ -128,6 +128,22 @@ information_only="1" si_class="vtkSITimeLabelProperty"> + + + + + + diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/vtkRebinningTransformOperator.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/vtkRebinningTransformOperator.cxx index acb764342886..bb1703d838fb 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/vtkRebinningTransformOperator.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/vtkRebinningTransformOperator.cxx @@ -534,3 +534,65 @@ bool vtkRebinningTransformOperator::getForceOrthogonal() const { return m_ForceOrthogonal; } + +/** + * Gets the minimum value of the data associated with the + * workspace. + * @return The minimum value of the workspace data. + */ +double vtkRebinningTransformOperator::GetMinValue() const +{ + if (NULL == m_presenter) + { + return 0.0; + } + try + { + return m_presenter->getMinValue(); + } + catch (std::runtime_error &) + { + return 0; + } +} + +/** + * Gets the maximum value of the data associated with the + * workspace. + * @return The maximum value of the workspace data. + */ +double vtkRebinningTransformOperator::GetMaxValue() const +{ + if (NULL == m_presenter) + { + return 0.0; + } + try + { + return m_presenter->getMaxValue(); + } + catch (std::runtime_error &) + { + return 0; + } +} + +/** + * Gets the (first) instrument which is associated with the workspace. + * @return The name of the instrument. + */ +const char* vtkRebinningTransformOperator::GetInstrument() const +{ + if (NULL == m_presenter) + { + return ""; + } + try + { + return m_presenter->getInstrument().c_str(); + } + catch (std::runtime_error &) + { + return ""; + } +} diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/vtkRebinningTransformOperator.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/vtkRebinningTransformOperator.h index 53cda28193bd..309e7c3d3d6e 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/vtkRebinningTransformOperator.h +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/vtkRebinningTransformOperator.h @@ -2,10 +2,13 @@ #define _vtkRebinningTransformOperator_h #include #include "vtkUnstructuredGridAlgorithm.h" +#include "MantidVatesAPI/MetadataJsonManager.h" #include "MantidVatesAPI/ThresholdRange.h" +#include "MantidVatesAPI/VatesConfigurations.h" #include "MantidGeometry/MDGeometry/MDTypes.h" #include "MantidKernel/MultiThreaded.h" #include "MantidKernel/V3D.h" +#include #include /** @@ -100,6 +103,9 @@ class VTK_EXPORT vtkRebinningTransformOperator : public vtkUnstructuredGridAlgor virtual double getLengthB3() const; virtual bool getForceOrthogonal() const; virtual bool getOutputHistogramWS() const; + virtual double GetMinValue() const; + virtual double GetMaxValue() const; + virtual const char* GetInstrument() const; protected: @@ -172,6 +178,5 @@ class VTK_EXPORT vtkRebinningTransformOperator : public vtkUnstructuredGridAlgor bool m_ForceOrthogonal; /// Flag indicating that a histogram workspace should be provided. bool m_bOutputHistogramWS; - }; #endif diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx index ad8a531fa1c0..77c9dcb81e1b 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx @@ -113,7 +113,7 @@ void vtkScaleWorkspace::SetZScaling(double zScaling) /** * Gets the minimum value of the data associated with the * workspace. - * @return The minimum value of the workspace data. + * @returns The minimum value of the workspace data. */ double vtkScaleWorkspace::GetMinValue() { @@ -123,7 +123,7 @@ double vtkScaleWorkspace::GetMinValue() /** * Gets the maximum value of the data associated with the * workspace. - * @return The maximum value of the workspace data. + * @returns The maximum value of the workspace data. */ double vtkScaleWorkspace::GetMaxValue() { diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.h index 7dcb2cd3e881..a48719311248 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.h +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.h @@ -15,11 +15,8 @@ class VTK_EXPORT vtkScaleWorkspace : public vtkUnstructuredGridAlgorithm void SetXScaling(double xScaling); void SetYScaling(double yScaling); void SetZScaling(double zScaling); - /// Getter for the minimum value of the workspace data double GetMinValue(); - /// Getter for the maximum value of the workspace data double GetMaxValue(); - /// Getter for the instrument associated with the instrument. const char* GetInstrument(); protected: diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWRebinningPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWRebinningPresenter.h index 1852a68794aa..f3b4c352c201 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWRebinningPresenter.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWRebinningPresenter.h @@ -3,7 +3,9 @@ #include "MantidVatesAPI/MDRebinningPresenter.h" #include "MantidGeometry/MDGeometry/MDImplicitFunction.h" +#include "MantidVatesAPI/MetadataJsonManager.h" #include "MantidVatesAPI/RebinningKnowledgeSerializer.h" +#include "MantidVatesAPI/VatesConfigurations.h" #include "MantidVatesAPI/vtkDataSetToGeometry.h" #include #include "MantidKernel/VMD.h" @@ -68,6 +70,12 @@ namespace Mantid virtual void setAxisLabels(vtkDataSet* visualDataSet); + virtual const std::string& getInstrument() const; + + virtual double getMaxValue() const; + + virtual double getMinValue() const; + /*-----------------------------------End MDRebinningPresenter methods -------------------------------------*/ MDEWRebinningPresenter(vtkDataSet* input, RebinningActionManager* request, MDRebinningView* view, const WorkspaceProvider& wsProvider); @@ -121,6 +129,12 @@ namespace Mantid bool m_bOutputHistogramWS; /// Tag for the rebinned workspace static const std::string rb_tag; + /// Pointer to the manager for json metadata + boost::scoped_ptr m_metadataJsonManager; + /// Pointer to the vates configuration object + boost::scoped_ptr m_vatesConfigurations; + /// Store for the instrument + mutable std::string m_instrument; }; } } diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDRebinningPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDRebinningPresenter.h index 2ac3a4f4e5fa..e73dc31f5f0c 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDRebinningPresenter.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDRebinningPresenter.h @@ -52,6 +52,9 @@ namespace Mantid virtual void makeNonOrthogonal(vtkDataSet* visualDataSet) = 0; virtual void setAxisLabels(vtkDataSet* visualDataSet) = 0; virtual ~MDRebinningPresenter(){} + virtual const std::string& getInstrument() const = 0; + virtual double getMaxValue() const = 0; + virtual double getMinValue() const = 0; }; typedef boost::shared_ptr MDRebinningPresenter_sptr; diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/NullRebinningPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/NullRebinningPresenter.h index 715428b19b43..33313ff473fe 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/NullRebinningPresenter.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/NullRebinningPresenter.h @@ -27,6 +27,12 @@ namespace Mantid virtual void setAxisLabels(vtkDataSet* visualDataSet); + virtual const std::string& getInstrument() const; + + virtual double getMaxValue() const; + + virtual double getMinValue() const; + virtual ~NullRebinningPresenter(); private: diff --git a/Code/Mantid/Vates/VatesAPI/src/MDEWRebinningPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDEWRebinningPresenter.cpp index 65be06cf1483..f0292c682328 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDEWRebinningPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDEWRebinningPresenter.cpp @@ -10,12 +10,14 @@ #include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" #include "MantidVatesAPI/FieldDataToMetadata.h" #include "MantidVatesAPI/MetadataToFieldData.h" +#include "MantidVatesAPI/MetadataJsonManager.h" #include "MantidVatesAPI/vtkDataSetFactory.h" #include "MantidVatesAPI/WorkspaceProvider.h" #include "MantidVatesAPI/vtkDataSetToImplicitFunction.h" #include "MantidVatesAPI/vtkDataSetToNonOrthogonalDataSet.h" #include "MantidVatesAPI/vtkDataSetToWsLocation.h" #include "MantidVatesAPI/vtkDataSetToWsName.h" +#include "MantidVatesAPI/VatesConfigurations.h" #include "MantidVatesAPI/Common.h" #include "MantidAPI/AlgorithmManager.h" #include "MantidAPI/ImplicitFunctionFactory.h" @@ -56,7 +58,10 @@ namespace Mantid m_lengthB2(1), m_lengthB3(1), m_ForceOrthogonal(true), - m_bOutputHistogramWS(true) + m_bOutputHistogramWS(true), + m_instrument(""), + m_metadataJsonManager(new MetadataJsonManager()), + m_vatesConfigurations(new VatesConfigurations()) { using namespace Mantid::API; vtkFieldData* fd = input->GetFieldData(); @@ -105,6 +110,18 @@ namespace Mantid //Apply the workspace name after extraction from the input xml. m_serializer.setWorkspaceName( wsName); + // Extract Json metadata from the field data + if(NULL == fd || NULL == fd->GetArray(m_vatesConfigurations->getMetadataIdJson().c_str())) + { + throw std::logic_error("Rebinning operations require Rebinning Json Metadata"); + } + + FieldDataToMetadata fieldDataToMetadata; + + std::string jsonString = fieldDataToMetadata(fd, m_vatesConfigurations->getMetadataIdJson()); + m_metadataJsonManager->readInSerializedJson(jsonString); + + m_instrument = m_metadataJsonManager->getInstrument(); } /// Destructor @@ -388,9 +405,19 @@ namespace Mantid Mantid::API::Workspace_sptr result=Mantid::API::AnalysisDataService::Instance().retrieve(outWsName); - vtkDataSet* temp = factory->oneStepCreate(result, drawingProgressUpdate); + vtkDataSet* temp = factory->oneStepCreate(result, drawingProgressUpdate); + + // Extract min and max range of the data set and update the json store + double* range = temp->GetScalarRange(); + + if (range) + { + m_metadataJsonManager->setMinValue(range[0]); + m_metadataJsonManager->setMaxValue(range[1]); + } persistReductionKnowledge(temp, this->m_serializer, XMLDefinitions::metaDataId().c_str()); + m_request->reset(); return temp; } @@ -467,9 +494,39 @@ namespace Mantid MetadataToFieldData convert; convert(fd, xmlGenerator.createXMLString().c_str(), id); + // Add second entry for Json metadata + std::string jsonMetadata = m_metadataJsonManager->getSerializedJson(); + convert(fd, jsonMetadata, m_vatesConfigurations->getMetadataIdJson()); + out_ds->SetFieldData(fd); fd->Delete(); } + /** + * Get the maximum value of the data range. + * @returns The maximum value. + */ + double MDEWRebinningPresenter::getMaxValue() const + { + return this->m_metadataJsonManager->getMaxValue(); + } + + /** + * Get the minimum value of the data range. + * @retruns The maximum value of the data range. + */ + double MDEWRebinningPresenter::getMinValue() const + { + return this->m_metadataJsonManager->getMinValue(); + } + + /** + * Get the instrument associated with the workspace + * @returns The instrument + */ + const std::string& MDEWRebinningPresenter::getInstrument() const + { + return m_instrument; + } } } diff --git a/Code/Mantid/Vates/VatesAPI/src/NullRebinningPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/NullRebinningPresenter.cpp index d273163cfb68..b313d1c3ef40 100644 --- a/Code/Mantid/Vates/VatesAPI/src/NullRebinningPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/NullRebinningPresenter.cpp @@ -54,5 +54,20 @@ namespace Mantid UNUSED_ARG(visualDataSet); throw std::runtime_error("NullRebinningPresenter does not implement this method. Misused"); } + + const std::string& NullRebinningPresenter::getInstrument() const + { + throw std::runtime_error("NullRebinningPresenter does not implement this method. Misused"); + } + + double NullRebinningPresenter::getMaxValue() const + { + throw std::runtime_error("NullRebinningPresenter does not implement this method. Misused"); + } + + double NullRebinningPresenter::getMinValue() const + { + throw std::runtime_error("NullRebinningPresenter does not implement this method. Misused"); + } } } diff --git a/Code/Mantid/Vates/VatesAPI/test/MDEWRebinningPresenterTest.h b/Code/Mantid/Vates/VatesAPI/test/MDEWRebinningPresenterTest.h index ffd5adaa08a0..e92aae121b13 100644 --- a/Code/Mantid/Vates/VatesAPI/test/MDEWRebinningPresenterTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/MDEWRebinningPresenterTest.h @@ -8,8 +8,9 @@ #include "MockObjects.h" #include "MantidVatesAPI/MDEWRebinningPresenter.h" - +#include "MantidVatesAPI/MetadataToFieldData.h" #include "MantidVatesAPI/RebinningKnowledgeSerializer.h" +#include "MantidVatesAPI/VatesConfigurations.h" #include "MantidVatesAPI/ADSWorkspaceProvider.h" #include "MantidVatesAPI/vtkMDHistoHexFactory.h" #include "MantidVatesAPI/vtkMDHistoHex4DFactory.h" @@ -28,7 +29,27 @@ using namespace Mantid::MDEvents; //===================================================================================== class MDEWRebinningPresenterTest : public CxxTest::TestSuite { +private: + + vtkFieldData* generateFieldData(std::string testData) + { + // Create mock object + vtkFieldData* fieldData = createFieldDataWithCharArray(testData); + + // Generate metadata + MetadataJsonManager manager; + manager.setInstrument("OSIRIS"); + + VatesConfigurations config; + std::string jsonString = manager.getSerializedJson(); + + // Add additional json metadata to the field data + MetadataToFieldData convert; + convert(fieldData, jsonString, config.getMetadataIdJson().c_str()); + + return fieldData; + } public: @@ -47,7 +68,7 @@ class MDEWRebinningPresenterTest : public CxxTest::TestSuite MockRebinningActionManager actionManager; vtkUnstructuredGrid* dataset = vtkUnstructuredGrid::New(); - dataset->SetFieldData(createFieldDataWithCharArray(constructXML("qx", "qy", "qz", "en"))); + dataset->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); MockWorkspaceProvider wsProvider; EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillOnce(Return(false)); @@ -62,7 +83,7 @@ class MDEWRebinningPresenterTest : public CxxTest::TestSuite EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(createFieldDataWithCharArray(constructXML("qx", "qy", "qz", "en"))); + dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); MDEWRebinningPresenter presenter(dataSet, pRequest, new MockMDRebinningView, wsProvider); TSM_ASSERT("Geometry should be available immediately after construction.", !presenter.getAppliedGeometryXML().empty()); @@ -86,7 +107,7 @@ class MDEWRebinningPresenterTest : public CxxTest::TestSuite EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(createFieldDataWithCharArray(constructXML("qx", "qy", "qz", "en"))); + dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); presenter.updateModel(); @@ -113,7 +134,7 @@ class MDEWRebinningPresenterTest : public CxxTest::TestSuite EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(createFieldDataWithCharArray(constructXML("qx", "qy", "qz", "en"))); + dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); presenter.updateModel(); @@ -140,7 +161,7 @@ class MDEWRebinningPresenterTest : public CxxTest::TestSuite EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(createFieldDataWithCharArray(constructXML("qx", "qy", "qz", "en"))); + dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); presenter.updateModel(); @@ -167,7 +188,7 @@ class MDEWRebinningPresenterTest : public CxxTest::TestSuite EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(createFieldDataWithCharArray(constructXML("qx", "qy", "qz", "en"))); + dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); presenter.updateModel(); @@ -194,7 +215,7 @@ class MDEWRebinningPresenterTest : public CxxTest::TestSuite EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(createFieldDataWithCharArray(constructXML("qx", "qy", "qz", "en"))); + dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); presenter.updateModel(); @@ -221,7 +242,7 @@ class MDEWRebinningPresenterTest : public CxxTest::TestSuite EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(createFieldDataWithCharArray(constructXML("qx", "qy", "qz", "en"))); + dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); presenter.updateModel(); @@ -249,7 +270,7 @@ class MDEWRebinningPresenterTest : public CxxTest::TestSuite EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(createFieldDataWithCharArray(constructXML("qx", "qy", "qz", "en"))); + dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); presenter.updateModel(); @@ -276,7 +297,7 @@ class MDEWRebinningPresenterTest : public CxxTest::TestSuite EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(createFieldDataWithCharArray(constructXML("qx", "qy", "qz", "en"))); + dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); presenter.updateModel(); @@ -312,7 +333,7 @@ class MDEWRebinningPresenterTest : public CxxTest::TestSuite EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(createFieldDataWithCharArray(constructXML("qx", "qy", "qz", "en"))); + dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); presenter.updateModel(); @@ -352,7 +373,7 @@ class MDEWRebinningPresenterTest : public CxxTest::TestSuite EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(createFieldDataWithCharArray(constructXML("qx", "qy", "qz", "en"))); + dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); presenter.updateModel(); @@ -393,7 +414,7 @@ class MDEWRebinningPresenterTest : public CxxTest::TestSuite EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(createFieldDataWithCharArray(constructXML("qx", "qy", "qz", "en"))); + dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); presenter.updateModel(); @@ -416,7 +437,7 @@ class MDEWRebinningPresenterTest : public CxxTest::TestSuite // Create an empty dataset and attach that xml as field data. vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(createFieldDataWithCharArray(creationalXML)); + dataSet->SetFieldData(generateFieldData(creationalXML)); /* The vtkFilter is the view in our MVP set up. @@ -472,7 +493,7 @@ class MDEWRebinningPresenterTest : public CxxTest::TestSuite std::string creationalXML = serializer.createXMLString(); vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(createFieldDataWithCharArray(creationalXML)); + dataSet->SetFieldData(generateFieldData(creationalXML)); MockMDRebinningView* view = new MockMDRebinningView; EXPECT_CALL(*view, getOutputHistogramWS()).WillRepeatedly(Return(true)); @@ -508,7 +529,7 @@ class MDEWRebinningPresenterTest : public CxxTest::TestSuite std::string creationalXML = serializer.createXMLString(); vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(createFieldDataWithCharArray(creationalXML)); + dataSet->SetFieldData(generateFieldData(creationalXML)); MockMDRebinningView* view = new MockMDRebinningView; EXPECT_CALL(*view, getOutputHistogramWS()).WillRepeatedly(Return(true)); @@ -558,7 +579,7 @@ class MDEWRebinningPresenterTest : public CxxTest::TestSuite std::string creationalXML = serializer.createXMLString(); vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(createFieldDataWithCharArray(creationalXML)); + dataSet->SetFieldData(generateFieldData(creationalXML)); MockMDRebinningView* view = new MockMDRebinningView; EXPECT_CALL(*view, getOutputHistogramWS()).WillRepeatedly(Return(true)); @@ -597,6 +618,19 @@ class MDEWRebinningPresenterTest : public CxxTest::TestSuite "Axis1 (m)"); } + void testJsonMetadataExtractionFromRebinnedDataSet() + { + MockRebinningActionManager* pRequest = new MockRebinningActionManager; + MockWorkspaceProvider wsProvider; + EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); + + vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); + dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); + + MDEWRebinningPresenter presenter(dataSet, pRequest, new MockMDRebinningView, wsProvider); + TSM_ASSERT("Instrument should be available immediately after construction.", !presenter.getInstrument().empty()); + TSM_ASSERT("Instrument should be read out correctly.", presenter.getInstrument() == "OSIRIS"); + } }; #endif diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkDataSetToScaledDataSetTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkDataSetToScaledDataSetTest.h index 11a841e1ffdc..041a036bf847 100644 --- a/Code/Mantid/Vates/VatesAPI/test/vtkDataSetToScaledDataSetTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/vtkDataSetToScaledDataSetTest.h @@ -2,6 +2,10 @@ #define MANTID_VATESAPI_VTKDATASETTOSCALEDDATASETTEST_H_ #include "MantidTestHelpers/MDEventsTestHelper.h" +#include "MantidVatesAPI/FieldDataToMetadata.h" +#include "MantidVatesAPI/MetadataJsonManager.h" +#include "MantidVatesAPI/MetadataToFieldData.h" +#include "MantidVatesAPI/VatesConfigurations.h" #include "MantidVatesAPI/NoThresholdRange.h" #include "MantidVatesAPI/vtkDataSetToScaledDataSet.h" #include "MantidVatesAPI/vtkMDHexFactory.h" @@ -10,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +56,25 @@ class vtkDataSetToScaledDataSetTest : public CxxTest::TestSuite return vals; } + vtkUnstructuredGrid *makeDataSetWithJsonMetadata() + { + vtkUnstructuredGrid* data = makeDataSet(); + + MetadataJsonManager manager; + std::string instrument = "OSIRIS"; + manager.setInstrument(instrument); + std::string jsonString = manager.getSerializedJson(); + + MetadataToFieldData convert; + VatesConfigurations config; + vtkFieldData* fieldData = data->GetFieldData(); + convert(fieldData, jsonString, config.getMetadataIdJson().c_str()); + + data->SetFieldData(fieldData); + + return data; + } + public: // This pair of boilerplate methods prevent the suite being created statically // This means the constructor isn't called when running other tests @@ -127,6 +151,32 @@ class vtkDataSetToScaledDataSetTest : public CxxTest::TestSuite in->Delete(); out->Delete(); } + + void testJsonMetadataExtractionFromScaledDataSet() + { + // Arrange + vtkUnstructuredGrid *in = makeDataSetWithJsonMetadata(); + vtkUnstructuredGrid *out = vtkUnstructuredGrid::New(); + + // Act + vtkDataSetToScaledDataSet scaler(in, out); + scaler.initialize(0.1, 0.5, 0.2); + TS_ASSERT_THROWS_NOTHING(scaler.execute()); + + vtkFieldData* fieldData = out->GetFieldData(); + MetadataJsonManager manager; + VatesConfigurations config; + FieldDataToMetadata convert; + + std::string jsonString = convert(fieldData, config.getMetadataIdJson()); + manager.readInSerializedJson(jsonString); + + // Assert + TS_ASSERT("OSIRIS" == manager.getInstrument()); + + in->Delete(); + out->Delete(); + } }; diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp index f717e09ea452..3293a47f99dc 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp @@ -11,11 +11,14 @@ #include #include #include +#include #include #include #include #include +#include + namespace Mantid { namespace Vates @@ -137,70 +140,51 @@ namespace SimpleGui */ void AutoScaleRangeGenerator::setMinBufferAndMaxBuffer(pqPipelineSource* source, double& minValue, double& maxValue) { - pqPipelineSource* pqSource = source; + // Make sure that the pipeline properties are up to date + vtkSMProxy* proxy = source->getProxy(); + proxy->UpdateVTKObjects(); + proxy->UpdatePropertyInformation(); + source->updatePipeline(); + + // Check if source is custom filter + if (QString(proxy->GetXMLName()).contains("MantidParaViewScaleWorkspace") || + QString(proxy->GetXMLName()).contains("MDEWRebinningCutter") || + QString(proxy->GetXMLName()).contains("MantidParaViewSplatterPlot")) + { + minValue = vtkSMPropertyHelper(proxy,"MinValue").GetAsDouble(); + maxValue = vtkSMPropertyHelper(proxy,"MaxValue").GetAsDouble(); - bool isFilter = true; + return; + } - while(isFilter) + // Check if source is custom source (MDHisto or MDEvent) + if (QString(proxy->GetXMLName()).contains("MDEW Source") || + QString(proxy->GetXMLName()).contains("MDHW Source")) { - // Make sure that the pipeline properties are up to date - vtkSMProxy* proxy = pqSource->getProxy(); - proxy->UpdateVTKObjects(); - proxy->UpdatePropertyInformation(); - pqSource->updatePipeline(); - - // If we are dealing with a filter, we can cast it. If it is a source, - // then the cast should result in a NULL, an exception is the splatterplot filter which - // also contains size information - pqPipelineFilter* filter = qobject_cast(pqSource); - - if (QString(proxy->GetXMLName()).contains("SplatterPlot")) - { - minValue = vtkSMPropertyHelper(proxy,"MinValue").GetAsDouble(); + minValue = vtkSMPropertyHelper(proxy,"MinValue").GetAsDouble(); + maxValue = vtkSMPropertyHelper(proxy,"MaxValue").GetAsDouble(); - maxValue = vtkSMPropertyHelper(proxy,"MaxValue").GetAsDouble(); + return; + } - isFilter = false; - } - else if (!filter) - { - // Only MDEvent and MDHisto workspaces will provide us with min and max - const char* workspaceTypeName = vtkSMPropertyHelper(proxy,"WorkspaceTypeName").GetAsString(); - std::string workspaceType(workspaceTypeName); - size_t mdEvent = workspaceType.find("MDEventWorkspace"); - size_t mdHisto = workspaceType.find("MDHistoWorkspace"); + // Check if Peak Workspace. This workspace should not contribute to colorscale + if (QString(proxy->GetXMLName()).contains("Peaks Source")) + { + minValue = DBL_MAX; + maxValue = -DBL_MAX; - if (mdEvent != std::string::npos || mdHisto != std::string::npos) - { - minValue = vtkSMPropertyHelper(proxy,"MinValue").GetAsDouble(); + return; + } - maxValue = vtkSMPropertyHelper(proxy,"MaxValue").GetAsDouble(); - } - else - { - // Peak Source should not produce a color scale range - minValue = DBL_MAX; - maxValue = -DBL_MAX; - } + // Otherwise get the data range of the representation for the active view + pqPipelineRepresentation* pipelineRepresenation = qobject_cast(source->getRepresentation(pqActiveObjects::instance().activeView())); - isFilter = false; - } - else - { - // We expect one input, if not provide default values - if (filter->getInputCount() != 1) - { - minValue = this->defaultValue; - maxValue = this->defaultValue; + if (pipelineRepresenation) + { + QPair range = pipelineRepresenation->getColorFieldRange(); - isFilter = false; - } - else - { - QList outputPorts = filter->getAllInputs(); - pqSource = outputPorts[0]->getSource(); - } - } + minValue = range.first; + maxValue = range.second; } } diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp index 10a445ef2e9d..08a110a003a2 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp @@ -184,7 +184,7 @@ void SplatterPlotView::render() this->resetDisplay(); if (this->peaksSource.isEmpty()) { - this->setAutoColorScale(); + //this->setAutoColorScale(); } else { From 186f15c8467f9c42b6c48326b72fbf2d6175b423 Mon Sep 17 00:00:00 2001 From: Anton Piccardo-Selg Date: Thu, 11 Dec 2014 16:16:28 +0000 Subject: [PATCH 017/275] Refs #10627 Accounting for negative data in auto scaling --- .../ViewWidgets/src/AutoScaleRangeGenerator.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp index 3293a47f99dc..0d605bbf6f6f 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp @@ -122,6 +122,16 @@ namespace SimpleGui // Set the color scale output VsiColorScale vsiColorScale; + // Account for possible negative data. If min value is negative and max value is larger than 100, then set to default + // else set to three orders of magnitude smaller than the max value + if (minValue < 0 && maxValue > 100) + { + minValue = this->defaultValue; + } else if (minValue < 0 && maxValue < 100) + { + minValue = maxValue*0.001; + } + vsiColorScale.minValue = minValue; vsiColorScale.maxValue = minValue + 0.1*(maxValue - minValue); vsiColorScale.useLogScale = TRUE; From 6977c7fcbc9a6dc1681603373a3b36f2eb0d3fdd Mon Sep 17 00:00:00 2001 From: Anton Piccardo-Selg Date: Mon, 12 Jan 2015 13:43:58 +0000 Subject: [PATCH 018/275] Refs #10627 Fix log scale bug --- Code/Mantid/MantidQt/API/CMakeLists.txt | 4 ++ .../API/inc/MantidQtAPI/MdConstants.h | 54 +++++++++++++++ .../MantidQt/API/inc/MantidQtAPI/MdSettings.h | 68 +++++++++++++++++++ Code/Mantid/MantidQt/API/src/MdConstants.cpp | 18 +++++ Code/Mantid/MantidQt/API/src/MdSettings.cpp | 34 ++++++++++ .../AutoScaleRangeGenerator.h | 17 +++++ .../ColorUpdater.h | 3 +- .../ViewBase.h | 2 + .../src/AutoScaleRangeGenerator.cpp | 67 ++++++++++++++++-- .../ViewWidgets/src/ColorUpdater.cpp | 11 +++ .../ViewWidgets/src/MdViewerWidget.cpp | 13 ++++ .../ViewWidgets/src/ViewBase.cpp | 8 +++ 12 files changed, 291 insertions(+), 8 deletions(-) create mode 100644 Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdConstants.h create mode 100644 Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdSettings.h create mode 100644 Code/Mantid/MantidQt/API/src/MdConstants.cpp create mode 100644 Code/Mantid/MantidQt/API/src/MdSettings.cpp diff --git a/Code/Mantid/MantidQt/API/CMakeLists.txt b/Code/Mantid/MantidQt/API/CMakeLists.txt index 1e5024413323..d80d71a8bc12 100644 --- a/Code/Mantid/MantidQt/API/CMakeLists.txt +++ b/Code/Mantid/MantidQt/API/CMakeLists.txt @@ -16,6 +16,8 @@ set ( SRC_FILES src/MantidHelpInterface.cpp src/MantidQwtIMDWorkspaceData.cpp src/MantidWidget.cpp + src/MdConstants.cpp + src/MdSettings.cpp src/Message.cpp src/OptionsPropertyWidget.cpp src/PlotAxis.cpp @@ -80,6 +82,8 @@ set ( INC_FILES inc/MantidQtAPI/MantidColorMap.h inc/MantidQtAPI/MantidQwtIMDWorkspaceData.h inc/MantidQtAPI/MantidQwtWorkspaceData.h + inc/MantidQtAPI/MdConstants.h + inc/MantidQtAPI/MdSettings.h inc/MantidQtAPI/PropertyWidgetFactory.h inc/MantidQtAPI/QwtRasterDataMD.h inc/MantidQtAPI/QwtWorkspaceBinData.h diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdConstants.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdConstants.h new file mode 100644 index 000000000000..a1ca73d0387f --- /dev/null +++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdConstants.h @@ -0,0 +1,54 @@ +#ifndef MDCONSTANTS_H_ +#define MDCONSTANTS_H_ + +#include "DllOption.h" + +namespace MantidQt +{ + namespace API + { + /** + * + This class is a collection of constants and keys used for the VSI. + + @date 6/1/2015 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + + class EXPORT_OPT_MANTIDQT_API MdConstants + { + public: + + MdConstants(); + + ~MdConstants(); + + const double getColorScaleStandardMax() const; + + private: + + const double m_colorScaleStandardMax; + }; + } +} + +#endif diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdSettings.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdSettings.h new file mode 100644 index 000000000000..346fd3f3a69f --- /dev/null +++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdSettings.h @@ -0,0 +1,68 @@ +#ifndef MDSETTINGS_H_ +#define MDSETTINGS_H_ + +#include "DllOption.h" +#include "MantidQtAPI/MdConstants.h" +#include + +namespace MantidQt +{ + namespace API + { + /** + * + This class is for reading and persisting MD properties. + + @date 19/12/2014 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + + class EXPORT_OPT_MANTIDQT_API MdSettings + { + public: + + MdSettings(); + + ~MdSettings(); + + /** + * Sets if the color scale was log in the last session + * @param logScale The state of the log scale. + */ + void setLastSessionLogScale(bool logScale); + + /** + * Retrieves the state of the last session's log scale. + * @returns Was a log scale state? + */ + bool getLastSessionLogScale(); + + private: + MdConstants m_mdConstants; + + QString m_vsiGroup; + QString m_lblLastSessionLogScale; + }; + } +} + +#endif diff --git a/Code/Mantid/MantidQt/API/src/MdConstants.cpp b/Code/Mantid/MantidQt/API/src/MdConstants.cpp new file mode 100644 index 000000000000..fa4ea5446f5e --- /dev/null +++ b/Code/Mantid/MantidQt/API/src/MdConstants.cpp @@ -0,0 +1,18 @@ +#include "MantidQtAPI/MdConstants.h" + +namespace MantidQt +{ + namespace API + { + MdConstants::MdConstants() : m_colorScaleStandardMax(0.1) + { + }; + + MdConstants::~MdConstants(){}; + + const double MdConstants::getColorScaleStandardMax() const + { + return m_colorScaleStandardMax; + } + } +} diff --git a/Code/Mantid/MantidQt/API/src/MdSettings.cpp b/Code/Mantid/MantidQt/API/src/MdSettings.cpp new file mode 100644 index 000000000000..97c364171b53 --- /dev/null +++ b/Code/Mantid/MantidQt/API/src/MdSettings.cpp @@ -0,0 +1,34 @@ +#include "MantidQtAPI/MdSettings.h" +#include +#include + +using namespace MantidQt::API; + +MdSettings::MdSettings() : m_vsiGroup("Mantid/MdPlotting/Vsi"), + m_lblLastSessionLogScale("lastsessionlogscale") +{ + +}; + +MdSettings::~MdSettings(){}; + +void MdSettings::setLastSessionLogScale(bool logScale) +{ + QSettings settings; + + settings.beginGroup(m_vsiGroup); + settings.setValue(m_lblLastSessionLogScale, logScale); + settings.endGroup(); +} + +bool MdSettings::getLastSessionLogScale() +{ + QSettings settings; + + settings.beginGroup(m_vsiGroup); + bool logScale = settings.value(m_lblLastSessionLogScale, false).asBool(); + settings.endGroup(); + + return logScale; +} + diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h index 7e13e15895c7..ad5131edb625 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h @@ -29,6 +29,8 @@ */ #include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h" +#include "MantidQtAPI/MdConstants.h" +#include "MantidQtAPI/MdSettings.h" #include class pqPipelineSource; @@ -63,6 +65,12 @@ class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS AutoScaleRangeGenerator /// Enum for different modes typedef enum COLORSCALEMODE{STANDARD, TECHNIQUEDEPENDENT, OFFSET} COLORSCALEMODE; + /// Initialize the color scale + void initializeColorScale(); + + /// Update log scale setting + void updateLogScaleSetting(bool logScale); + private: /// Selected color scale mode. COLORSCALEMODE mode; @@ -79,6 +87,9 @@ class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS AutoScaleRangeGenerator /// Make sure that the color scale is valid. void sanityCheck(VsiColorScale& colorscale); + /// Gets the log scale setting for the mode + bool getLogScale(); + /** * Extract the min and max values of a source. If we are dealing with a filter which does not * have the information then look upstream for the information @@ -87,6 +98,12 @@ class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS AutoScaleRangeGenerator * @param maxValueBuffer A reference to a max value. */ void AutoScaleRangeGenerator::setMinBufferAndMaxBuffer(pqPipelineSource* source, double& minValue, double& maxValue); + + /// Md constants + MantidQt::API::MdConstants m_mdConstants; + + /// Md Settings + MantidQt::API::MdSettings m_mdSettings; }; } diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorUpdater.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorUpdater.h index 4c9d74f9e69f..2d9862c0e177 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorUpdater.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorUpdater.h @@ -79,7 +79,8 @@ class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS ColorUpdater double getMaximumRange(); /// Get the minimum color scaling range value. double getMinimumRange(); - + /// Initializes the color scale + void initializeColorScale(); /** * Set logarithmic color scaling on the data. * @param state flag to determine whether or not to use log color scaling diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h index 3e44d4cd43ed..30da56284755 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h @@ -115,6 +115,8 @@ class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS ViewBase : public QWidget virtual void setPluginSource(QString pluginName, QString wsName); /// Determines if source has timesteps (4D). virtual bool srcHasTimeSteps(pqPipelineSource *src); + /// Initializes the settings of the color scale + virtual void initializeColorScale(); /// Enumeration for Cartesian coordinates enum Direction {X, Y, Z}; diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp index 0d605bbf6f6f..1ecf32eefc33 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp @@ -1,5 +1,5 @@ #include "MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h" - +#include "MantidQtAPI/MdConstants.h" // Have to deal with ParaView warnings and Intel compiler the hard way. #if defined(__INTEL_COMPILER) #pragma warning disable 1170 @@ -18,6 +18,7 @@ #include #include +#include "MantidQtAPI/MdSettings.h" namespace Mantid { @@ -28,7 +29,39 @@ namespace SimpleGui /** * Note that the mode is currently set to standard. */ - AutoScaleRangeGenerator::AutoScaleRangeGenerator() : mode(STANDARD), defaultValue(1e-2) {}; + AutoScaleRangeGenerator::AutoScaleRangeGenerator() : mode(STANDARD), defaultValue(1e-2) + { + //Set the initial log scale state due to the mode + m_mdSettings.setLastSessionLogScale(getLogScale()); + }; + + /** + * Gets the log scale for the mode + * @returns The log scale state. + */ + bool AutoScaleRangeGenerator::getLogScale() + { + bool logScale = false; + + switch(mode) + { + case(STANDARD): + logScale = false; + break; + + case(TECHNIQUEDEPENDENT): + // Implement technique-dependence here + + case(OFFSET): + // Implement color scale which accounts for noise floor here. + + default: + logScale= false; + break; + } + + return logScale; + } /** * Get the auto color scale which depends on the mode setting. @@ -54,11 +87,15 @@ namespace SimpleGui default: colorScaleContainer.maxValue = 1.0; colorScaleContainer.minValue = 0.0; - colorScaleContainer.useLogScale= FALSE; + colorScaleContainer.useLogScale= false; break; } + // Set the colorScale Container + colorScaleContainer.useLogScale = m_mdSettings.getLastSessionLogScale(); + + // Make sure that the color scale is valid, and if not set default values. sanityCheck(colorScaleContainer); @@ -83,7 +120,7 @@ namespace SimpleGui double minValue = this->defaultValue; double minValueBuffer = this->defaultValue; - bool initialSetting = TRUE; + bool initialSetting = true; QList sources = getAllPVSources(); @@ -114,7 +151,7 @@ namespace SimpleGui minValue = minValueBuffer; } - initialSetting = FALSE; + initialSetting = false; } } } @@ -133,8 +170,7 @@ namespace SimpleGui } vsiColorScale.minValue = minValue; - vsiColorScale.maxValue = minValue + 0.1*(maxValue - minValue); - vsiColorScale.useLogScale = TRUE; + vsiColorScale.maxValue = minValue + (maxValue - minValue)*m_mdConstants.getColorScaleStandardMax(); return vsiColorScale; } @@ -233,6 +269,23 @@ namespace SimpleGui colorscale.maxValue = this->defaultValue; } } + + /** + * Initializes the color scale state, in particular if it is a log scale. + */ + void AutoScaleRangeGenerator::initializeColorScale() + { + m_mdSettings.setLastSessionLogScale(getLogScale()); + } + + /** + * Update the log scale setting + * @param logScale The log scale setting + */ + void AutoScaleRangeGenerator::updateLogScaleSetting(bool logScale) + { + m_mdSettings.setLastSessionLogScale(logScale); + } } } } \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp index 93d1dae03a45..c77f37e84667 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp @@ -59,6 +59,9 @@ VsiColorScale ColorUpdater::autoScale() // Set the color scale for all sources this->minScale = vsiColorScale.minValue; this->maxScale = vsiColorScale.maxValue; + + // If the view + this->logScaleState = vsiColorScale.useLogScale; // Update the lookup tables, i.e. react to a color scale change @@ -199,6 +202,7 @@ void ColorUpdater::updateState(ColorSelectionWidget *cs) this->logScaleState = cs->getLogScaleState(); this->minScale = cs->getMinRange(); this->maxScale = cs->getMaxRange(); + this->autoScaleRangeGenerator.updateLogScaleSetting(this->logScaleState); } /** @@ -245,6 +249,13 @@ void ColorUpdater::print() std::cout << "Max Range: " << this->maxScale << std::endl; } +/** + * Initializes the color scale + */ +void ColorUpdater::initializeColorScale() +{ + autoScaleRangeGenerator.initializeColorScale(); +} } } } diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp index 015fd3db00ca..02810a1ba846 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp @@ -489,6 +489,13 @@ void MdViewerWidget::renderingDone() */ void MdViewerWidget::renderWorkspace(QString workspaceName, int workspaceType, std::string instrumentName) { + // If there are no other sources, then set the required + if (this->currentView->getNumSources() == 0) + { + // Set the auto log scale state + this->currentView->initializeColorScale(); + } + QString sourcePlugin = ""; if (VatesViewerInterface::PEAKS == workspaceType) { @@ -759,6 +766,12 @@ void MdViewerWidget::checkForUpdates() { this->currentView->resetDisplay(); } + + // Make sure that the color scale is calculated + if (this->ui.colorSelectionWidget->getAutoScaleState()) + { + this->currentView->onAutoScale(this->ui.colorSelectionWidget); + } } /** diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp index e83eebd884f0..3b984b7d2a2a 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp @@ -704,6 +704,14 @@ void ViewBase::onVisibilityChanged(pqPipelineSource *source, pqDataRepresentatio } } +/** + * Initializes the settings of the color scale + */ +void ViewBase::initializeColorScale() +{ + colorUpdater.initializeColorScale(); +} + } // namespace SimpleGui } // namespace Vates } // namespace Mantid From fb30248c42f33052054692d2b5d9646a66e9a87a Mon Sep 17 00:00:00 2001 From: Anton Piccardo-Selg Date: Mon, 12 Jan 2015 14:07:59 +0000 Subject: [PATCH 019/275] Refs #10627 Fix the closing window bug --- .../Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp index 02810a1ba846..4306b4c23884 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp @@ -489,6 +489,11 @@ void MdViewerWidget::renderingDone() */ void MdViewerWidget::renderWorkspace(QString workspaceName, int workspaceType, std::string instrumentName) { + if (this->currentView->getNumSources() == 0) + { + this->ui.modeControlWidget->setToStandardView(); + } + // If there are no other sources, then set the required if (this->currentView->getNumSources() == 0) { @@ -843,7 +848,6 @@ bool MdViewerWidget::eventFilter(QObject *obj, QEvent *ev) pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder(); builder->destroySources(); - this->ui.modeControlWidget->setToStandardView(); return true; } } From 760c2e058ce4fc2f727ae93d0dcfc6035a080f13 Mon Sep 17 00:00:00 2001 From: Anton Piccardo-Selg Date: Wed, 14 Jan 2015 13:54:56 +0000 Subject: [PATCH 020/275] Refs #10627 Fix unit test empty data set in splatter plot --- Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp index b789e90a75e2..10fb09950d74 100644 --- a/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp @@ -541,7 +541,13 @@ namespace VATES // Set the instrument m_instrument = m_metaDataExtractor->extractInstrument(m_workspace); - double* range = dataSet->GetScalarRange(); + double* range = NULL; + + if (dataSet) + { + range = dataSet->GetScalarRange(); + } + if (range) { m_minValue = range[0]; From bb4d57df3ec166c880a07b0b97fb2971c183a9ab Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Fri, 16 Jan 2015 13:18:54 +0000 Subject: [PATCH 021/275] Fix rpm for Fedora >= 18 and RHEL >= 7 The rpm command is now more strict on these systems and requires the package not to own system directories Refs #10911 --- Code/Mantid/Build/CMake/LinuxPackageScripts.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Code/Mantid/Build/CMake/LinuxPackageScripts.cmake b/Code/Mantid/Build/CMake/LinuxPackageScripts.cmake index d3ddda676e5d..cf5728be28ba 100644 --- a/Code/Mantid/Build/CMake/LinuxPackageScripts.cmake +++ b/Code/Mantid/Build/CMake/LinuxPackageScripts.cmake @@ -22,6 +22,10 @@ endif() set ( CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/${LIB_DIR};${CMAKE_INSTALL_PREFIX}/${PLUGINS_DIR};${CMAKE_INSTALL_PREFIX}/${PVPLUGINS_DIR} ) +# Tell rpm that this package does not own /opt /usr/share/{applications,pixmaps} +# Required for Fedora >= 18 and RHEL >= 7 +set ( CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION /opt /usr/share/applications /usr/share/pixmaps ) + ########################################################################### # LD_PRELOAD libraries ########################################################################### From 00e3c71cdc1c7587b642e5c5e56d4d7240023927 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Fri, 16 Jan 2015 14:46:44 +0000 Subject: [PATCH 022/275] Re #10894 updating PlotAsymmetryByLogValue algorithm --- .../PlotAsymmetryByLogValue.h | 33 +- .../src/PlotAsymmetryByLogValue.cpp | 406 +++++++++++------- 2 files changed, 273 insertions(+), 166 deletions(-) diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/PlotAsymmetryByLogValue.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/PlotAsymmetryByLogValue.h index e1dd2d90a01b..26508de9191b 100644 --- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/PlotAsymmetryByLogValue.h +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/PlotAsymmetryByLogValue.h @@ -69,7 +69,6 @@ class DLLExport PlotAsymmetryByLogValue : public API::Algorithm { virtual const std::string summary() const { return "Calculates asymmetry for a series of log values"; } - /// Algorithm's version for identification overriding a virtual method virtual int version() const { return 1; } /// Algorithm's category for identification overriding a virtual method @@ -79,19 +78,24 @@ class DLLExport PlotAsymmetryByLogValue : public API::Algorithm { // Overridden Algorithm methods void init(); void exec(); - + // Parse run names + void parseRunNames (std::string& firstFN, std::string& lastFN, std::string& fnBase, std::string& fnExt); + // Load dead-time corrections from specified file + void loadCorrectionsFromFile (API::Workspace_sptr &customDeadTimes, std::string deadTimeFile ); + // Apply dead-time corrections + void applyDeadtimeCorr (API::Workspace_sptr &loadedWs, API::Workspace_sptr deadTimes); + /// Group detectors from run file + void groupDetectors (API::Workspace_sptr &loadedWs, API::Workspace_sptr loadedDetGrouping); /// Calculate the integral asymmetry for a workspace (single period) void calcIntAsymmetry(API::MatrixWorkspace_sptr ws, double &Y, double &E); - /// Calculate the integral asymmetry for a workspace (red & green) - void calcIntAsymmetry(API::MatrixWorkspace_sptr ws_red, - API::MatrixWorkspace_sptr ws_geen, double &Y, - double &E); + void calcIntAsymmetry(API::MatrixWorkspace_sptr ws_red, API::MatrixWorkspace_sptr ws_geen, double &Y, double &E); /// Group detectors - void groupDetectors(API::MatrixWorkspace_sptr &ws, - const std::vector &spectraList); + void groupDetectors (API::MatrixWorkspace_sptr &ws, const std::vector &spectraList); /// Get log value - double getLogValue(API::MatrixWorkspace &ws, const std::string &logName); + double getLogValue(API::MatrixWorkspace &ws); + /// Populate output workspace with results + void populateOutputWorkspace (API::MatrixWorkspace_sptr &outWS, int nplots); /// Stores property "Int" bool m_int; @@ -101,6 +105,17 @@ class DLLExport PlotAsymmetryByLogValue : public API::Algorithm { std::vector m_backward_list; /// If true call LoadMuonNexus with Autogroup on bool m_autogroup; + // Mantid vectors to store results + // Red mantid vectors + MantidVec m_redX, m_redY, m_redE; + // Green mantid vectors + MantidVec m_greenX, m_greenY, m_greenE; + // Mantid vectors to store Red + Green + MantidVec m_sumX, m_sumY, m_sumE; + // Mantid vectors to store Red - Green + MantidVec m_diffX, m_diffY, m_diffE; + // LogValue name + std::string m_logName; }; } // namespace Algorithm diff --git a/Code/Mantid/Framework/Algorithms/src/PlotAsymmetryByLogValue.cpp b/Code/Mantid/Framework/Algorithms/src/PlotAsymmetryByLogValue.cpp index c9dfec93a203..aac17d5f3771 100644 --- a/Code/Mantid/Framework/Algorithms/src/PlotAsymmetryByLogValue.cpp +++ b/Code/Mantid/Framework/Algorithms/src/PlotAsymmetryByLogValue.cpp @@ -15,6 +15,7 @@ #include "MantidAPI/AlgorithmManager.h" #include "MantidAlgorithms/PlotAsymmetryByLogValue.h" #include "MantidDataObjects/Workspace2D.h" +#include "MantidDataObjects/TableWorkspace.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/ListValidator.h" #include "MantidKernel/MandatoryValidator.h" @@ -130,232 +131,322 @@ void PlotAsymmetryByLogValue::init() { * Executes the algorithm */ void PlotAsymmetryByLogValue::exec() { + + // Get properties + // Get grouping property m_forward_list = getProperty("ForwardSpectra"); m_backward_list = getProperty("BackwardSpectra"); m_autogroup = (m_forward_list.size() == 0 && m_backward_list.size() == 0); - - std::string logName = getProperty("LogValue"); - + // Get log value + m_logName = getProperty("LogValue"); + // Get green and red periods int red = getProperty("Red"); int green = getProperty("Green"); - + // Get type of computation std::string stype = getProperty("Type"); m_int = stype == "Integral"; - + // Get type of dead-time corrections + const std::string dtcType = getPropertyValue("DeadTimeCorrType"); + // Get runs std::string firstFN = getProperty("FirstRun"); std::string lastFN = getProperty("LastRun"); - std::string ext = firstFN.substr(firstFN.find_last_of(".")); - - firstFN.erase(firstFN.size() - 4); - lastFN.erase(lastFN.size() - 4); - - std::string fnBase = firstFN; - size_t i = fnBase.size() - 1; - while (isdigit(fnBase[i])) - i--; - if (i == fnBase.size() - 1) { - g_log.error("File name must end with a number."); - throw Exception::FileError("File name must end with a number.", firstFN); - } - fnBase.erase(i + 1); - - firstFN.erase(0, fnBase.size()); - lastFN.erase(0, fnBase.size()); - + // Parse run names and get the number of runs + std::string fnBase, fnExt; + parseRunNames( firstFN, lastFN, fnBase, fnExt); size_t is = atoi(firstFN.c_str()); // starting run number size_t ie = atoi(lastFN.c_str()); // last run number int w = static_cast(firstFN.size()); - // The number of runs - size_t npoints = ie - is + 1; - - // Create the 2D workspace for the output - int nplots = green != EMPTY_INT() ? 4 : 1; - MatrixWorkspace_sptr outWS = WorkspaceFactory::Instance().create( - "Workspace2D", - nplots, // the number of plots - npoints, // the number of data points on a plot - npoints // it's not a histogram - ); - TextAxis *tAxis = new TextAxis(nplots); - if (nplots == 1) { - tAxis->setLabel(0, "Asymmetry"); - } else { - tAxis->setLabel(0, "Red-Green"); - tAxis->setLabel(1, "Red"); - tAxis->setLabel(2, "Green"); - tAxis->setLabel(3, "Red+Green"); - } - outWS->replaceAxis(1, tAxis); - - const std::string dtcType = getPropertyValue("DeadTimeCorrType"); + // Dead-time corrections: if user specifies a file, load corrections now Workspace_sptr customDeadTimes; - if (dtcType == "FromSpecifiedFile") { - IAlgorithm_sptr loadDeadTimes = createChildAlgorithm("LoadNexusProcessed"); - loadDeadTimes->initialize(); - loadDeadTimes->setPropertyValue("Filename", - getPropertyValue("DeadTimeCorrFile")); - loadDeadTimes->execute(); - - customDeadTimes = loadDeadTimes->getProperty("OutputWorkspace"); + loadCorrectionsFromFile (customDeadTimes, getPropertyValue("DeadTimeCorrFile")); } Progress progress(this, 0, 1, ie - is + 2); + + // Loop through runs for (size_t i = is; i <= ie; i++) { + + // Get complete run name std::ostringstream fn, fnn; fnn << std::setw(w) << std::setfill('0') << i; - fn << fnBase << fnn.str() << ext; + fn << fnBase << fnn.str() << fnExt; + // Load run IAlgorithm_sptr load = createChildAlgorithm("LoadMuonNexus"); - load->initialize(); load->setPropertyValue("Filename", fn.str()); load->execute(); - Workspace_sptr loadedWs = load->getProperty("OutputWorkspace"); + // Check if dead-time corrections have to be applied if (dtcType != "None") { - IAlgorithm_sptr applyCorr = - AlgorithmManager::Instance().create("ApplyDeadTimeCorr"); - applyCorr->setLogging(false); - applyCorr->setRethrows(true); - - ScopedWorkspace ws(loadedWs); - applyCorr->setPropertyValue("InputWorkspace", ws.name()); - applyCorr->setPropertyValue("OutputWorkspace", ws.name()); - - ScopedWorkspace deadTimes; - if (dtcType == "FromSpecifiedFile") { - deadTimes.set(customDeadTimes); + applyDeadtimeCorr (loadedWs, customDeadTimes); } else { - deadTimes.set(load->getProperty("DeadTimeTable")); + Workspace_sptr deadTimes = load->getProperty("DeadTimeTable"); + applyDeadtimeCorr (loadedWs, deadTimes); } - - applyCorr->setPropertyValue("DeadTimeTable", deadTimes.name()); - applyCorr->execute(); - - // Workspace should've been replaced in the ADS by ApplyDeadTimeCorr, so - // need to - // re-assign it - loadedWs = ws.retrieve(); } + // If m_autogroup, group detectors if (m_autogroup) { - Workspace_sptr loadedDetGrouping = - load->getProperty("DetectorGroupingTable"); - + Workspace_sptr loadedDetGrouping = load->getProperty("DetectorGroupingTable"); if (!loadedDetGrouping) throw std::runtime_error("No grouping info in the file.\n\nPlease " "specify grouping manually"); - - // Could be groups of workspaces, so need to work with ADS - ScopedWorkspace inWS(loadedWs); - ScopedWorkspace grouping(loadedDetGrouping); - ScopedWorkspace outWS; - - try { - IAlgorithm_sptr applyGrouping = - AlgorithmManager::Instance().create("MuonGroupDetectors"); - applyGrouping->setLogging(false); - applyGrouping->setRethrows(true); - - applyGrouping->setPropertyValue("InputWorkspace", inWS.name()); - applyGrouping->setPropertyValue("DetectorGroupingTable", - grouping.name()); - applyGrouping->setPropertyValue("OutputWorkspace", outWS.name()); - applyGrouping->execute(); - - loadedWs = outWS.retrieve(); - } catch (...) { - throw std::runtime_error( - "Unable to group detectors.\n\nPlease specify grouping manually."); - } + groupDetectors(loadedWs,loadedDetGrouping); } + // Check if workspace is a workspace group WorkspaceGroup_sptr loadedGroup = boost::dynamic_pointer_cast(loadedWs); + // If it is not, we only have 'red' data if (!loadedGroup) { Workspace2D_sptr loadedWs2D = boost::dynamic_pointer_cast(loadedWs); double Y, E; calcIntAsymmetry(loadedWs2D, Y, E); - outWS->dataY(0)[i - is] = Y; - outWS->dataX(0)[i - is] = getLogValue(*loadedWs2D, logName); - outWS->dataE(0)[i - is] = E; + m_redX.push_back(getLogValue(*loadedWs2D)); + m_redY.push_back(Y); + m_redE.push_back(E); + } else { + DataObjects::Workspace2D_sptr ws_red; DataObjects::Workspace2D_sptr ws_green; - - // Run through the periods of the loaded file and do calculations on the + // Run through the periods of the loaded file and save the // selected ones for (int mi = 0; mi < loadedGroup->getNumberOfEntries(); mi++) { + Workspace2D_sptr memberWs = boost::dynamic_pointer_cast(loadedGroup->getItem(mi)); - int period = mi + 1; - - // Do only one period - if (green == EMPTY_INT() && period == red) { + if ( period == red ){ ws_red = memberWs; - double Y, E; - calcIntAsymmetry(ws_red, Y, E); - outWS->dataY(0)[i - is] = Y; - outWS->dataX(0)[i - is] = getLogValue(*ws_red, logName); - outWS->dataE(0)[i - is] = E; - } else // red & green - { - if (period == red) - ws_red = memberWs; - if (period == green) + } + if ( green!= EMPTY_INT() ){ + if ( period == green ){ ws_green = memberWs; + } } } - // red & green claculation - if (green != EMPTY_INT()) { - if (!ws_red || !ws_green) - throw std::invalid_argument("Red or green period is out of range"); + // Check ws_red + if (!ws_red){ + throw std::invalid_argument("Red period is out of range"); + } + // Check ws_green + if ( (green!=EMPTY_INT()) && (!ws_green) ){ + throw std::invalid_argument("Green period is out of range"); + } + + if ( green==EMPTY_INT() ){ double Y, E; - double Y1, E1; - double logValue = getLogValue(*ws_red, logName); calcIntAsymmetry(ws_red, Y, E); - calcIntAsymmetry(ws_green, Y1, E1); - outWS->dataY(1)[i - is] = Y; - outWS->dataX(1)[i - is] = logValue; - outWS->dataE(1)[i - is] = E; - - outWS->dataY(2)[i - is] = Y1; - outWS->dataX(2)[i - is] = logValue; - outWS->dataE(2)[i - is] = E1; - - outWS->dataY(3)[i - is] = Y + Y1; - outWS->dataX(3)[i - is] = logValue; - outWS->dataE(3)[i - is] = sqrt(E * E + E1 * E1); - + m_redX.push_back(getLogValue(*ws_red)); + m_redY.push_back(Y); + m_redE.push_back(E); + + } else{ + + double YR, ER; + double YG, EG; + double logValue = getLogValue(*ws_red); + calcIntAsymmetry(ws_red, YR, ER); + calcIntAsymmetry(ws_green, YG, EG); + // Red data + m_redX.push_back(logValue); + m_redY.push_back(YR); + m_redE.push_back(ER); + // Green data + m_greenX.push_back(logValue); + m_greenY.push_back(YG); + m_greenE.push_back(EG); + // Sum + m_sumX.push_back(logValue); + m_sumY.push_back(YR+YG); + m_sumE.push_back(sqrt(ER * ER + EG * EG)); // move to last for safety since some grouping takes place in the // calcIntAsymmetry call below - calcIntAsymmetry(ws_red, ws_green, Y, E); - outWS->dataY(0)[i - is] = Y; - outWS->dataX(0)[i - is] = logValue; - outWS->dataE(0)[i - is] = E; - } else if (!ws_red) - throw std::invalid_argument("Red period is out of range"); - } + calcIntAsymmetry(ws_red, ws_green, YR, ER); + m_diffX.push_back(logValue); + m_diffY.push_back(YR); + m_diffE.push_back(ER); + } + } // else loadedGroup progress.report(); } - outWS->getAxis(0)->title() = logName; - outWS->setYUnitLabel("Asymmetry"); + // Create the 2D workspace for the output + int nplots = m_greenX.size() ? 4 : 1; + size_t npoints = ie - is + 1; + MatrixWorkspace_sptr outWS = WorkspaceFactory::Instance().create( + "Workspace2D", + nplots, // the number of plots + npoints, // the number of data points on a plot + npoints // it's not a histogram + ); + // Populate output workspace with data + populateOutputWorkspace(outWS,nplots); // Assign the result to the output workspace property setProperty("OutputWorkspace", outWS); } +/** Load dead-time corrections from specified file +* @param customDeadTimes :: [input/output] Output workspace to store corrections +* @param deadTimeFile :: [input] File to read corrections from +*/ +void PlotAsymmetryByLogValue::loadCorrectionsFromFile (Workspace_sptr &customDeadTimes, std::string deadTimeFile ) +{ + try{ + IAlgorithm_sptr loadDeadTimes = createChildAlgorithm("LoadNexusProcessed"); + loadDeadTimes->setPropertyValue("Filename", deadTimeFile); + loadDeadTimes->setProperty("OutputWorkspace", customDeadTimes); + loadDeadTimes->executeAsChildAlg(); + customDeadTimes = loadDeadTimes->getProperty("OutputWorkspace"); + } + catch (...){ + throw std::runtime_error("Unable to load corrections from specified file\n"); + } +} +/** Populate output workspace with results +* @param outWS :: [input/output] Output workspace to populate +* @param nplots :: [input] Number of histograms +*/ +void PlotAsymmetryByLogValue::populateOutputWorkspace (MatrixWorkspace_sptr &outWS, int nplots) +{ + TextAxis *tAxis = new TextAxis(nplots); + if (nplots == 1) { + tAxis->setLabel(0, "Asymmetry"); + outWS->dataX(0) = m_redX; + outWS->dataY(0) = m_redY; + outWS->dataE(0) = m_redE; + } else { + tAxis->setLabel(0, "Red-Green"); + tAxis->setLabel(1, "Red"); + tAxis->setLabel(2, "Green"); + tAxis->setLabel(3, "Red+Green"); + outWS->dataX(0) = m_diffX; + outWS->dataY(0) = m_diffY; + outWS->dataE(0) = m_diffE; + outWS->dataX(1) = m_redX; + outWS->dataY(1) = m_redY; + outWS->dataE(1) = m_redE; + outWS->dataX(2) = m_greenX; + outWS->dataY(2) = m_greenY; + outWS->dataE(2) = m_greenE; + outWS->dataX(3) = m_sumX; + outWS->dataY(3) = m_sumY; + outWS->dataE(3) = m_sumE; + } + outWS->replaceAxis(1, tAxis); + outWS->getAxis(0)->title() = m_logName; + outWS->setYUnitLabel("Asymmetry"); +} +/** Parse run names +* @param firstFN :: [input/output] First run's name +* @param lastFN :: [input/output] Last run's name +* @param fnBase :: [output] Runs base name +* @param fnExt :: [output] Runs extension +*/ +void PlotAsymmetryByLogValue::parseRunNames (std::string& firstFN, std::string& lastFN, std::string& fnBase, std::string& fnExt) +{ + + if ( firstFN.size() != lastFN.size() ) + { + throw std::runtime_error("First and last runs are not in the same directory\n"); + } + + fnExt = firstFN.substr(firstFN.find_last_of(".")); + + firstFN.erase(firstFN.size() - 4); + lastFN.erase(lastFN.size() - 4); + + fnBase = firstFN; + size_t i = fnBase.size() - 1; + while (isdigit(fnBase[i])) + i--; + if (i == fnBase.size() - 1) { + throw Exception::FileError("File name must end with a number.", firstFN); + } + fnBase.erase(i + 1); + + std::string fnBase2 = lastFN; + fnBase2.erase(i + 1); + if ( fnBase != fnBase2 ) + { + throw std::runtime_error("First and last runs are not in the same directory\n"); + } + + firstFN.erase(0, fnBase.size()); + lastFN.erase(0, fnBase.size()); +} + +/** Apply dead-time corrections. The calculation is done by ApplyDeadTimeCorr algorithm +* @param loadedWs :: [input/output] Workspace to apply corrections to +* @param deadTimes :: [input] Corrections to apply +*/ +void PlotAsymmetryByLogValue::applyDeadtimeCorr (Workspace_sptr &loadedWs, Workspace_sptr deadTimes) +{ + ScopedWorkspace ws(loadedWs); + ScopedWorkspace dt(deadTimes); + + try + { + IAlgorithm_sptr applyCorr = AlgorithmManager::Instance().create("ApplyDeadTimeCorr"); + applyCorr->setLogging(false); + applyCorr->setRethrows(true); + applyCorr->setPropertyValue("InputWorkspace", ws.name()); + applyCorr->setPropertyValue("OutputWorkspace", ws.name()); + applyCorr->setProperty("DeadTimeTable", dt.name()); + applyCorr->execute(); + // Workspace should've been replaced in the ADS by ApplyDeadTimeCorr, so + // need to + // re-assign it + loadedWs = ws.retrieve(); + } + catch (...) + { + throw std::runtime_error("Unable to apply corrections\n"); + } +} + +/** Group detectors from specified file +* @param loadedWs :: [input/output] Workspace to apply grouping to +* @param loadedDetGrouping :: [input] Workspace storing detectors grouping +*/ +void PlotAsymmetryByLogValue::groupDetectors (Workspace_sptr &loadedWs, Workspace_sptr loadedDetGrouping) +{ + + // Could be groups of workspaces, so need to work with ADS + ScopedWorkspace inWS(loadedWs); + ScopedWorkspace grouping(loadedDetGrouping); + ScopedWorkspace outWS; + + try + { + IAlgorithm_sptr applyGrouping = AlgorithmManager::Instance().create("MuonGroupDetectors"); + applyGrouping->setLogging(false); + applyGrouping->setRethrows(true); + + applyGrouping->setPropertyValue("InputWorkspace", inWS.name()); + applyGrouping->setPropertyValue("DetectorGroupingTable", grouping.name()); + applyGrouping->setPropertyValue("OutputWorkspace", outWS.name()); + applyGrouping->execute(); + + loadedWs = outWS.retrieve(); + } + catch (...) + { + throw std::runtime_error("Unable to group detectors.\n\nPlease specify grouping manually."); + } +} /** Calculate the integral asymmetry for a workspace. * The calculation is done by MuonAsymmetryCalc and SimpleIntegration * algorithms. @@ -539,16 +630,14 @@ PlotAsymmetryByLogValue::groupDetectors(API::MatrixWorkspace_sptr &ws, * Get log value from a workspace. Convert to double if possible. * * @param ws :: The input workspace. - * @param logName :: Name of the log file. * @return :: Log value. * @throw :: std::invalid_argument if the log cannot be converted to a double or *doesn't exist. */ -double PlotAsymmetryByLogValue::getLogValue(MatrixWorkspace &ws, - const std::string &logName) { - auto *property = ws.run().getLogData(logName); +double PlotAsymmetryByLogValue::getLogValue(MatrixWorkspace &ws) { + auto *property = ws.run().getLogData(m_logName); if (!property) { - throw std::invalid_argument("Log " + logName + " does not exist."); + throw std::invalid_argument("Log " + m_logName + " does not exist."); } double value = 0; @@ -582,8 +671,11 @@ double PlotAsymmetryByLogValue::getLogValue(MatrixWorkspace &ws, } } - throw std::invalid_argument("Log " + logName + + throw std::invalid_argument("Log " + m_logName + " cannot be converted to a double type."); } + + + } // namespace Algorithm } // namespace Mantid From d8a5f963b27dd4b34d33e806ca2137507ee5de84 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Fri, 23 Jan 2015 09:24:36 +0000 Subject: [PATCH 023/275] Re #10894 Fixing build plot asymmetry by log value --- .../Mantid/Framework/Algorithms/src/PlotAsymmetryByLogValue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Mantid/Framework/Algorithms/src/PlotAsymmetryByLogValue.cpp b/Code/Mantid/Framework/Algorithms/src/PlotAsymmetryByLogValue.cpp index aac17d5f3771..20afdb2e61f9 100644 --- a/Code/Mantid/Framework/Algorithms/src/PlotAsymmetryByLogValue.cpp +++ b/Code/Mantid/Framework/Algorithms/src/PlotAsymmetryByLogValue.cpp @@ -138,7 +138,7 @@ void PlotAsymmetryByLogValue::exec() { m_backward_list = getProperty("BackwardSpectra"); m_autogroup = (m_forward_list.size() == 0 && m_backward_list.size() == 0); // Get log value - m_logName = getProperty("LogValue"); + m_logName = getPropertyValue("LogValue"); // Get green and red periods int red = getProperty("Red"); int green = getProperty("Green"); From 8e882012c27914e0fd4a5942a1d43ae1961a9582 Mon Sep 17 00:00:00 2001 From: Anton Piccardo-Selg Date: Mon, 26 Jan 2015 12:55:54 +0000 Subject: [PATCH 024/275] Refs #10627 Fix for qwt on linux and others --- Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdConstants.h | 4 ++-- Code/Mantid/MantidQt/API/src/MdConstants.cpp | 2 +- Code/Mantid/Vates/VatesAPI/CMakeLists.txt | 2 ++ .../VatesAPI/inc/MantidVatesAPI/MetaDataExtractorUtils.h | 2 +- .../Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp | 2 +- .../Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp | 2 +- Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp | 2 +- Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp | 2 +- Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp | 2 +- .../ViewWidgets/src/AutoScaleRangeGenerator.cpp | 1 + 10 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdConstants.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdConstants.h index a1ca73d0387f..cd8b5d46a29e 100644 --- a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdConstants.h +++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdConstants.h @@ -42,11 +42,11 @@ namespace MantidQt ~MdConstants(); - const double getColorScaleStandardMax() const; + double getColorScaleStandardMax(); private: - const double m_colorScaleStandardMax; + double m_colorScaleStandardMax; }; } } diff --git a/Code/Mantid/MantidQt/API/src/MdConstants.cpp b/Code/Mantid/MantidQt/API/src/MdConstants.cpp index fa4ea5446f5e..11073af78c83 100644 --- a/Code/Mantid/MantidQt/API/src/MdConstants.cpp +++ b/Code/Mantid/MantidQt/API/src/MdConstants.cpp @@ -10,7 +10,7 @@ namespace MantidQt MdConstants::~MdConstants(){}; - const double MdConstants::getColorScaleStandardMax() const + double MdConstants::getColorScaleStandardMax() { return m_colorScaleStandardMax; } diff --git a/Code/Mantid/Vates/VatesAPI/CMakeLists.txt b/Code/Mantid/Vates/VatesAPI/CMakeLists.txt index 630971b8a1a0..72465397a248 100644 --- a/Code/Mantid/Vates/VatesAPI/CMakeLists.txt +++ b/Code/Mantid/Vates/VatesAPI/CMakeLists.txt @@ -168,6 +168,7 @@ test/vtkDataSetToNonOrthogonalDataSetTest.h ) include_directories( inc ) +include_directories ( SYSTEM ${QWT_INCLUDE_DIR} ) set( SRC_UNITY_IGNORE_FILES ) if( UNITY_BUILD ) @@ -192,6 +193,7 @@ ${MANTID_SUBPROJECT_LIBS} vtkCommonCore vtkCommonDataModel vtkIOLegacy +${QWT_LIBRARIES} ) # Create test file projects diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetaDataExtractorUtils.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetaDataExtractorUtils.h index da624794e995..adba2cb342d0 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetaDataExtractorUtils.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetaDataExtractorUtils.h @@ -3,7 +3,7 @@ #include "MantidAPI/IMDWorkspace.h" #include "MantidAPI/IMDIterator.h" -#include "qwt/qwt_double_interval.h" +#include #include diff --git a/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp index 24f19ce4c898..97796ff8e705 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp @@ -4,7 +4,7 @@ #include "MantidVatesAPI/vtkDataSetFactory.h" #include "MantidVatesAPI/WorkspaceProvider.h" #include "MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h" -#include "qwt/qwt_double_interval.h" +#include #include namespace Mantid diff --git a/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp index c4c138c5b2d0..82023d01a586 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp @@ -5,7 +5,7 @@ #include "MantidVatesAPI/vtkDataSetFactory.h" #include "MantidVatesAPI/WorkspaceProvider.h" #include "MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h" -#include "qwt/qwt_double_interval.h" +#include #include namespace Mantid diff --git a/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp index 7877f1c570f5..0c0b78f3369c 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp @@ -5,7 +5,7 @@ #include "MantidGeometry/MDGeometry/MDHistoDimension.h" #include "MantidGeometry/MDGeometry/NullImplicitFunction.h" #include "MantidVatesAPI/RebinningKnowledgeSerializer.h" -#include "MantidVatesAPI/MetadataExtractorUtils.h" +#include "MantidVatesAPI/MetaDataExtractorUtils.h" #include "MantidVatesAPI/MetadataJsonManager.h" #include "MantidVatesAPI/MetadataToFieldData.h" #include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" diff --git a/Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp b/Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp index 59bf8ab51e82..5c9d5ea64442 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp @@ -1,5 +1,5 @@ #include "MantidVatesAPI/MetaDataExtractorUtils.h" -#include "qwt/qwt_double_interval.h" +#include #include "MantidAPI/IMDIterator.h" #include "MantidAPI/IMDEventWorkspace.h" #include "MantidAPI/IMDHistoWorkspace.h" diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp index 10fb09950d74..91606a695251 100644 --- a/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp @@ -21,7 +21,7 @@ #include #include -#include "qwt/qwt_double_interval.h" +#include using namespace Mantid::API; using namespace Mantid::MDEvents; diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp index 1ecf32eefc33..0f2a3f94b63d 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include "MantidQtAPI/MdSettings.h" From 73716f932fab77e99f259e9c0b83ad230da479b8 Mon Sep 17 00:00:00 2001 From: Anton Piccardo-Selg Date: Mon, 26 Jan 2015 13:38:16 +0000 Subject: [PATCH 025/275] Refs #10627 Fix qwt dependency for plugins --- .../ParaViewFilters/SplatterPlot/CMakeLists.txt | 4 +++- .../ParaViewReaders/EventNexusReader/CMakeLists.txt | 4 +++- .../ParaViewReaders/MDEWNexusReader/CMakeLists.txt | 4 +++- .../ParaViewReaders/MDHWNexusReader/CMakeLists.txt | 4 +++- .../ParaViewReaders/SQWEventReader/CMakeLists.txt | 4 +++- .../ParaviewPlugins/ParaViewSources/MDEWSource/CMakeLists.txt | 4 ++-- .../ParaviewPlugins/ParaViewSources/MDHWSource/CMakeLists.txt | 4 +++- .../MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h | 2 +- 8 files changed, 21 insertions(+), 9 deletions(-) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/CMakeLists.txt index b9bc569be5fd..d6beddcd88c7 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/CMakeLists.txt @@ -9,8 +9,10 @@ ADD_PARAVIEW_PLUGIN(MantidParaViewSplatterPlotSMPlugin "1.0" # Add to the 'VatesParaViewPlugins' group in VS set_property( TARGET MantidParaViewSplatterPlotSMPlugin PROPERTY FOLDER "MantidVatesParaViewPlugins" ) +include_directories ( SYSTEM ${QWT_INCLUDE_DIR} ) + target_link_libraries( MantidParaViewSplatterPlotSMPlugin -${MANTID_SUBPROJECT_LIBS} ) +${MANTID_SUBPROJECT_LIBS} ${QWT_LIBRARIES}) # Put library into subfolder. SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewSplatterPlotSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR}) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/EventNexusReader/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/EventNexusReader/CMakeLists.txt index 2e8997936002..798b29582c9b 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/EventNexusReader/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/EventNexusReader/CMakeLists.txt @@ -9,8 +9,10 @@ add_paraview_plugin( MantidParaViewEventNexusReaderSMPlugin "1.0" # Add to the 'VatesParaViewPlugins' group in VS set_property( TARGET MantidParaViewEventNexusReaderSMPlugin PROPERTY FOLDER "MantidVatesParaViewPlugins" ) +include_directories ( SYSTEM ${QWT_INCLUDE_DIR} ) + target_link_libraries( MantidParaViewEventNexusReaderSMPlugin -${MANTID_SUBPROJECT_LIBS} ) +${MANTID_SUBPROJECT_LIBS} ${QWT_LIBRARIES}) # Put library into subfolder. SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewEventNexusReaderSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR}) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/CMakeLists.txt index 1b2992046007..aa1f3a57ed9c 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/CMakeLists.txt @@ -9,8 +9,10 @@ add_paraview_plugin( MantidParaViewMDEWNexusReaderSMPlugin "1.0" # Add to the 'VatesParaViewPlugins' group in VS set_property( TARGET MantidParaViewMDEWNexusReaderSMPlugin PROPERTY FOLDER "MantidVatesParaViewPlugins" ) +include_directories ( SYSTEM ${QWT_INCLUDE_DIR} ) + target_link_libraries( MantidParaViewMDEWNexusReaderSMPlugin -${MANTID_SUBPROJECT_LIBS} ) +${MANTID_SUBPROJECT_LIBS} ${QWT_LIBRARIES}) # Put library into subfolder. SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewMDEWNexusReaderSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR}) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDHWNexusReader/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDHWNexusReader/CMakeLists.txt index be097d44301b..6ad4b9ff3c82 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDHWNexusReader/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/MDHWNexusReader/CMakeLists.txt @@ -9,8 +9,10 @@ add_paraview_plugin( MantidParaViewMDHWNexusReaderSMPlugin "1.0" # Add to the 'VatesParaViewPlugins' group in VS set_property( TARGET MantidParaViewMDHWNexusReaderSMPlugin PROPERTY FOLDER "MantidVatesParaViewPlugins" ) +include_directories ( SYSTEM ${QWT_INCLUDE_DIR} ) + target_link_libraries( MantidParaViewMDHWNexusReaderSMPlugin -${MANTID_SUBPROJECT_LIBS} ) +${MANTID_SUBPROJECT_LIBS} ${QWT_LIBRARIES}) # Put library into subfolder. SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewMDHWNexusReaderSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR}) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWEventReader/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWEventReader/CMakeLists.txt index 5488738dd751..eace77b7a09b 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWEventReader/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewReaders/SQWEventReader/CMakeLists.txt @@ -9,8 +9,10 @@ add_paraview_plugin( MantidParaViewSQWEventReaderSMPlugin "1.0" # Add to the 'VatesParaViewPlugins' group in VS set_property( TARGET MantidParaViewSQWEventReaderSMPlugin PROPERTY FOLDER "MantidVatesParaViewPlugins" ) +include_directories ( SYSTEM ${QWT_INCLUDE_DIR} ) + target_link_libraries( MantidParaViewSQWEventReaderSMPlugin -${MANTID_SUBPROJECT_LIBS} ) +${MANTID_SUBPROJECT_LIBS} ${QWT_LIBRARIES}) # Put library into subfolder. SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewSQWEventReaderSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR}) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/CMakeLists.txt index 76ae941b98c5..1719a68e0bd6 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/CMakeLists.txt @@ -6,9 +6,9 @@ ADD_PARAVIEW_PLUGIN(MantidParaViewMDEWSourceSMPlugin "1.0" # Add to the 'VatesParaViewPlugins' group in VS set_property( TARGET MantidParaViewMDEWSourceSMPlugin PROPERTY FOLDER "MantidVatesParaViewPlugins" ) - +include_directories ( SYSTEM ${QWT_INCLUDE_DIR} ) target_link_libraries( MantidParaViewMDEWSourceSMPlugin -${MANTID_SUBPROJECT_LIBS} ) +${MANTID_SUBPROJECT_LIBS} ${QWT_LIBRARIES}) # Put library into subfolder. SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewMDEWSourceSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR}) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/CMakeLists.txt index 56c3fb458c57..d65a9066e679 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/CMakeLists.txt @@ -7,8 +7,10 @@ ADD_PARAVIEW_PLUGIN(MantidParaViewMDHWSourceSMPlugin "1.0" # Add to the 'VatesParaViewPlugins' group in VS set_property( TARGET MantidParaViewMDHWSourceSMPlugin PROPERTY FOLDER "MantidVatesParaViewPlugins" ) +include_directories ( SYSTEM ${QWT_INCLUDE_DIR} ) + target_link_libraries( MantidParaViewMDHWSourceSMPlugin -${MANTID_SUBPROJECT_LIBS} ) +${MANTID_SUBPROJECT_LIBS} ${QWT_LIBRARIES}) # Put library into subfolder. SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewMDHWSourceSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR}) diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h index ad5131edb625..40dcdc12b1dd 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h @@ -97,7 +97,7 @@ class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS AutoScaleRangeGenerator * @param minValueBuffer A reference to a min value. * @param maxValueBuffer A reference to a max value. */ - void AutoScaleRangeGenerator::setMinBufferAndMaxBuffer(pqPipelineSource* source, double& minValue, double& maxValue); + void setMinBufferAndMaxBuffer(pqPipelineSource* source, double& minValue, double& maxValue); /// Md constants MantidQt::API::MdConstants m_mdConstants; From 10c42df988065253cb263327c20b622fdb4b1bf0 Mon Sep 17 00:00:00 2001 From: Anton Piccardo-Selg Date: Mon, 26 Jan 2015 13:43:14 +0000 Subject: [PATCH 026/275] Refs #10627 Fix error in Viewbase header --- .../ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h index 30da56284755..de6f6b03d573 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h @@ -200,7 +200,7 @@ public slots: /** * Set the color scale for auto color scaling. */ - void ViewBase::setAutoColorScale(); + void setAutoColorScale(); private: Q_DISABLE_COPY(ViewBase) From 7ddd451d95160422c27f7d3fcb7ede25e6b0188d Mon Sep 17 00:00:00 2001 From: Anton Piccardo-Selg Date: Mon, 26 Jan 2015 13:57:21 +0000 Subject: [PATCH 027/275] Refs #10627 Fix test for metadata extractor utils --- Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h b/Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h index 0d7a517d46c1..5dca8ba541b6 100644 --- a/Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h @@ -8,7 +8,7 @@ #include #include "MockObjects.h" -#include "qwt/qwt_double_interval.h" +#include #include "MantidTestHelpers/MDEventsTestHelper.h" #include "MantidAPI/FileFinder.h" #include "boost/pointer_cast.hpp" From 708e892b877e40ce9ca2e48ca9b4ba6959ced3f6 Mon Sep 17 00:00:00 2001 From: Anton Piccardo-Selg Date: Mon, 26 Jan 2015 14:58:40 +0000 Subject: [PATCH 028/275] Refs #10627 Fixing warnings --- .../VatesAPI/inc/MantidVatesAPI/MDEWLoadingPresenter.h | 8 ++++---- .../VatesAPI/inc/MantidVatesAPI/MDEWRebinningPresenter.h | 4 ++-- .../VatesAPI/inc/MantidVatesAPI/MDHWLoadingPresenter.h | 9 +++++---- .../VatesAPI/inc/MantidVatesAPI/MetadataJsonManager.h | 2 +- Code/Mantid/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp | 2 +- Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp | 2 +- .../Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp | 1 + Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp | 6 +++--- Code/Mantid/Vates/VatesAPI/src/VatesConfigurations.cpp | 2 +- .../Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h | 2 +- .../Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h | 9 ++++++++- .../VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp | 2 -- .../Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp | 2 +- 13 files changed, 29 insertions(+), 22 deletions(-) diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWLoadingPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWLoadingPresenter.h index e5cc9cb0066f..7f85639f622b 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWLoadingPresenter.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWLoadingPresenter.h @@ -64,10 +64,6 @@ namespace Mantid MDLoadingView* m_view; Mantid::Geometry::MDGeometryBuilderXML xmlBuilder; - boost::scoped_ptr m_metadataJsonManager; - boost::scoped_ptr m_metaDataExtractor; - boost::scoped_ptr m_vatesConfigurations; - Mantid::Geometry::IMDDimension_sptr tDimension; std::vector axisLabels; @@ -80,6 +76,10 @@ namespace Mantid size_t m_recursionDepth; bool m_loadInMemory; bool m_firstLoad; + + boost::scoped_ptr m_metadataJsonManager; + boost::scoped_ptr m_metaDataExtractor; + boost::scoped_ptr m_vatesConfigurations; }; } } diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWRebinningPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWRebinningPresenter.h index f3b4c352c201..159b93f49c5c 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWRebinningPresenter.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWRebinningPresenter.h @@ -129,12 +129,12 @@ namespace Mantid bool m_bOutputHistogramWS; /// Tag for the rebinned workspace static const std::string rb_tag; + /// Store for the instrument + mutable std::string m_instrument; /// Pointer to the manager for json metadata boost::scoped_ptr m_metadataJsonManager; /// Pointer to the vates configuration object boost::scoped_ptr m_vatesConfigurations; - /// Store for the instrument - mutable std::string m_instrument; }; } } diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWLoadingPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWLoadingPresenter.h index 52869be877a6..0655de7db511 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWLoadingPresenter.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDHWLoadingPresenter.h @@ -66,10 +66,6 @@ namespace Mantid Mantid::Geometry::MDGeometryBuilderXML xmlBuilder; - boost::scoped_ptr m_metadataJsonManager; - boost::scoped_ptr m_metaDataExtractor; - boost::scoped_ptr m_vatesConfigurations; - Mantid::Geometry::IMDDimension_sptr tDimension; std::vector axisLabels; virtual void appendMetadata(vtkDataSet* visualDataSet, @@ -82,6 +78,11 @@ namespace Mantid double m_time; bool m_loadInMemory; bool m_firstLoad; + + boost::scoped_ptr m_metadataJsonManager; + boost::scoped_ptr m_metaDataExtractor; + boost::scoped_ptr m_vatesConfigurations; + }; } } diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetadataJsonManager.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetadataJsonManager.h index fe03a51c5dd5..f29bc938eb9c 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetadataJsonManager.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetadataJsonManager.h @@ -1,7 +1,7 @@ #ifndef METADATA_JSON_MANAGER_H #define METADATA_JSON_MANAGER_H -#include "jsoncpp/json/json.h" +#include #include "MantidKernel/System.h" #include namespace Mantid diff --git a/Code/Mantid/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp index d8fc623cab0b..c104b6ffbf12 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp @@ -28,8 +28,8 @@ namespace Mantid m_recursionDepth(0), m_loadInMemory(false), m_firstLoad(true), - m_metaDataExtractor(new MetaDataExtractorUtils()), m_metadataJsonManager(new MetadataJsonManager()), + m_metaDataExtractor(new MetaDataExtractorUtils()), m_vatesConfigurations(new VatesConfigurations()) { Mantid::API::FrameworkManager::Instance(); diff --git a/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp index 0c0b78f3369c..7087e9bc783d 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp @@ -30,8 +30,8 @@ namespace Mantid m_time(-1), m_loadInMemory(false), m_firstLoad(true), - m_metaDataExtractor(new MetaDataExtractorUtils()), m_metadataJsonManager(new MetadataJsonManager()), + m_metaDataExtractor(new MetaDataExtractorUtils()), m_vatesConfigurations(new VatesConfigurations()) { Mantid::API::FrameworkManager::Instance(); diff --git a/Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp b/Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp index 5c9d5ea64442..75b2df724983 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp @@ -7,6 +7,7 @@ #include "MantidAPI/IMDWorkspace.h" #include "MantidKernel/Logger.h" #include "boost/pointer_cast.hpp" +#include namespace Mantid { diff --git a/Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp b/Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp index 3936f1593467..6567be7f263f 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp @@ -1,7 +1,7 @@ #include "MantidVatesAPI/MetadataJsonManager.h" -#include "jsoncpp/json/json.h" -#include "jsoncpp/json/writer.h" -#include "jsoncpp/json/reader.h" +#include +#include +#include namespace Mantid { diff --git a/Code/Mantid/Vates/VatesAPI/src/VatesConfigurations.cpp b/Code/Mantid/Vates/VatesAPI/src/VatesConfigurations.cpp index 9ae3f8e1a9c7..bf4523816f37 100644 --- a/Code/Mantid/Vates/VatesAPI/src/VatesConfigurations.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/VatesConfigurations.cpp @@ -31,7 +31,7 @@ namespace Mantid */ - VatesConfigurations::VatesConfigurations() :metaDataId("VATES_Metadata_Json"), maxRecursionDepth(10000) + VatesConfigurations::VatesConfigurations() : maxRecursionDepth(10000),metaDataId("VATES_Metadata_Json") { } diff --git a/Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h b/Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h index 5dca8ba541b6..9c59c553c1ff 100644 --- a/Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h @@ -40,7 +40,7 @@ class MetaDataExtractorUtilsTest : public CxxTest::TestSuite void testShouldExtractMinAndMaxFromWorkspaceForMDHisto() { // Arrange - double maxValue = 1.3; + coord_t maxValue = 1.3; Mantid::MDEvents::MDHistoWorkspace_sptr histoWorkspace = makeFakeMDHistoWorkspace(1.0, 4, 5, maxValue, 0.1,"MD_HISTO_WS"); // Act diff --git a/Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h b/Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h index 178af51ed1ba..7aa5460c4d49 100644 --- a/Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h @@ -1,10 +1,17 @@ #ifndef METADATA_JSON_MANAGER_TEST #define METADATA_JSON_MANAGER_TEST +#ifdef _WIN32 +// Disabling Json warnings regarding non-export of Json::Reader and Json::Writer +#pragma warning(disable : 4275) +#endif + + #include #include "MantidVatesAPI/MetadataJsonManager.h" #include -#include "jsoncpp/json/reader.h" +#include + using Mantid::VATES::MetadataJsonManager; diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp index 4306b4c23884..e0cb2a036ab4 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp @@ -1135,8 +1135,6 @@ void MdViewerWidget::setVisibilityListener() QList sources; sources = smModel->findItems(server); - pqView* activeView = pqActiveObjects::instance().activeView(); - // Attach the visibilityChanged signal for all sources. for (QList::iterator source = sources.begin(); source != sources.end(); ++source) { diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp index 3b984b7d2a2a..53dd071a51b7 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp @@ -695,7 +695,7 @@ bool ViewBase::hasWorkspaceType(const QString &wsTypeName) * @param source The pipeleine source assoicated with the call. * @param representation The representation associatied with the call */ -void ViewBase::onVisibilityChanged(pqPipelineSource *source, pqDataRepresentation *representation) +void ViewBase::onVisibilityChanged(pqPipelineSource*, pqDataRepresentation*) { // Reset the colorscale if it is set to autoscale if (colorUpdater.isAutoScale()) From 128df8fcc9cd981c4181b3d144228505eef44060 Mon Sep 17 00:00:00 2001 From: Anton Piccardo-Selg Date: Mon, 26 Jan 2015 15:29:39 +0000 Subject: [PATCH 029/275] Refs #10627 Fixing Json header files --- Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h | 3 +-- Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h b/Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h index 9c59c553c1ff..82fb1eedd73e 100644 --- a/Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h @@ -40,8 +40,7 @@ class MetaDataExtractorUtilsTest : public CxxTest::TestSuite void testShouldExtractMinAndMaxFromWorkspaceForMDHisto() { // Arrange - coord_t maxValue = 1.3; - Mantid::MDEvents::MDHistoWorkspace_sptr histoWorkspace = makeFakeMDHistoWorkspace(1.0, 4, 5, maxValue, 0.1,"MD_HISTO_WS"); + Mantid::MDEvents::MDHistoWorkspace_sptr histoWorkspace = makeFakeMDHistoWorkspace(1.0, 4, 5, 1.3, 0.1,"MD_HISTO_WS"); // Act MetaDataExtractorUtils extractor; diff --git a/Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h b/Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h index 7aa5460c4d49..e021b3bdce65 100644 --- a/Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h @@ -3,7 +3,7 @@ #ifdef _WIN32 // Disabling Json warnings regarding non-export of Json::Reader and Json::Writer -#pragma warning(disable : 4275) +#pragma warning(disable : 4251) #endif From 63c3428675694617bc81c33c6741b1591142a065 Mon Sep 17 00:00:00 2001 From: Anton Piccardo-Selg Date: Mon, 26 Jan 2015 16:33:27 +0000 Subject: [PATCH 030/275] Refs #10627 Potential fix for makeFakeMDHistoWorkspace --- Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h b/Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h index 82fb1eedd73e..29c3278be94a 100644 --- a/Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h @@ -40,7 +40,7 @@ class MetaDataExtractorUtilsTest : public CxxTest::TestSuite void testShouldExtractMinAndMaxFromWorkspaceForMDHisto() { // Arrange - Mantid::MDEvents::MDHistoWorkspace_sptr histoWorkspace = makeFakeMDHistoWorkspace(1.0, 4, 5, 1.3, 0.1,"MD_HISTO_WS"); + Mantid::MDEvents::MDHistoWorkspace_sptr histoWorkspace = makeFakeMDHistoWorkspace(1.0, 4); // Act MetaDataExtractorUtils extractor; From 49d396acafd46b76dde83a4c026da7abaf57d843 Mon Sep 17 00:00:00 2001 From: Anton Piccardo-Selg Date: Tue, 27 Jan 2015 08:10:20 +0000 Subject: [PATCH 031/275] Refs #10627 Fix the doxygen warnings --- .../VatesAPI/src/MDEWRebinningPresenter.cpp | 4 +- .../Vates/VatesAPI/src/MDLoadingPresenter.cpp | 164 ------------------ .../VatesAPI/src/MetaDataExtractorUtils.cpp | 6 +- .../VatesAPI/src/MetadataJsonManager.cpp | 2 +- .../ViewBase.h | 2 +- .../src/AutoScaleRangeGenerator.cpp | 6 +- .../ViewWidgets/src/ColorUpdater.cpp | 2 +- .../ViewWidgets/src/ViewBase.cpp | 4 +- 8 files changed, 13 insertions(+), 177 deletions(-) delete mode 100644 Code/Mantid/Vates/VatesAPI/src/MDLoadingPresenter.cpp diff --git a/Code/Mantid/Vates/VatesAPI/src/MDEWRebinningPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDEWRebinningPresenter.cpp index f0292c682328..851019910bc1 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDEWRebinningPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDEWRebinningPresenter.cpp @@ -513,14 +513,14 @@ namespace Mantid /** * Get the minimum value of the data range. - * @retruns The maximum value of the data range. + * @returns The maximum value of the data range. */ double MDEWRebinningPresenter::getMinValue() const { return this->m_metadataJsonManager->getMinValue(); } - /** + /**getM * Get the instrument associated with the workspace * @returns The instrument */ diff --git a/Code/Mantid/Vates/VatesAPI/src/MDLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDLoadingPresenter.cpp deleted file mode 100644 index 45d07bd3cc5c..000000000000 --- a/Code/Mantid/Vates/VatesAPI/src/MDLoadingPresenter.cpp +++ /dev/null @@ -1,164 +0,0 @@ -#include "MantidVatesAPI/MDLoadingPresenter.h" -#include "qwt/qwt_double_interval.h" -#include "MantidAPI/IMDIterator.h" -#include "MantidAPI/IMDEventWorkspace.h" -#include "MantidAPI/IMDHistoWorkspace.h" -#include "MantidAPI/IPeaksWorkspace.h" -#include "MantidAPI/IMDWorkspace.h" -#include "MantidKernel/Logger.h" -#include "boost/pointer_cast.hpp" - -namespace Mantid -{ - namespace VATES - { - namespace - { - /// Static logger - Kernel::Logger g_log("MDLoadingPresenter"); - } - /** - * Extract the instrument information from the workspace. If there - * is more than one instrument involved, then extract the first instrument - * from the list. - * @param workspace A shared pointer to the workspace. - * @returns The instrument name or an empty string. - */ - std::string MDLoadingPresenter::extractInstrument(Mantid::API::IMDWorkspace_sptr workspace) - { - Mantid::API::IMDEventWorkspace_sptr eventWorkspace = boost::dynamic_pointer_cast(workspace); - Mantid::API::IMDHistoWorkspace_sptr histoWorkspace = boost::dynamic_pointer_cast(workspace); - - std::string instrument; - - // Check which workspace is currently used and that it contains at least one instrument. - if (eventWorkspace) - { - if (eventWorkspace->getNumExperimentInfo() > 0) - { - instrument = eventWorkspace->getExperimentInfo(0)->getInstrument()->getName(); - } else - { - g_log.warning() << "The event workspace does not have any instruments. \n"; - - instrument = ""; - } - } else if (histoWorkspace) - { - if (histoWorkspace->getNumExperimentInfo() > 0) - { - instrument = histoWorkspace->getExperimentInfo(0)->getInstrument()->getName(); - } else - { - g_log.warning() << "The histo workspace does not have any instruments. \n"; - - instrument = ""; - } - } else - { - g_log.warning() << "The workspace does not seem to be either event or histo. \n"; - instrument = ""; - } - - return instrument; - } - - /** - * Set the minimum and maximum of the workspace data. Code essentially copied from SignalRange.cpp - * @param histWs A reference to an IMD workspace - * @returns The minimum and maximum value of the workspace dataset. - */ - QwtDoubleInterval MDLoadingPresenter::getMinAndMax(Mantid::API::IMDWorkspace_sptr workspace) - { - auto iterators = workspace->createIterators(PARALLEL_GET_MAX_THREADS, 0); - - std::vector intervals(iterators.size()); - // cppcheck-suppress syntaxError - PRAGMA_OMP( parallel for schedule(dynamic, 1)) - for (int i=0; i < int(iterators.size()); i++) - { - Mantid::API::IMDIterator * it = iterators[i]; - QwtDoubleInterval range = this->getRange(it); - intervals[i] = range; - // don't delete iterator in parallel. MSVC doesn't like it - // when the iterator points to a mock object. - } - - // Combine the overall min/max - double minSignal = DBL_MAX; - double maxSignal = -DBL_MAX; - auto inf = std::numeric_limits::infinity(); - for (size_t i=0; i < iterators.size(); i++) - { - delete iterators[i]; - - double signal; - signal = intervals[i].minValue(); - if (signal != inf && signal < minSignal) minSignal = signal; - - signal = intervals[i].maxValue(); - if (signal != inf && signal > maxSignal) maxSignal = signal; - } - - if (minSignal == DBL_MAX) - { - minSignal = 0.0; - maxSignal = 1.0; - } - - QwtDoubleInterval minMaxContainer; - - if (minSignal < maxSignal) - minMaxContainer = QwtDoubleInterval(minSignal, maxSignal); - else - { - if (minSignal != 0) - // Possibly only one value in range - minMaxContainer = QwtDoubleInterval(minSignal*0.5, minSignal*1.5); - else - // Other default value - minMaxContainer = QwtDoubleInterval(0., 1.0); - } - - return minMaxContainer; - } - - /** - * Get the range of a workspace dataset for a single iterator. Code the same as in SignalRange.cpp - * @param it :: IMDIterator of what to find - * @return the min/max range, or INFINITY if not found - */ - QwtDoubleInterval MDLoadingPresenter::getRange(Mantid::API::IMDIterator * it) - { - if (!it) - return QwtDoubleInterval(0., 1.0); - if (!it->valid()) - return QwtDoubleInterval(0., 1.0); - - // Use no normalization - it->setNormalization(Mantid::API::VolumeNormalization); - - double minSignal = DBL_MAX; - double maxSignal = -DBL_MAX; - auto inf = std::numeric_limits::infinity(); - do - { - double signal = it->getNormalizedSignal(); - // Skip any 'infs' as it screws up the color scale - if (signal != inf) - { - if (signal < minSignal) minSignal = signal; - if (signal > maxSignal) maxSignal = signal; - } - } while (it->next()); - - - if (minSignal == DBL_MAX) - { - minSignal = inf; - maxSignal = inf; - } - return QwtDoubleInterval(minSignal, maxSignal); - } - } -} \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp b/Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp index 75b2df724983..9d9beb6abf55 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp @@ -31,7 +31,7 @@ namespace Mantid * Extract the instrument information from the workspace. If there * is more than one instrument involved, then extract the first instrument * from the list. - * @param workspace A shared pointer to the workspace. + * @param workspace Shared pointer to the workspace. * @returns The instrument name or an empty string. */ std::string MetaDataExtractorUtils::extractInstrument(Mantid::API::IMDWorkspace_sptr workspace) @@ -75,7 +75,7 @@ namespace Mantid /** * Set the minimum and maximum of the workspace data. Code essentially copied from SignalRange.cpp - * @param histWs A reference to an IMD workspace + * @param workspace Rreference to an IMD workspace * @returns The minimum and maximum value of the workspace dataset. */ QwtDoubleInterval MetaDataExtractorUtils::getMinAndMax(Mantid::API::IMDWorkspace_sptr workspace) @@ -146,7 +146,7 @@ namespace Mantid /** * Get the range of a workspace dataset for a single iterator. Code the same as in SignalRange.cpp * @param it :: IMDIterator of what to find - * @return the min/max range, or INFINITY if not found + * @returns the min/max range, or INFINITY if not found */ QwtDoubleInterval MetaDataExtractorUtils::getRange(Mantid::API::IMDIterator * it) { diff --git a/Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp b/Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp index 6567be7f263f..11fba10cb877 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp @@ -35,7 +35,7 @@ namespace Mantid /** * Read in the serialized JSON data and opulate the JSON container - * @param serialzedJson The serialized JSON string. + * @param serializedJson The serialized JSON string. */ void MetadataJsonManager::readInSerializedJson(std::string serializedJson) { diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h index de6f6b03d573..0d955541fa8f 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h @@ -192,7 +192,7 @@ public slots: void setViewsStatus(ModeControlWidget::Views view, bool state); /** * Singal to tell other elements that the log scale was altered programatically - * @param State flag wheter or not to enable the + * @param state flag wheter or not to enable the */ void setLogScale(bool state); diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp index 0f2a3f94b63d..5962e131e2fe 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp @@ -66,7 +66,7 @@ namespace SimpleGui /** * Get the auto color scale which depends on the mode setting. - * @retruns A VsiColorScale data structure which contains information + * @returns A VsiColorScale data structure which contains information * regarding the min and max value as well as if the log * scale is being used. */ @@ -182,8 +182,8 @@ namespace SimpleGui * we have to encounter a source with the desired properties. * Note that this assumes a unique source. * @param source A pointer to a source. - * @param minValueBuffer A reference to a min value buffer. - * @param maxValueBuffer A reference to a max value buffer. + * @param minValue A reference to a min value buffer. + * @param maxValue A reference to a max value buffer. */ void AutoScaleRangeGenerator::setMinBufferAndMaxBuffer(pqPipelineSource* source, double& minValue, double& maxValue) { diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp index c77f37e84667..adcf679791a6 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp @@ -182,7 +182,7 @@ void ColorUpdater::updateLookupTable(pqDataRepresentation* representation) /** * React to changing the log scale option - * @param The state to which the log scale is being changed. + * @param state The state to which the log scale is being changed. */ void ColorUpdater::logScale(int state) { diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp index 53dd071a51b7..d3d0b47a31ea 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp @@ -184,7 +184,7 @@ void ViewBase::onColorScaleChange(double min, double max) /** * This function sets logarithmic color scaling on the data. - * @param state flag to determine whether or not to use log color scaling + * @param state Flag to determine whether or not to use log color scaling */ void ViewBase::onLogScale(int state) { @@ -204,7 +204,7 @@ void ViewBase::setColorScaleState(ColorSelectionWidget *cs) /** * This function checks the current state from the color updater and * processes the necessary color changes. - * @param A pointer to the colorscale widget. + * @param colorScale A pointer to the colorscale widget. */ void ViewBase::setColorsForView(ColorSelectionWidget *colorScale) { From 00fb1fbf05a3c19258d83d038e9a2d9b662c5c61 Mon Sep 17 00:00:00 2001 From: Anton Piccardo-Selg Date: Tue, 27 Jan 2015 08:41:37 +0000 Subject: [PATCH 032/275] Refs #10627 Further doxygen fixes --- .../VatesAPI/inc/MantidVatesAPI/MetaDataExtractorUtils.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetaDataExtractorUtils.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetaDataExtractorUtils.h index adba2cb342d0..bba948644f93 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetaDataExtractorUtils.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetaDataExtractorUtils.h @@ -48,13 +48,13 @@ namespace Mantid /** * Get the minimum, maximum pair from the workspace * @param workspace A pointer to the workspace - * @return A pair of minimum and maximum values. + * @returns A pair of minimum and maximum values. */ QwtDoubleInterval getMinAndMax(Mantid::API::IMDWorkspace_sptr workspace); /** * Extracts the instrument from the workspace. - * @param A pointer to a workspace. + * @param workspace A pointer to a workspace. * @returns The instrument. */ std::string extractInstrument(Mantid::API::IMDWorkspace_sptr workspace); @@ -63,7 +63,7 @@ namespace Mantid /** * Get the range of data values from an MD iterator * @param it Iterator for a general MD workspace. - * @retunrs A maximum and minimum pair. + * @returns A maximum and minimum pair. */ QwtDoubleInterval getRange(Mantid::API::IMDIterator* it); From b0553b37ce4d369ca2ba33a41d692653fcb404b9 Mon Sep 17 00:00:00 2001 From: Anton Piccardo-Selg Date: Tue, 27 Jan 2015 08:51:05 +0000 Subject: [PATCH 033/275] Refs #10627 Fix for min and max value --- .../MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h index 40dcdc12b1dd..20c74d517435 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h @@ -94,8 +94,8 @@ class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS AutoScaleRangeGenerator * Extract the min and max values of a source. If we are dealing with a filter which does not * have the information then look upstream for the information * @param source A pointer to a source - * @param minValueBuffer A reference to a min value. - * @param maxValueBuffer A reference to a max value. + * @param minValue A reference to a min value. + * @param maxValue A reference to a max value. */ void setMinBufferAndMaxBuffer(pqPipelineSource* source, double& minValue, double& maxValue); From a835e2c44cdaf96a2876523df4f89da6067d9179 Mon Sep 17 00:00:00 2001 From: Harry Jeffery Date: Tue, 20 Jan 2015 16:29:30 +0000 Subject: [PATCH 034/275] Refs #10828 Create slit calculator widget --- .../MantidQt/MantidWidgets/CMakeLists.txt | 3 + .../MantidQtMantidWidgets/SlitCalculator.h | 52 +++ .../MantidQtMantidWidgets/SlitCalculator.ui | 438 ++++++++++++++++++ .../MantidWidgets/src/SlitCalculator.cpp | 38 ++ 4 files changed, 531 insertions(+) create mode 100644 Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SlitCalculator.h create mode 100644 Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SlitCalculator.ui create mode 100644 Code/Mantid/MantidQt/MantidWidgets/src/SlitCalculator.cpp diff --git a/Code/Mantid/MantidQt/MantidWidgets/CMakeLists.txt b/Code/Mantid/MantidQt/MantidWidgets/CMakeLists.txt index c7a613275f15..dd67d32c1c9c 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/CMakeLists.txt +++ b/Code/Mantid/MantidQt/MantidWidgets/CMakeLists.txt @@ -33,6 +33,7 @@ set ( SRC_FILES src/SelectFunctionDialog.cpp src/SelectWorkspacesDialog.cpp src/SequentialFitDialog.cpp + src/SlitCalculator.cpp src/StringDialogEditor.cpp src/StringEditorFactory.cpp src/UserFunctionDialog.cpp @@ -80,6 +81,7 @@ set ( MOC_FILES inc/MantidQtMantidWidgets/SelectFunctionDialog.h inc/MantidQtMantidWidgets/SelectWorkspacesDialog.h inc/MantidQtMantidWidgets/SequentialFitDialog.h + inc/MantidQtMantidWidgets/SlitCalculator.h inc/MantidQtMantidWidgets/StringDialogEditor.h inc/MantidQtMantidWidgets/StringEditorFactory.h inc/MantidQtMantidWidgets/UserFunctionDialog.h @@ -111,6 +113,7 @@ set ( UI_FILES inc/MantidQtMantidWidgets/RenameParDialog.ui inc/MantidQtMantidWidgets/SelectFunctionDialog.ui inc/MantidQtMantidWidgets/SequentialFitDialog.ui + inc/MantidQtMantidWidgets/SlitCalculator.ui inc/MantidQtMantidWidgets/UserFunctionDialog.ui inc/MantidQtMantidWidgets/pqHelpWindow.ui ) diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SlitCalculator.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SlitCalculator.h new file mode 100644 index 000000000000..199550efb76f --- /dev/null +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SlitCalculator.h @@ -0,0 +1,52 @@ +#ifndef MANTID_MANTIDWIDGETS_SLITCALCULATOR_H +#define MANTID_MANTIDWIDGETS_SLITCALCULATOR_H + +//---------------------------------- +// Includes +//---------------------------------- +#include "WidgetDllOption.h" +#include "ui_SlitCalculator.h" + +#include + +namespace MantidQt +{ + namespace MantidWidgets + { + /** SlitCalculator : A calculator for Reflectometry instrument slits + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS SlitCalculator : public QDialog + { + Q_OBJECT + public: + SlitCalculator(QWidget* parent); + virtual ~SlitCalculator(); + protected: + Ui::SlitCalculator ui; + private slots: + void on_recalculate_triggered(); + }; + } +} + +#endif /* MANTID_MANTIDWIDGETS_SLITCALCULATOR_H */ diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SlitCalculator.ui b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SlitCalculator.ui new file mode 100644 index 000000000000..a5933ec81714 --- /dev/null +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SlitCalculator.ui @@ -0,0 +1,438 @@ + + + SlitCalculator + + + + 0 + 0 + 275 + 342 + + + + + 0 + 0 + + + + Slit Calculator + + + + + + Input + + + + + + + 75 + true + + + + Slit 1 → Slit 2 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + mm + + + 10000.000000000000000 + + + 1940.500000000000000 + + + + + + + + 75 + true + + + + Slit 2 → SA + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + mm + + + 10000.000000000000000 + + + 364.000000000000000 + + + + + + + + 75 + true + + + + Resolution (dQ/Q) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 3 + + + 0.010000000000000 + + + 0.030000000000000 + + + + + + + ° + + + 10.000000000000000 + + + 0.100000000000000 + + + 0.700000000000000 + + + + + + + + 75 + true + + + + Footprint + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + mm + + + 1 + + + 500.000000000000000 + + + 50.000000000000000 + + + + + + + + 75 + true + + + + Angle + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Output + + + + + + + 75 + true + + + + Slit 1 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 75 + 16777215 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + + + + + + 75 + true + + + + Slit 2 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 75 + 16777215 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + + + + + mm + + + + + + + mm + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + recalculate + + + + + buttonBox + spinSlit1Slit2 + spinSlit2Sample + spinResolution + spinFootprint + spinAngle + slit1Text + slit2Text + + + + + buttonBox + accepted() + SlitCalculator + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + SlitCalculator + reject() + + + 316 + 260 + + + 286 + 274 + + + + + spinAngle + valueChanged(double) + recalculate + trigger() + + + 172 + 171 + + + -1 + -1 + + + + + spinFootprint + valueChanged(double) + recalculate + trigger() + + + 172 + 140 + + + -1 + -1 + + + + + spinResolution + valueChanged(double) + recalculate + trigger() + + + 172 + 109 + + + -1 + -1 + + + + + spinSlit1Slit2 + valueChanged(double) + recalculate + trigger() + + + 172 + 47 + + + -1 + -1 + + + + + spinSlit2Sample + valueChanged(double) + recalculate + trigger() + + + 172 + 78 + + + -1 + -1 + + + + + diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/SlitCalculator.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/SlitCalculator.cpp new file mode 100644 index 000000000000..8dcf3f6c9bc5 --- /dev/null +++ b/Code/Mantid/MantidQt/MantidWidgets/src/SlitCalculator.cpp @@ -0,0 +1,38 @@ +#include "MantidQtMantidWidgets/SlitCalculator.h" +#include + +namespace MantidQt +{ + namespace MantidWidgets + { + SlitCalculator::SlitCalculator(QWidget *parent) + { + Q_UNUSED(parent); + ui.setupUi(this); + on_recalculate_triggered(); + } + + SlitCalculator::~SlitCalculator() + { + } + + void SlitCalculator::on_recalculate_triggered() + { + //Gather input + const double PI = 2*qAsin(1); + const double s1s2 = ui.spinSlit1Slit2->value(); + const double s2sa = ui.spinSlit2Sample->value(); + const double res = ui.spinResolution->value(); + const double footprint = ui.spinFootprint->value(); + const double angle = ui.spinAngle->value(); + + //Calculate values + const double s1 = 2 * (s1s2 + s2sa) * qTan(res * angle * PI / 180) - footprint * qSin(angle * PI / 180); + const double s2 = s1s2 * (footprint * qSin(angle * PI / 180) + s1) / (s1s2 + s2sa) - s1; + + //Update output + ui.slit1Text->setText(QString::number(s1,'f',3)); + ui.slit2Text->setText(QString::number(s2,'f',3)); + } + } +} From a221f822ee8e21179814a0e3015b8ec2c16f51b7 Mon Sep 17 00:00:00 2001 From: Harry Jeffery Date: Tue, 20 Jan 2015 16:46:30 +0000 Subject: [PATCH 035/275] Refs #10828 Add slit calculator to new Refl UI --- .../inc/MantidQtCustomInterfaces/QtReflMainView.h | 3 +++ .../inc/MantidQtCustomInterfaces/ReflMainWidget.ui | 11 +++++++++++ .../MantidQt/CustomInterfaces/src/QtReflMainView.cpp | 10 +++++++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/QtReflMainView.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/QtReflMainView.h index 3d14e13c84ce..5318875e6433 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/QtReflMainView.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/QtReflMainView.h @@ -7,6 +7,7 @@ #include "MantidQtCustomInterfaces/IReflPresenter.h" #include "MantidQtCustomInterfaces/ReflSearchModel.h" #include "MantidQtCustomInterfaces/QReflTableModel.h" +#include "MantidQtMantidWidgets/SlitCalculator.h" #include #include #include "ui_ReflMainWidget.h" @@ -100,6 +101,7 @@ namespace MantidQt //the workspace the user selected to open std::string m_toOpen; QSignalMapper* m_openMap; + MantidWidgets::SlitCalculator* m_calculator; private slots: void on_actionNewTable_triggered(); @@ -123,6 +125,7 @@ namespace MantidQt void on_actionHelp_triggered(); void on_actionPlotRow_triggered(); void on_actionPlotGroup_triggered(); + void on_actionSlitCalculator_triggered(); void on_comboSearchInstrument_currentIndexChanged(int index); void on_comboProcessInstrument_currentIndexChanged(int index); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainWidget.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainWidget.ui index fed9132ab6db..6c2b193e9a93 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainWidget.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainWidget.ui @@ -368,6 +368,8 @@ + + @@ -685,6 +687,15 @@ Creates a plot of the stitched IvsQ workspaces produced by any groups any selected rows are in. + + + + :/param_range_btn.png:/param_range_btn.png + + + Slit Calculator + + comboSearchInstrument diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/QtReflMainView.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/QtReflMainView.cpp index 447c556521bf..7882684398a5 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/QtReflMainView.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/QtReflMainView.cpp @@ -19,7 +19,7 @@ namespace MantidQt //---------------------------------------------------------------------------------------------- /** Constructor */ - QtReflMainView::QtReflMainView(QWidget *parent) : UserSubWindow(parent), m_openMap(new QSignalMapper(this)) + QtReflMainView::QtReflMainView(QWidget *parent) : UserSubWindow(parent), m_openMap(new QSignalMapper(this)), m_calculator(new MantidWidgets::SlitCalculator(this)) { } @@ -294,6 +294,14 @@ namespace MantidQt m_presenter->notify(IReflPresenter::PlotGroupFlag); } + /** + This slot shows the slit calculator + */ + void QtReflMainView::on_actionSlitCalculator_triggered() + { + m_calculator->show(); + } + /** This slot notifies the presenter that the table has been updated/changed by the user */ From d4f2299df6a1ab5c03fe6dd2fbb031584d2d6821 Mon Sep 17 00:00:00 2001 From: Harry Jeffery Date: Wed, 21 Jan 2015 15:37:54 +0000 Subject: [PATCH 036/275] Refs #10828 Don't use qmath in slit calculator --- Code/Mantid/MantidQt/MantidWidgets/src/SlitCalculator.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/SlitCalculator.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/SlitCalculator.cpp index 8dcf3f6c9bc5..e9ea47454da1 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/SlitCalculator.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/SlitCalculator.cpp @@ -1,5 +1,5 @@ #include "MantidQtMantidWidgets/SlitCalculator.h" -#include +#include namespace MantidQt { @@ -19,7 +19,6 @@ namespace MantidQt void SlitCalculator::on_recalculate_triggered() { //Gather input - const double PI = 2*qAsin(1); const double s1s2 = ui.spinSlit1Slit2->value(); const double s2sa = ui.spinSlit2Sample->value(); const double res = ui.spinResolution->value(); @@ -27,8 +26,8 @@ namespace MantidQt const double angle = ui.spinAngle->value(); //Calculate values - const double s1 = 2 * (s1s2 + s2sa) * qTan(res * angle * PI / 180) - footprint * qSin(angle * PI / 180); - const double s2 = s1s2 * (footprint * qSin(angle * PI / 180) + s1) / (s1s2 + s2sa) - s1; + const double s1 = 2 * (s1s2 + s2sa) * tan(res * angle * M_PI / 180) - footprint * sin(angle * M_PI / 180); + const double s2 = s1s2 * (footprint * sin(angle * M_PI / 180) + s1) / (s1s2 + s2sa) - s1; //Update output ui.slit1Text->setText(QString::number(s1,'f',3)); From 4c11d71209d297d2d34d29cfe12e3df01ad9c20f Mon Sep 17 00:00:00 2001 From: Harry Jeffery Date: Tue, 27 Jan 2015 14:35:58 +0000 Subject: [PATCH 037/275] Refs #10828 Add CalculateSlits algorithm --- .../Framework/Algorithms/CMakeLists.txt | 2 + .../inc/MantidAlgorithms/CalculateSlits.h | 54 ++++++++ .../Algorithms/src/CalculateSlits.cpp | 125 ++++++++++++++++++ 3 files changed, 181 insertions(+) create mode 100644 Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CalculateSlits.h create mode 100644 Code/Mantid/Framework/Algorithms/src/CalculateSlits.cpp diff --git a/Code/Mantid/Framework/Algorithms/CMakeLists.txt b/Code/Mantid/Framework/Algorithms/CMakeLists.txt index 048e4ad29b1c..a0d783d12839 100644 --- a/Code/Mantid/Framework/Algorithms/CMakeLists.txt +++ b/Code/Mantid/Framework/Algorithms/CMakeLists.txt @@ -24,6 +24,7 @@ set ( SRC_FILES src/CalculateEfficiency.cpp src/CalculateFlatBackground.cpp src/CalculateResolution.cpp + src/CalculateSlits.cpp src/CalculateTransmission.cpp src/CalculateTransmissionBeamSpreader.cpp src/CalculateZscore.cpp @@ -277,6 +278,7 @@ set ( INC_FILES inc/MantidAlgorithms/CalculateEfficiency.h inc/MantidAlgorithms/CalculateFlatBackground.h inc/MantidAlgorithms/CalculateResolution.h + inc/MantidAlgorithms/CalculateSlits.h inc/MantidAlgorithms/CalculateTransmission.h inc/MantidAlgorithms/CalculateTransmissionBeamSpreader.h inc/MantidAlgorithms/CalculateZscore.h diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CalculateSlits.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CalculateSlits.h new file mode 100644 index 000000000000..e92700572a98 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CalculateSlits.h @@ -0,0 +1,54 @@ +#ifndef MANTID_ALGORITHMS_CALCULATESLITS_H_ +#define MANTID_ALGORITHMS_CALCULATESLITS_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidAPI/DataProcessorAlgorithm.h" +#include + +namespace Mantid { +namespace Algorithms { + +/** CalculateSlits + +Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge +National Laboratory & European Spallation Source + +This file is part of Mantid. + +Mantid is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. + +Mantid is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +File change history is stored at: +Code Documentation is available at: +*/ + +class DLLExport CalculateSlits : public API::DataProcessorAlgorithm { +public: + CalculateSlits(); + virtual ~CalculateSlits(); + + virtual const std::string name() const; + virtual int version() const; + virtual const std::string category() const; + virtual const std::string summary() const; + +private: + void init(); + void exec(); +}; + +} // namespace Algorithms +} // namespace Mantid + +#endif /* MANTID_ALGORITHMS_CALCULATESLITS_H_ */ diff --git a/Code/Mantid/Framework/Algorithms/src/CalculateSlits.cpp b/Code/Mantid/Framework/Algorithms/src/CalculateSlits.cpp new file mode 100644 index 000000000000..cf9b8312714f --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/src/CalculateSlits.cpp @@ -0,0 +1,125 @@ +#include "MantidAlgorithms/CalculateSlits.h" + +#include +#include + +namespace Mantid { +namespace Algorithms { + +using namespace Mantid::API; +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; + +// Register the algorithm into the AlgorithmFactory +DECLARE_ALGORITHM(CalculateSlits) + +//---------------------------------------------------------------------------------------------- +/** Constructor +*/ +CalculateSlits::CalculateSlits() {} + +//---------------------------------------------------------------------------------------------- +/** Destructor +*/ +CalculateSlits::~CalculateSlits() {} + +//---------------------------------------------------------------------------------------------- + +/// Algorithm's name for identification. @see Algorithm::name +const std::string CalculateSlits::name() const { + return "CalculateSlits"; +}; + +/// Algorithm's version for identification. @see Algorithm::version +int CalculateSlits::version() const { return 1; }; + +/// Algorithm's category for identification. @see Algorithm::category +const std::string CalculateSlits::category() const { + return "Reflectometry\\ISIS"; +} + +/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary +const std::string CalculateSlits::summary() const { + return "Calculates appropriate slit widths for reflectometry instruments."; +}; + +//---------------------------------------------------------------------------------------------- +/** Initialize the algorithm's properties. +*/ +void CalculateSlits::init() { + declareProperty("Slit1Slit2", Mantid::EMPTY_DBL(), + "Distance between slit 1 and slit 2 in mm"); + declareProperty("Slit2SA", Mantid::EMPTY_DBL(), "Unknown distance in mm"); + declareProperty("Resolution", Mantid::EMPTY_DBL(), "Resolution"); + declareProperty("Footprint", Mantid::EMPTY_DBL(), "Footprint in mm"); + declareProperty("Angle", Mantid::EMPTY_DBL(), "Angle in degrees"); + + declareProperty("Slit1", Mantid::EMPTY_DBL(), "Slit 1 width in mm", + Direction::Output); + declareProperty("Slit2", Mantid::EMPTY_DBL(), "Slit 2 width in mm", + Direction::Output); +} + +//---------------------------------------------------------------------------------------------- +/** Execute the algorithm. +*/ +void CalculateSlits::exec() { + const double res = getProperty("Resolution"); + const double fp = getProperty("Footprint"); + const double angleDeg = getProperty("Angle"); + const double s1s2 = getProperty("Slit1Slit2"); + const double s2sa = getProperty("Slit2SA"); + + + /* + |←----d-----→| + _ _ + _ _ _-¯ | ↑ + ↑ | ¯-_ _-¯ | | + S₂ | (Θ_X_Θ) | S₁ ←---beam--- + ↓ |_-¯ ¯-_ | | + ¯ ¯-_| ↓ + ¯ + _ _ + _-¯ | ↑ + _-¯ | | + _-¯ _| | ½S₀ + _-¯α) | | ↓ + ¯¯¯¯¯¯¯¯¯¯¯¯ ¯ + |←----d-----→| + + For the purposes of these diagrams, Θ has + already been multiplied by the resolution. + + α = ½Θ + t = tan(α) + r = resolution + f = footprint (???) + u = unknown dimension + + S₀ = S₁ + S₂ + = 2•d•t + + S₁ = 2•d•t - S₂ + = 2•d•t - f•sin(α/r) + 2•u•t + = 2•(d+u)•t - f•sin(α/r) + + S₂ = f•sin(α/r) - 2•u•t + + sin(α/r) is opp/hyp of the full angle, without the resolution coefficient + if f is the hypotenuse of a triangle constructed from the full angle + then f•sin(α/r) is the length of the side opposite the angle + */ + + //Convert angle to radians for our calculations + const double a = angleDeg * M_PI / 180.0; + + const double s2 = (fp * sin(a)) - (2 * s2sa * tan(res * a)); + const double s1 = (2 * s1s2 * tan(res * a)) - s2; + + setProperty("Slit1", s1); + setProperty("Slit2", s2); +} + +} // namespace Algorithms +} // namespace Mantid From d00a987452dfbc676db693885fdfa37df84be2d4 Mon Sep 17 00:00:00 2001 From: Harry Jeffery Date: Tue, 27 Jan 2015 14:36:10 +0000 Subject: [PATCH 038/275] Refs #10828 Use CalculateSlits algorithm in slit calculator --- .../MantidQt/MantidWidgets/src/SlitCalculator.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/SlitCalculator.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/SlitCalculator.cpp index e9ea47454da1..08255d1a7e14 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/SlitCalculator.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/SlitCalculator.cpp @@ -1,4 +1,5 @@ #include "MantidQtMantidWidgets/SlitCalculator.h" +#include "MantidAPI/AlgorithmManager.h" #include namespace MantidQt @@ -26,8 +27,18 @@ namespace MantidQt const double angle = ui.spinAngle->value(); //Calculate values - const double s1 = 2 * (s1s2 + s2sa) * tan(res * angle * M_PI / 180) - footprint * sin(angle * M_PI / 180); - const double s2 = s1s2 * (footprint * sin(angle * M_PI / 180) + s1) / (s1s2 + s2sa) - s1; + Mantid::API::IAlgorithm_sptr algSlit = Mantid::API::AlgorithmManager::Instance().create("CalculateSlits"); + algSlit->initialize(); + algSlit->setChild(true); + algSlit->setProperty("Slit1Slit2", s1s2); + algSlit->setProperty("Slit2SA", s2sa); + algSlit->setProperty("Resolution", res); + algSlit->setProperty("Footprint", footprint); + algSlit->setProperty("Angle", angle); + algSlit->execute(); + + const double s1 = algSlit->getProperty("Slit1"); + const double s2 = algSlit->getProperty("Slit2"); //Update output ui.slit1Text->setText(QString::number(s1,'f',3)); From 8094470ffacbd38f0c16c08d0956911248d648ef Mon Sep 17 00:00:00 2001 From: Harry Jeffery Date: Tue, 27 Jan 2015 16:40:28 +0000 Subject: [PATCH 039/275] Refs #10828 Add SlitCalculator dialog to old refl gui --- Code/Mantid/MantidQt/Python/mantidqt.sip | 28 +++++++++++++++++++ .../Interface/ui/reflectometer/refl_gui.py | 6 ++++ .../Interface/ui/reflectometer/refl_window.py | 8 ++++-- .../Interface/ui/reflectometer/refl_window.ui | 8 +++++- 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/Code/Mantid/MantidQt/Python/mantidqt.sip b/Code/Mantid/MantidQt/Python/mantidqt.sip index cb4fe1b5674b..a4f514df9c8a 100644 --- a/Code/Mantid/MantidQt/Python/mantidqt.sip +++ b/Code/Mantid/MantidQt/Python/mantidqt.sip @@ -1390,3 +1390,31 @@ public: }; // end namespace MantidWidgets }; // end namespace MantidQt + +namespace MantidQt +{ +namespace MantidWidgets +{ + +class SlitCalculator : QDialog +{ +%TypeHeaderCode +#include "MantidQtMantidWidgets/SlitCalculator.h" +%End +%Docstring + +SlitCalculator +============== + + The SlitCalculator is a control for interacting with the CalculateSlits algorithm. + +%End + +public: + SlitCalculator(QWidget* parent); + virtual ~SlitCalculator(); + +}; + +}; // end namespace MantidWidgets +}; // end namespace MantidQt diff --git a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui.py b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui.py index 569a85819416..99b3c7da943e 100644 --- a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui.py +++ b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui.py @@ -14,6 +14,7 @@ from isis_reflectometry.convert_to_wavelength import ConvertToWavelength from isis_reflectometry import load_live_runs from isis_reflectometry.combineMulti import * +import mantidqtpython from mantid.api import Workspace, WorkspaceGroup, CatalogManager, AlgorithmManager try: @@ -200,6 +201,10 @@ def _plot_row(self): plotbutton = self.sender() self._plot(plotbutton) + def _show_slit_calculator(self): + calc = mantidqtpython.MantidQt.MantidWidgets.SlitCalculator(self) + calc.exec_() + def _polar_corr_selected(self): """ Event handler for polarisation correction selection. @@ -360,6 +365,7 @@ def _connect_slots(self): self.actionCopy.triggered.connect(self._copy_cells) self.actionChoose_Columns.triggered.connect(self._choose_columns) self.actionRefl_Gui_Options.triggered.connect(self._options_dialog) + self.actionSlit_Calculator.triggered.connect(self._show_slit_calculator) def __valid_rb(self): diff --git a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_window.py b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_window.py index 40fd99411eb0..689e5e4647f9 100644 --- a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_window.py +++ b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_window.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'refl_window.ui' # -# Created: Thu Aug 14 15:01:03 2014 +# Created: Tue Jan 27 15:40:39 2015 # by: PyQt4 UI code generator 4.10.4 # # WARNING! All changes made in this file will be lost! @@ -220,7 +220,7 @@ def setupUi(self, windowRefl): self.layoutBase.addWidget(self.splitterList) windowRefl.setCentralWidget(self.widgetMainRow) self.menuBar = QtGui.QMenuBar(windowRefl) - self.menuBar.setGeometry(QtCore.QRect(0, 0, 1000, 21)) + self.menuBar.setGeometry(QtCore.QRect(0, 0, 1000, 23)) self.menuBar.setObjectName(_fromUtf8("menuBar")) self.menuFile = QtGui.QMenu(self.menuBar) self.menuFile.setObjectName(_fromUtf8("menuFile")) @@ -275,6 +275,8 @@ def setupUi(self, windowRefl): self.actionChoose_Columns.setObjectName(_fromUtf8("actionChoose_Columns")) self.actionRefl_Gui_Options = QtGui.QAction(windowRefl) self.actionRefl_Gui_Options.setObjectName(_fromUtf8("actionRefl_Gui_Options")) + self.actionSlit_Calculator = QtGui.QAction(windowRefl) + self.actionSlit_Calculator.setObjectName(_fromUtf8("actionSlit_Calculator")) self.menuFile.addAction(self.actionOpen_Table) self.menuFile.addAction(self.actionReload_from_Disk) self.menuFile.addSeparator() @@ -284,6 +286,7 @@ def setupUi(self, windowRefl): self.menuFile.addSeparator() self.menuFile.addAction(self.actionClose_Refl_Gui) self.menuHelp.addAction(self.actionMantid_Help) + self.menuHelp.addAction(self.actionSlit_Calculator) self.menuFunction.addAction(self.actionTransfer) self.menuFunction.addAction(self.actionAutofill) self.menuFunction.addSeparator() @@ -420,4 +423,5 @@ def retranslateUi(self, windowRefl): self.actionChoose_Columns.setShortcut(_translate("windowRefl", "Ctrl+M", None)) self.actionRefl_Gui_Options.setText(_translate("windowRefl", "Refl Gui Options...", None)) self.actionRefl_Gui_Options.setShortcut(_translate("windowRefl", "Ctrl+Shift+O", None)) + self.actionSlit_Calculator.setText(_translate("windowRefl", "Slit Calculator", None)) diff --git a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_window.ui b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_window.ui index 63004f04a8ce..19206e2136a9 100644 --- a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_window.ui +++ b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_window.ui @@ -610,7 +610,7 @@ 0 0 1000 - 21 + 23 @@ -631,6 +631,7 @@ Help + @@ -817,6 +818,11 @@ Ctrl+Shift+O + + + Slit Calculator + + comboInstrument From e7765fb7ffec4b6cd5e59a122e97812b6d05d8b9 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Wed, 28 Jan 2015 09:06:19 +0000 Subject: [PATCH 040/275] Re #9556 DKT base implementation --- .../Framework/CurveFitting/CMakeLists.txt | 2 + .../MantidCurveFitting/DynamicKuboToyabe.h | 72 +++++ .../CurveFitting/src/DynamicKuboToyabe.cpp | 245 ++++++++++++++++++ 3 files changed, 319 insertions(+) create mode 100644 Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/DynamicKuboToyabe.h create mode 100644 Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp diff --git a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt index d48a4ac4a661..93d8e42f046a 100644 --- a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt +++ b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt @@ -29,6 +29,7 @@ set ( SRC_FILES src/DerivMinimizer.cpp src/DiffRotDiscreteCircle.cpp src/DiffSphere.cpp + src/DynamicKuboToyabe.cpp src/EndErfc.cpp src/ExpDecay.cpp src/ExpDecayMuon.cpp @@ -135,6 +136,7 @@ set ( INC_FILES inc/MantidCurveFitting/DiffRotDiscreteCircle.h inc/MantidCurveFitting/DiffSphere.h inc/MantidCurveFitting/DllConfig.h + inc/MantidCurveFitting/DynamicKuboToyabe.h inc/MantidCurveFitting/EndErfc.h inc/MantidCurveFitting/ExpDecay.h inc/MantidCurveFitting/ExpDecayMuon.h diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/DynamicKuboToyabe.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/DynamicKuboToyabe.h new file mode 100644 index 000000000000..261905dc46ce --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/DynamicKuboToyabe.h @@ -0,0 +1,72 @@ +#ifndef MANTID_CURVEFITTING_DYNAMICKUBOTOYABE_H_ +#define MANTID_CURVEFITTING_DYNAMICKUBOTOYABE_H_ + +//---------------------------------------------------------------------- +// Includes +//---------------------------------------------------------------------- +#include "MantidAPI/IPeakFunction.h" +#include "MantidAPI/IFunctionMW.h" +#include "MantidAPI/IFunctionWithLocation.h" +#include + +//#include "MantidAPI/ParamFunction.h" +//#include "MantidAPI/IPeakFunction.h" + +//#include "MantidAPI/IFunctionMW.h" +//#include "MantidAPI/IFunction1D.h" + +namespace Mantid +{ + namespace CurveFitting + { + /** + Provide Dynamic Kubo Toyabe function interface to IPeakFunction for muon scientists. + + @author Karl Palmen, ISIS, RAL + @date 21/03/2012 + + Copyright © 2007-2012 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + + class DLLExport DynamicKuboToyabe : public API::ParamFunction, public API::IFunction1D + { + public: + + /// Destructor + virtual ~DynamicKuboToyabe() {} + + /// overwrite base class methods + std::string name()const{return "DynamicKuboToyabe";} + virtual const std::string category() const { return "Muon";} + + protected: + virtual void function1D(double* out, const double* xValues, const size_t nData)const; + virtual void functionDeriv1D(API::Jacobian* out, const double* xValues, const size_t nData); + virtual void functionDeriv(const API::FunctionDomain& domain, API::Jacobian& jacobian); + virtual void init(); + virtual void setActiveParameter(size_t i, double value); + + }; + + } // namespace CurveFitting +} // namespace Mantid + +#endif /*MANTID_CURVEFITTING_DYNAMICKUBOTOYABE_H_*/ \ No newline at end of file diff --git a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp new file mode 100644 index 000000000000..c3c00ca34cc1 --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp @@ -0,0 +1,245 @@ +//---------------------------------------------------------------------- +// Includes +//---------------------------------------------------------------------- +#include "MantidCurveFitting/DynamicKuboToyabe.h" +#include "MantidAPI/Jacobian.h" +#include "MantidAPI/FunctionFactory.h" +#include +#include // TODO Remove + +#define EPS 1e-6 +#define JMAX 14 +#define JMAXP (JMAX+1) +#define K 5 +#define NR_END 1 +#define FREE_ARG char* + +namespace Mantid +{ +namespace CurveFitting +{ + +using namespace Kernel; +using namespace API; +using namespace boost::math; + +DECLARE_FUNCTION(DynamicKuboToyabe) + +// ** MODIFY THIS ** +// Here specify/declare the parameters of your Fit Function +// +// declareParameter takes three arguments: +// +// 1st: The name of the parameter +// 2nd: The default (initial) value of the parameter +// 3rd: A description of the parameter (optional) +// +void DynamicKuboToyabe::init() +{ + declareParameter("Asym", 0.2); + declareParameter("Delta", 0.2); + declareParameter("Field",0.0); + declareParameter("Nu",0.0); + //declareParameter("EndX",15); +} + + +//------------------------------------------------------------------------------------------------ +double *vector(long nl, long nh) +/* allocate a double vector with subscript range v[nl..nh] */ +{ + double *v; + + v=(double *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(double))); + if (!v) throw std::runtime_error("allocation failure in dvector()"); + return v-nl+NR_END; +} +void free_vector(double *v, long nl, long nh) +/* free a double vector allocated with dvector() */ +{ + free((FREE_ARG) (v+nl-NR_END)); +} +double midpnt(double func(const double, const double, const double), + const double a, const double b, const int n, const double g, const double w0) { +// quote & modified from numerical recipe 2nd edtion (page147) + + static double s; + + if (n==1) { + double s1 = 0.5*(b-a)*func(a,g,w0)+func(b,g,w0); + double s2 = (b-a)*func(0.5*(a+b),g,w0); + return (s2); + } else { + double x, tnm, sum, del, ddel; + int it, j; + for (it=1,j=1;j= K) { + polint(&h[j-K],&s[j-K],K,0.0,ss,dss); + if (fabs(dss) <= fabs(ss)) return ss; + } + h[j+1]=h[j]/9.0; + } + throw std::runtime_error("integrate(): Too many steps in routine integrate\n"); + return 0.0; +} + +//-------------------------------------------------------------------------------------------------------------------------------------- + + +double f1(const double x, const double G, const double w0) { + return( exp(-G*G*x*x/2)*sin(w0*x)); +} + +double ZFKT (double q){ + // In zero field: + // g(t) = 1/3 + 2/3 exp( -q/2 ) ( 1 - q ) + // q = t *sigma + return (0.3333333333 + 0.6666666667*exp(-0.5*q)*(1-q)); +} +double gz (const double x, const double G, const double F) +{ + double w0 = 2.0*3.1415926536*0.01355342*F; + const double q = G*G*x*x; + + if (w0 == 0.0) { + return (ZFKT(q)); + } + else { + + if (F>2.0*G) { w0 = 2*3.1415926*0.01355342*F ;} else { w0 =2*3.1415926*0.01355342*2.0*G; } + + double p = G*G/(w0*w0); + double HKT = 1.0-2.0*p*(1-exp(-q/2.0)*cos(w0*x))+2.0*p*p*w0*integrate(f1,0.0,x,G,w0); + if (F>2.0*G) {return (HKT);} + else {return (ZFKT(q)+ (F/2.0/G)*(HKT-ZFKT(q)));} + + } +} + +// Original function by mark telling +void DynamicKuboToyabe::function1D(double* out, const double* xValues, const size_t nData)const +{ + const double& A = getParameter("Asym"); + const double& G = fabs(getParameter("Delta")); + const double& F = fabs(getParameter("Field")); + const double& v = fabs(getParameter("Nu")); + + + // Zero hopping rate + if (v == 0.0) { + for (size_t i = 0; i < nData; i++) { + out[i] = A*gz(xValues[i],G,F); + } + } + + // Non-zero hopping rate + else { + + const int n = 1000; + const double stepsize = fabs(xValues[nData-1]/n); + // do{stepsizeTemp=stepsizeTemp/10;nTemp=nTemp*10; }while (xValues[0] funcG(n); + + for (int i = 0; i < n; i++) { + + double Integral=0.0; + for (int c = 1; c <= i; c++) { + Integral= gz(c*stepsize,G,F)*exp(-v*c*stepsize)*funcG[i-c]*(stepsize) + Integral; + } + funcG[i] = (gz(i*stepsize,G,F)*exp(-v*i*stepsize) + v*Integral); + } + + + for (size_t i = 0; i < nData; i++) { + double a =xValues[i]/stepsize; + out[i] = A*(funcG.at(int(a)-1)); + } + + } // else hopping rate != 0 + +} + + + +void DynamicKuboToyabe::functionDeriv(const API::FunctionDomain& domain, API::Jacobian& jacobian) +{ + calNumericalDeriv(domain, jacobian); +} + +void DynamicKuboToyabe::functionDeriv1D(API::Jacobian* , const double* , const size_t ) +{ + throw Mantid::Kernel::Exception::NotImplementedError("functionDerivLocal is not implemented for DynamicKuboToyabe."); +} + +void DynamicKuboToyabe::setActiveParameter(size_t i, double value) { + + setParameter( i, fabs(value), false); + +} + +} // namespace CurveFitting +} // namespace Mantid From fb9f1dce6329b9a624232841821980e6e350c7b7 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Wed, 28 Jan 2015 11:11:34 +0000 Subject: [PATCH 041/275] Re #9556 DKT updating parameter description --- .../CurveFitting/src/DynamicKuboToyabe.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp index c3c00ca34cc1..bb8564563d19 100644 --- a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp @@ -36,10 +36,10 @@ DECLARE_FUNCTION(DynamicKuboToyabe) // void DynamicKuboToyabe::init() { - declareParameter("Asym", 0.2); - declareParameter("Delta", 0.2); - declareParameter("Field",0.0); - declareParameter("Nu",0.0); + declareParameter("Asym", 0.2, "Amplitude at time 0"); + declareParameter("Delta", 0.2, "Local field"); + declareParameter("Field", 0.0, "External field"); + declareParameter("Nu", 0.0, "Hopping rate"); //declareParameter("EndX",15); } @@ -197,13 +197,11 @@ void DynamicKuboToyabe::function1D(double* out, const double* xValues, const siz // Non-zero hopping rate else { - const int n = 1000; const double stepsize = fabs(xValues[nData-1]/n); // do{stepsizeTemp=stepsizeTemp/10;nTemp=nTemp*10; }while (xValues[0] funcG(n); - for (int i = 0; i < n; i++) { double Integral=0.0; @@ -216,7 +214,8 @@ void DynamicKuboToyabe::function1D(double* out, const double* xValues, const siz for (size_t i = 0; i < nData; i++) { double a =xValues[i]/stepsize; - out[i] = A*(funcG.at(int(a)-1)); + a = a Date: Wed, 28 Jan 2015 11:15:14 +0000 Subject: [PATCH 042/275] Re #9556 DKT documentation --- .../source/fitfunctions/DynamicKuboToyabe.rst | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Code/Mantid/docs/source/fitfunctions/DynamicKuboToyabe.rst diff --git a/Code/Mantid/docs/source/fitfunctions/DynamicKuboToyabe.rst b/Code/Mantid/docs/source/fitfunctions/DynamicKuboToyabe.rst new file mode 100644 index 000000000000..206be446c5e1 --- /dev/null +++ b/Code/Mantid/docs/source/fitfunctions/DynamicKuboToyabe.rst @@ -0,0 +1,31 @@ +.. _func-DynamicKuboToyabe: + +================ +DynamicKuboToyabe +================ + +.. index:: DynamicKuboToyabe + +Description +----------- + +Dynamic Kubo Toyabe fitting function for use by Muon scientists defined +by + +.. math:: G_z \left(t\right) = g_z\left(t\right) e^{-\nu t} + \nu \int_0^t g_z\left(\tau\right) e^{-\nu\tau} G_z\left(t-\tau\right) d\tau + +where :math:`g_z\left(t\right)` is the static KT function. + +| In zero field, :math:`B_0=0`: + +.. math:: g_z\left(t\right) = \mbox{A} \Bigg[ \frac{1}{3} + \frac{2}{3} \left( 1 - {\Delta}^2 {t}^2 \right) e^{-\frac{1}{2}\Delta^2 t^2} \Bigg] + +| In the presence of a longitudinal field, :math:`B_0=\omega_0 /\gamma_{\mu}>0`: + +.. math:: g_z\left(t\right) = \mbox{A} \Bigg[ 1 - 2\frac{\Delta^2}{\omega_0^2}\Big(1-cos(\omega_0 t)e^{-\frac{1}{2}\Delta^2 t^2}\Big) + 2\frac{\Delta^4}{\omega_0^4}\omega_0\int_0^\tau \sin(\omega_0\tau)e^{-\frac{1}{2}\Delta^2\tau^2}d\tau \Bigg] + +.. attributes:: + +.. properties:: + +.. categories:: From 5868103f80f76603b289d0de43d54bc64db68e81 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Wed, 28 Jan 2015 11:21:24 +0000 Subject: [PATCH 043/275] Re #9556 DKT updating setActiveParameter --- .../Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp index bb8564563d19..2729c173d96c 100644 --- a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp @@ -238,6 +238,12 @@ void DynamicKuboToyabe::setActiveParameter(size_t i, double value) { setParameter( i, fabs(value), false); + if (parameterName(i)=="Nu"){ + if (value<1e-10){ + setParameter(i,0,false); + } + } + } } // namespace CurveFitting From 5079fc94404a4323c0ff72bdc1849475707e862e Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Wed, 28 Jan 2015 11:48:55 +0000 Subject: [PATCH 044/275] Re #9556 DKT unit test --- .../Framework/CurveFitting/CMakeLists.txt | 1 + .../CurveFitting/test/DynamicKuboToyabeTest.h | 108 ++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h diff --git a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt index 93d8e42f046a..f493cf94d865 100644 --- a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt +++ b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt @@ -239,6 +239,7 @@ set ( TEST_FILES DeltaFunctionTest.h DiffRotDiscreteCircleTest.h DiffSphereTest.h + DynamicKuboToyabeTest.h EndErfcTest.h ExpDecayMuonTest.h ExpDecayOscTest.h diff --git a/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h b/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h new file mode 100644 index 000000000000..9331529860ca --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h @@ -0,0 +1,108 @@ +#ifndef DYNAMICKUBOTOYABETEST_H_ +#define DYNAMICKUBOTOYABETEST_H_ + +#include + +#include "MantidCurveFitting/DynamicKuboToyabe.h" +#include "MantidAPI/CompositeFunction.h" +#include "MantidCurveFitting/LinearBackground.h" +#include "MantidCurveFitting/BoundaryConstraint.h" +#include "MantidCurveFitting/Fit.h" +#include "MantidKernel/UnitFactory.h" +#include "MantidAPI/AnalysisDataService.h" +#include "MantidAPI/WorkspaceFactory.h" +#include "MantidAPI/Algorithm.h" +#include "MantidDataObjects/Workspace2D.h" +#include "MantidKernel/Exception.h" +#include "MantidAPI/FunctionFactory.h" + +using namespace Mantid::Kernel; +using namespace Mantid::API; +using namespace Mantid::CurveFitting; +using namespace Mantid::DataObjects; + + +class DynamicKuboToyabeTest : public CxxTest::TestSuite +{ +public: + + void getMockData(Mantid::MantidVec& y, Mantid::MantidVec& e) + { + // Calculated with A = 0.24 and Delta = 0.16 on an Excel spreadsheet + y[0] = 0.24; + y[1] = 0.233921146; + y[2] = 0.216447929; + y[3] = 0.189737312; + y[4] = 0.156970237; + y[5] = 0.121826185; + y[6] = 0.08791249; + y[7] = 0.058260598; + y[8] = 0.034976545; + y[9] = 0.019090369; + + for (int i = 0; i <10; i++) + { + e[i] = 0.01; + } + + } + + void testAgainstMockData() + { + Fit alg2; + TS_ASSERT_THROWS_NOTHING(alg2.initialize()); + TS_ASSERT( alg2.isInitialized() ); + + // create mock data to test against + std::string wsName = "DynamicKuboToyabeData"; + int histogramNumber = 1; + int timechannels = 10; + Workspace_sptr ws = WorkspaceFactory::Instance().create("Workspace2D",histogramNumber,timechannels,timechannels); + Workspace2D_sptr ws2D = boost::dynamic_pointer_cast(ws); + for (int i = 0; i < 10; i++) ws2D->dataX(0)[i] = i; + Mantid::MantidVec& y = ws2D->dataY(0); // y-values (counts) + Mantid::MantidVec& e = ws2D->dataE(0); // error values of counts + getMockData(y, e); + + //put this workspace in the data service + TS_ASSERT_THROWS_NOTHING(AnalysisDataService::Instance().addOrReplace(wsName, ws2D)); + + // set up fitting function +// DynamicKuboToyabe fn; + std::string fnString = "name=DynamicKuboToyabe,ties=(Field=0,Nu=0);"; + IFunction_sptr fn = FunctionFactory::Instance().createInitialized(fnString); + + //alg2.setFunction(fn); + TS_ASSERT_THROWS_NOTHING(alg2.setProperty("Function",fnString)); + + // Set which spectrum to fit against and initial starting values + TS_ASSERT_THROWS_NOTHING(alg2.setPropertyValue("InputWorkspace", wsName)); + TS_ASSERT_THROWS_NOTHING(alg2.setPropertyValue("WorkspaceIndex","0")); + TS_ASSERT_THROWS_NOTHING(alg2.setPropertyValue("StartX","0")); + TS_ASSERT_THROWS_NOTHING(alg2.setPropertyValue("EndX","17")); + + fn->applyTies(); + // execute fit + TS_ASSERT_THROWS_NOTHING( + TS_ASSERT( alg2.execute() ) + ) + + TS_ASSERT( alg2.isExecuted() ); + + auto out = FunctionFactory::Instance().createInitialized(alg2.getPropertyValue("Function")); + TS_ASSERT_DELTA( out->getParameter("Asym"), 0.238 ,0.001); + TS_ASSERT_DELTA( out->getParameter("Delta"), 0.157 ,0.001); + + // check its categories + const std::vector categories = out->categories(); + TS_ASSERT( categories.size() == 1 ); + TS_ASSERT( categories[0] == "Muon" ); + + AnalysisDataService::Instance().remove(wsName); + + } + + +}; + +#endif /*DYNAMICKUBOTOYABETEST_H_*/ From 605309210a73e32affc300ee4fcc88ea1e52e2c3 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Wed, 28 Jan 2015 16:26:52 +0000 Subject: [PATCH 045/275] Re #10886 Recover lost change in dead time type --- .../CustomDialogs/src/PlotAsymmetryByLogValueDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Mantid/MantidQt/CustomDialogs/src/PlotAsymmetryByLogValueDialog.cpp b/Code/Mantid/MantidQt/CustomDialogs/src/PlotAsymmetryByLogValueDialog.cpp index 4e14e4a4bca5..3d6fe444ee56 100644 --- a/Code/Mantid/MantidQt/CustomDialogs/src/PlotAsymmetryByLogValueDialog.cpp +++ b/Code/Mantid/MantidQt/CustomDialogs/src/PlotAsymmetryByLogValueDialog.cpp @@ -215,5 +215,5 @@ void PlotAsymmetryByLogValueDialog::fillLogBox(const QString&) void PlotAsymmetryByLogValueDialog::showHideDeadTimeFileWidget(int deadTimeTypeIndex) { // Show only if "Using specified file" selected - m_uiForm.dtcFileContainer->setVisible(deadTimeTypeIndex == 1); + m_uiForm.dtcFileContainer->setVisible(deadTimeTypeIndex == 2); } From b977abd27292f4937e4ec55d0a124740158e80c1 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Thu, 29 Jan 2015 15:35:42 +0000 Subject: [PATCH 046/275] Re #9556 Unit test testing function not fitting --- .../CurveFitting/test/DynamicKuboToyabeTest.h | 176 ++++++++++-------- 1 file changed, 97 insertions(+), 79 deletions(-) diff --git a/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h b/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h index 9331529860ca..490f07fd4d67 100644 --- a/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h @@ -4,102 +4,120 @@ #include #include "MantidCurveFitting/DynamicKuboToyabe.h" -#include "MantidAPI/CompositeFunction.h" -#include "MantidCurveFitting/LinearBackground.h" -#include "MantidCurveFitting/BoundaryConstraint.h" -#include "MantidCurveFitting/Fit.h" -#include "MantidKernel/UnitFactory.h" -#include "MantidAPI/AnalysisDataService.h" -#include "MantidAPI/WorkspaceFactory.h" -#include "MantidAPI/Algorithm.h" -#include "MantidDataObjects/Workspace2D.h" -#include "MantidKernel/Exception.h" -#include "MantidAPI/FunctionFactory.h" +#include "MantidCurveFitting/StaticKuboToyabe.h" +#include "MantidAPI/FunctionDomain1D.h" +#include "MantidAPI/FunctionValues.h" +//#include "MantidAPI/CompositeFunction.h" +//#include "MantidCurveFitting/LinearBackground.h" +//#include "MantidCurveFitting/BoundaryConstraint.h" +//#include "MantidCurveFitting/Fit.h" +//#include "MantidKernel/UnitFactory.h" +//#include "MantidAPI/AnalysisDataService.h" +//#include "MantidAPI/WorkspaceFactory.h" +//#include "MantidAPI/Algorithm.h" +//#include "MantidDataObjects/Workspace2D.h" +//#include "MantidKernel/Exception.h" +//#include "MantidAPI/FunctionFactory.h" using namespace Mantid::Kernel; using namespace Mantid::API; using namespace Mantid::CurveFitting; -using namespace Mantid::DataObjects; +//using namespace Mantid::DataObjects; class DynamicKuboToyabeTest : public CxxTest::TestSuite { public: - void getMockData(Mantid::MantidVec& y, Mantid::MantidVec& e) + void testZFZNDKTFunction() { - // Calculated with A = 0.24 and Delta = 0.16 on an Excel spreadsheet - y[0] = 0.24; - y[1] = 0.233921146; - y[2] = 0.216447929; - y[3] = 0.189737312; - y[4] = 0.156970237; - y[5] = 0.121826185; - y[6] = 0.08791249; - y[7] = 0.058260598; - y[8] = 0.034976545; - y[9] = 0.019090369; - - for (int i = 0; i <10; i++) + // Test Dynamic Kubo Toyabe (DKT) for Zero Field (ZF) and Zero Nu (ZN) + // Function values must match exactly values from the Static Kubo Toyabe + const double asym = 1.0; + const double delta = 0.39; + const double field = 0; + const double nu = 0.0; + + DynamicKuboToyabe dkt; + dkt.initialize(); + dkt.setParameter("Asym", asym); + dkt.setParameter("Delta",delta ); + dkt.setParameter("Field",field); + dkt.setParameter("Nu", nu); + + StaticKuboToyabe skt; + skt.initialize(); + skt.setParameter("A", asym); + skt.setParameter("Delta", delta); + + // define 1d domain of 10 points in interval [0,10] + Mantid::API::FunctionDomain1DVector x(0,10,10); + Mantid::API::FunctionValues y1(x); + Mantid::API::FunctionValues y2(x); + + dkt.function(x,y1); + skt.function(x,y2); + + for(size_t i = 0; i < x.size(); ++i) { - e[i] = 0.01; + TS_ASSERT_DELTA( y1[i], y2[i], 1e-6 ); } - } - void testAgainstMockData() + void testZFDKTFunction() { - Fit alg2; - TS_ASSERT_THROWS_NOTHING(alg2.initialize()); - TS_ASSERT( alg2.isInitialized() ); - - // create mock data to test against - std::string wsName = "DynamicKuboToyabeData"; - int histogramNumber = 1; - int timechannels = 10; - Workspace_sptr ws = WorkspaceFactory::Instance().create("Workspace2D",histogramNumber,timechannels,timechannels); - Workspace2D_sptr ws2D = boost::dynamic_pointer_cast(ws); - for (int i = 0; i < 10; i++) ws2D->dataX(0)[i] = i; - Mantid::MantidVec& y = ws2D->dataY(0); // y-values (counts) - Mantid::MantidVec& e = ws2D->dataE(0); // error values of counts - getMockData(y, e); - - //put this workspace in the data service - TS_ASSERT_THROWS_NOTHING(AnalysisDataService::Instance().addOrReplace(wsName, ws2D)); - - // set up fitting function -// DynamicKuboToyabe fn; - std::string fnString = "name=DynamicKuboToyabe,ties=(Field=0,Nu=0);"; - IFunction_sptr fn = FunctionFactory::Instance().createInitialized(fnString); - - //alg2.setFunction(fn); - TS_ASSERT_THROWS_NOTHING(alg2.setProperty("Function",fnString)); - - // Set which spectrum to fit against and initial starting values - TS_ASSERT_THROWS_NOTHING(alg2.setPropertyValue("InputWorkspace", wsName)); - TS_ASSERT_THROWS_NOTHING(alg2.setPropertyValue("WorkspaceIndex","0")); - TS_ASSERT_THROWS_NOTHING(alg2.setPropertyValue("StartX","0")); - TS_ASSERT_THROWS_NOTHING(alg2.setPropertyValue("EndX","17")); - - fn->applyTies(); - // execute fit - TS_ASSERT_THROWS_NOTHING( - TS_ASSERT( alg2.execute() ) - ) - - TS_ASSERT( alg2.isExecuted() ); - - auto out = FunctionFactory::Instance().createInitialized(alg2.getPropertyValue("Function")); - TS_ASSERT_DELTA( out->getParameter("Asym"), 0.238 ,0.001); - TS_ASSERT_DELTA( out->getParameter("Delta"), 0.157 ,0.001); - - // check its categories - const std::vector categories = out->categories(); - TS_ASSERT( categories.size() == 1 ); - TS_ASSERT( categories[0] == "Muon" ); - - AnalysisDataService::Instance().remove(wsName); + // Test Dynamic Kubo Toyabe (DKT) for Zero Field (ZF) (non-zero Nu) + const double asym = 1.0; + const double delta = 0.39; + const double field = 0; + const double nu = 1.0; + + DynamicKuboToyabe dkt; + dkt.initialize(); + dkt.setParameter("Asym", asym); + dkt.setParameter("Delta",delta ); + dkt.setParameter("Field",field); + dkt.setParameter("Nu", nu); + + // define 1d domain of 5 points in interval [0,5] + Mantid::API::FunctionDomain1DVector x(0,5,5); + Mantid::API::FunctionValues y(x); + + dkt.function(x,y); + + TS_ASSERT_DELTA( y[0], 1.000000, 0.000001); + TS_ASSERT_DELTA( y[1], 0.849898, 0.000001); + TS_ASSERT_DELTA( y[2], 0.621963, 0.000001); + TS_ASSERT_DELTA( y[3], 0.443612, 0.000001); + TS_ASSERT_DELTA( y[4], 0.317374, 0.000001); + } + void testDKTFunction() + { + // Test Dynamic Kubo Toyabe (DKT) (non-zero Field, non-zero Nu) + const double asym = 1.0; + const double delta = 0.39; + const double field = 0.1; + const double nu = 0.5; + + DynamicKuboToyabe dkt; + dkt.initialize(); + dkt.setParameter("Asym", asym); + dkt.setParameter("Delta",delta ); + dkt.setParameter("Field",field); + dkt.setParameter("Nu", nu); + + // define 1d domain of 5 points in interval [0,5] + Mantid::API::FunctionDomain1DVector x(0,5,5); + Mantid::API::FunctionValues y(x); + + dkt.function(x,y); + + TS_ASSERT_DELTA( y[0], 1.000000, 0.000001); + TS_ASSERT_DELTA( y[1], 0.816422, 0.000001); + TS_ASSERT_DELTA( y[2], 0.503185, 0.000001); + TS_ASSERT_DELTA( y[3], 0.274738, 0.000001); + TS_ASSERT_DELTA( y[4], 0.152792, 0.000001); } From 06a5cb2fc14eb76dc3f9fdf0100eab2ca4f9d35c Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Thu, 29 Jan 2015 16:40:10 +0000 Subject: [PATCH 047/275] Re #9556 Fitting function improvements --- .../CurveFitting/src/DynamicKuboToyabe.cpp | 94 ++++++++++--------- 1 file changed, 50 insertions(+), 44 deletions(-) diff --git a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp index 2729c173d96c..5a42e851af01 100644 --- a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp @@ -5,7 +5,8 @@ #include "MantidAPI/Jacobian.h" #include "MantidAPI/FunctionFactory.h" #include -#include // TODO Remove +#include +//#include // TODO Remove #define EPS 1e-6 #define JMAX 14 @@ -40,35 +41,21 @@ void DynamicKuboToyabe::init() declareParameter("Delta", 0.2, "Local field"); declareParameter("Field", 0.0, "External field"); declareParameter("Nu", 0.0, "Hopping rate"); - //declareParameter("EndX",15); } //------------------------------------------------------------------------------------------------ -double *vector(long nl, long nh) -/* allocate a double vector with subscript range v[nl..nh] */ -{ - double *v; +// Routines from Numerical Recipes - v=(double *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(double))); - if (!v) throw std::runtime_error("allocation failure in dvector()"); - return v-nl+NR_END; -} -void free_vector(double *v, long nl, long nh) -/* free a double vector allocated with dvector() */ -{ - free((FREE_ARG) (v+nl-NR_END)); -} double midpnt(double func(const double, const double, const double), const double a, const double b, const int n, const double g, const double w0) { // quote & modified from numerical recipe 2nd edtion (page147) static double s; - if (n==1) { - double s1 = 0.5*(b-a)*func(a,g,w0)+func(b,g,w0); - double s2 = (b-a)*func(0.5*(a+b),g,w0); - return (s2); + if (n==1) { + double s1 = (b-a)*func(0.5*(a+b),g,w0); + return (s1); } else { double x, tnm, sum, del, ddel; int it, j; @@ -93,11 +80,9 @@ void polint (double xa[], double ya[], int n, double x, double& y, double& dy) { int i, m, ns = 1; double den, dif, dift, ho, hp, w; - double *c,*d; - dif = fabs(x-xa[1]); - c = vector(1,n); - d = vector(1,n); + std::vector c(n+1); + std::vector d(n+1); for (i=1;i<=n;i++){ if((dift=fabs(x-xa[i]))2.0*G) { w0 = 2*3.1415926*0.01355342*F ;} else { w0 =2*3.1415926*0.01355342*2.0*G; } + // Non-zero field + + if (F>2.0*G) { + w0 = 2*3.1415926*0.01355342*F ; + } else { + w0 =2*3.1415926*0.01355342*2.0*G; + } double p = G*G/(w0*w0); double HKT = 1.0-2.0*p*(1-exp(-q/2.0)*cos(w0*x))+2.0*p*p*w0*integrate(f1,0.0,x,G,w0); @@ -179,7 +170,7 @@ double gz (const double x, const double G, const double F) } } -// Original function by mark telling +// Dynamic Kubo Toyabe function void DynamicKuboToyabe::function1D(double* out, const double* xValues, const size_t nData)const { const double& A = getParameter("Asym"); @@ -197,20 +188,41 @@ void DynamicKuboToyabe::function1D(double* out, const double* xValues, const siz // Non-zero hopping rate else { - const int n = 1000; + + // Make sure stepsize is smaller than spacing between xValues + int n = 1000; + //while (n funcG(n); + + // Mark's implementation for (int i = 0; i < n; i++) { - double Integral=0.0; - for (int c = 1; c <= i; c++) { - Integral= gz(c*stepsize,G,F)*exp(-v*c*stepsize)*funcG[i-c]*(stepsize) + Integral; + double efac1=exp(-v*stepsize); // survival prob for step + double efac2=(1.0-efac1); // hop prob ~ hoprate*step + + funcG[0]=gz(0,G,F); + funcG[1]=gz(stepsize,G,F); + + for(i=1; i Date: Fri, 30 Jan 2015 08:34:39 +0000 Subject: [PATCH 048/275] Re #9556 Removing unnecessary includes --- .../CurveFitting/test/DynamicKuboToyabeTest.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h b/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h index 490f07fd4d67..52cc405feda5 100644 --- a/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h @@ -7,22 +7,10 @@ #include "MantidCurveFitting/StaticKuboToyabe.h" #include "MantidAPI/FunctionDomain1D.h" #include "MantidAPI/FunctionValues.h" -//#include "MantidAPI/CompositeFunction.h" -//#include "MantidCurveFitting/LinearBackground.h" -//#include "MantidCurveFitting/BoundaryConstraint.h" -//#include "MantidCurveFitting/Fit.h" -//#include "MantidKernel/UnitFactory.h" -//#include "MantidAPI/AnalysisDataService.h" -//#include "MantidAPI/WorkspaceFactory.h" -//#include "MantidAPI/Algorithm.h" -//#include "MantidDataObjects/Workspace2D.h" -//#include "MantidKernel/Exception.h" -//#include "MantidAPI/FunctionFactory.h" using namespace Mantid::Kernel; using namespace Mantid::API; using namespace Mantid::CurveFitting; -//using namespace Mantid::DataObjects; class DynamicKuboToyabeTest : public CxxTest::TestSuite From fb46f0e48eaee8628548678550c1f08a98b4538d Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Fri, 30 Jan 2015 08:42:08 +0000 Subject: [PATCH 049/275] Re #9556 removing math --- Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp index 5a42e851af01..54811c7ea9a1 100644 --- a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp @@ -4,9 +4,7 @@ #include "MantidCurveFitting/DynamicKuboToyabe.h" #include "MantidAPI/Jacobian.h" #include "MantidAPI/FunctionFactory.h" -#include #include -//#include // TODO Remove #define EPS 1e-6 #define JMAX 14 @@ -22,7 +20,6 @@ namespace CurveFitting using namespace Kernel; using namespace API; -using namespace boost::math; DECLARE_FUNCTION(DynamicKuboToyabe) From 257ba6d75666e1106da7968b90949c9930bf70be Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Fri, 30 Jan 2015 08:48:55 +0000 Subject: [PATCH 050/275] Re #9556 fixing cpp checks --- .../Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp index 54811c7ea9a1..e3005d9c51c0 100644 --- a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp @@ -48,7 +48,6 @@ double midpnt(double func(const double, const double, const double), const double a, const double b, const int n, const double g, const double w0) { // quote & modified from numerical recipe 2nd edtion (page147) - static double s; if (n==1) { double s1 = (b-a)*func(0.5*(a+b),g,w0); @@ -68,6 +67,7 @@ double midpnt(double func(const double, const double, const double), sum += func(x,g,w0); x += del; } + static double s; s=(s+(b-a)*sum/tnm)/3.0; return s; } @@ -75,12 +75,13 @@ double midpnt(double func(const double, const double, const double), void polint (double xa[], double ya[], int n, double x, double& y, double& dy) { int i, m, ns = 1; - double den, dif, dift, ho, hp, w; + double dif; dif = fabs(x-xa[1]); std::vector c(n+1); std::vector d(n+1); for (i=1;i<=n;i++){ + double dift; if((dift=fabs(x-xa[i])) Date: Fri, 30 Jan 2015 09:10:21 +0000 Subject: [PATCH 051/275] Re #9556 remove unit test temporarily --- Code/Mantid/Framework/CurveFitting/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt index f493cf94d865..93d8e42f046a 100644 --- a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt +++ b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt @@ -239,7 +239,6 @@ set ( TEST_FILES DeltaFunctionTest.h DiffRotDiscreteCircleTest.h DiffSphereTest.h - DynamicKuboToyabeTest.h EndErfcTest.h ExpDecayMuonTest.h ExpDecayOscTest.h From f4d713c85eb1b344541189658a9416fb5a8807ab Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Fri, 30 Jan 2015 10:35:11 +0000 Subject: [PATCH 052/275] Re #9556 Enabling some unit tests --- Code/Mantid/Framework/CurveFitting/CMakeLists.txt | 1 + .../CurveFitting/test/DynamicKuboToyabeTest.h | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt index 93d8e42f046a..f493cf94d865 100644 --- a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt +++ b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt @@ -239,6 +239,7 @@ set ( TEST_FILES DeltaFunctionTest.h DiffRotDiscreteCircleTest.h DiffSphereTest.h + DynamicKuboToyabeTest.h EndErfcTest.h ExpDecayMuonTest.h ExpDecayOscTest.h diff --git a/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h b/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h index 52cc405feda5..efddce67e31f 100644 --- a/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h @@ -43,8 +43,8 @@ class DynamicKuboToyabeTest : public CxxTest::TestSuite Mantid::API::FunctionValues y1(x); Mantid::API::FunctionValues y2(x); - dkt.function(x,y1); - skt.function(x,y2); + TS_ASSERT_THROWS_NOTHING(dkt.function(x,y1)); + TS_ASSERT_THROWS_NOTHING(skt.function(x,y2)); for(size_t i = 0; i < x.size(); ++i) { @@ -71,7 +71,7 @@ class DynamicKuboToyabeTest : public CxxTest::TestSuite Mantid::API::FunctionDomain1DVector x(0,5,5); Mantid::API::FunctionValues y(x); - dkt.function(x,y); + TS_ASSERT_THROWS_NOTHING(dkt.function(x,y)); TS_ASSERT_DELTA( y[0], 1.000000, 0.000001); TS_ASSERT_DELTA( y[1], 0.849898, 0.000001); @@ -80,7 +80,7 @@ class DynamicKuboToyabeTest : public CxxTest::TestSuite TS_ASSERT_DELTA( y[4], 0.317374, 0.000001); } - void testDKTFunction() + void xtestDKTFunction() { // Test Dynamic Kubo Toyabe (DKT) (non-zero Field, non-zero Nu) const double asym = 1.0; @@ -99,7 +99,7 @@ class DynamicKuboToyabeTest : public CxxTest::TestSuite Mantid::API::FunctionDomain1DVector x(0,5,5); Mantid::API::FunctionValues y(x); - dkt.function(x,y); + TS_ASSERT_THROWS_NOTHING(dkt.function(x,y)); TS_ASSERT_DELTA( y[0], 1.000000, 0.000001); TS_ASSERT_DELTA( y[1], 0.816422, 0.000001); From 29c2b33a5e709a7b58e0376d9891cfa2e63e5ca0 Mon Sep 17 00:00:00 2001 From: Anton Piccardo-Selg Date: Fri, 30 Jan 2015 11:02:39 +0000 Subject: [PATCH 053/275] Refs #10627 Check input values for min and max --- .../API/inc/MantidQtAPI/MdConstants.h | 5 +- Code/Mantid/MantidQt/API/src/MdConstants.cpp | 8 +- .../ColorSelectionWidget.h | 15 ++- .../ViewWidgets/src/ColorSelectionWidget.cpp | 98 ++++++++++++++++++- .../ViewWidgets/src/ColorUpdater.cpp | 2 +- 5 files changed, 119 insertions(+), 9 deletions(-) diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdConstants.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdConstants.h index cd8b5d46a29e..1561750bc510 100644 --- a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdConstants.h +++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdConstants.h @@ -44,9 +44,12 @@ namespace MantidQt double getColorScaleStandardMax(); + double getLogScaleDefaultValue(); + private: - double m_colorScaleStandardMax; + const double m_colorScaleStandardMax; + const double m_logScaleDefaultValue; }; } } diff --git a/Code/Mantid/MantidQt/API/src/MdConstants.cpp b/Code/Mantid/MantidQt/API/src/MdConstants.cpp index 11073af78c83..680269da3247 100644 --- a/Code/Mantid/MantidQt/API/src/MdConstants.cpp +++ b/Code/Mantid/MantidQt/API/src/MdConstants.cpp @@ -4,7 +4,7 @@ namespace MantidQt { namespace API { - MdConstants::MdConstants() : m_colorScaleStandardMax(0.1) + MdConstants::MdConstants() : m_colorScaleStandardMax(0.1), m_logScaleDefaultValue(0.1) { }; @@ -14,5 +14,11 @@ namespace MantidQt { return m_colorScaleStandardMax; } + + double MdConstants::getLogScaleDefaultValue() + + { + return m_logScaleDefaultValue; + } } } diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h index 4316c0cd0a04..1499fd57a988 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h @@ -3,13 +3,14 @@ #include "ui_ColorSelectionWidget.h" #include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h" - +#include "MantidQtAPI/MdConstants.h" #include class pqColorMapModel; class pqColorPresetManager; class pqColorPresetModel; class vtkPVXMLParser; +class QDoubleValidator; namespace Mantid { @@ -116,6 +117,18 @@ protected slots: void loadBuiltinColorPresets(); /// Set status of the color selection editor widgets. void setEditorStatus(bool status); + /// Set up the behaviour for with or without log scale. + void setupLogScale(int state); + /// Set min smaller max + void setMinSmallerMax(double& min, double& max); + + QDoubleValidator* m_minValidator; + QDoubleValidator* m_maxValidator; + + double m_minHistoric; + double m_maxHistoric; + + MantidQt::API::MdConstants m_mdConstants; pqColorPresetManager *presets; ///< Dialog for choosing color presets Ui::ColorSelectionWidgetClass ui; ///< The mode control widget's UI form diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionWidget.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionWidget.cpp index 492b169c0054..e18b9656b2b8 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionWidget.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionWidget.cpp @@ -1,6 +1,7 @@ #include "MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h" #include "MantidKernel/ConfigService.h" +#include "MantidQtAPI/MdConstants.h" #include #include @@ -16,6 +17,7 @@ #include #include +#include namespace Mantid { @@ -29,7 +31,7 @@ namespace SimpleGui * sub-components and connections. * @param parent the parent widget of the mode control widget */ -ColorSelectionWidget::ColorSelectionWidget(QWidget *parent) : QWidget(parent) + ColorSelectionWidget::ColorSelectionWidget(QWidget *parent) : QWidget(parent), m_minHistoric(0.01), m_maxHistoric(0.01) { this->ui.setupUi(this); this->ui.autoColorScaleCheckBox->setChecked(true); @@ -40,8 +42,11 @@ ColorSelectionWidget::ColorSelectionWidget(QWidget *parent) : QWidget(parent) this->loadBuiltinColorPresets(); - this->ui.maxValLineEdit->setValidator(new QDoubleValidator(this)); - this->ui.minValLineEdit->setValidator(new QDoubleValidator(this)); + m_minValidator = new QDoubleValidator(this); + m_maxValidator = new QDoubleValidator(this); + + this->ui.maxValLineEdit->setValidator(m_minValidator); + this->ui.minValLineEdit->setValidator(m_maxValidator); QObject::connect(this->ui.autoColorScaleCheckBox, SIGNAL(stateChanged(int)), this, SLOT(autoOrManualScaling(int))); @@ -166,8 +171,6 @@ void ColorSelectionWidget::autoOrManualScaling(int state) emit this->autoScale(this); break; } - - } /** @@ -196,8 +199,18 @@ void ColorSelectionWidget::loadPreset() */ void ColorSelectionWidget::getColorScaleRange() { + if (this->ui.useLogScaleCheckBox->isChecked()) + { + setupLogScale(true); + } + else + { + setupLogScale(false); + } + double min = this->ui.minValLineEdit->text().toDouble(); double max = this->ui.maxValLineEdit->text().toDouble(); + emit this->colorScaleChanged(min, max); } @@ -210,6 +223,9 @@ void ColorSelectionWidget::setColorScaleRange(double min, double max) { if (this->ui.autoColorScaleCheckBox->isChecked()) { + m_minHistoric = min; + m_maxHistoric = max; + this->ui.minValLineEdit->clear(); this->ui.minValLineEdit->insert(QString::number(min)); this->ui.maxValLineEdit->clear(); @@ -233,9 +249,56 @@ void ColorSelectionWidget::useLogScaling(int state) { state -= 1; } + + // Set up values for with or without log scale + getColorScaleRange(); + emit this->logScale(state); } +/** + * Set up the min and max values and validators for use with or without log scaling + * @param state The state of the log scale, where 0 is no log scale + */ +void ColorSelectionWidget::setupLogScale(int state) +{ + // Get the min and max values + double min = this->ui.minValLineEdit->text().toDouble(); + double max = this->ui.maxValLineEdit->text().toDouble(); + + // Make sure that the minimum is smaller or equal to the maximum + setMinSmallerMax(min, max); + + // If we switched to a log state make sure that values are larger than 0 + if (state) + { + if (min <= 0 ) + { + min = m_mdConstants.getLogScaleDefaultValue(); + } + + if (max <= 0) + { + max = m_mdConstants.getLogScaleDefaultValue(); + } + } + + // If min and max were changed we need to persist this + setMinSmallerMax(min, max); + + // Set the validators + if (state) + { + m_maxValidator->setBottom(0.0); + m_minValidator->setBottom(0.0); + } + else + { + m_maxValidator->setBottom(-DBL_MAX); + m_minValidator->setBottom(-DBL_MAX); + } +} + /** * Slot to set the checkbox if the logscaling behaviour has been set programatically * @param state Flag whether the checkbox should be checked or not @@ -245,6 +308,30 @@ void ColorSelectionWidget::onSetLogScale(bool state) ui.useLogScaleCheckBox->setChecked(state); } +/** + * Make sure that min is smaller/equal than max. If not then set to the old value. + * @param max The maximum value. + * @param min The minimum value. + */ +void ColorSelectionWidget::setMinSmallerMax(double& min, double& max) +{ + if (min <= max) + { + m_minHistoric = min; + m_maxHistoric = max; + } + else + { + min = m_minHistoric; + max = m_maxHistoric; + } + + this->ui.minValLineEdit->clear(); + this->ui.minValLineEdit->insert(QString::number(min)); + this->ui.maxValLineEdit->clear(); + this->ui.maxValLineEdit->insert(QString::number(max)); +} + /** * This function sets the state for all of the controls on the color selection * widget. @@ -304,6 +391,7 @@ bool ColorSelectionWidget::getLogScaleState() { state -= 1; } + return static_cast(state); } diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp index adcf679791a6..b4f2b3b34e8c 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp @@ -170,7 +170,7 @@ void ColorUpdater::updateLookupTable(pqDataRepresentation* representation) // Need to set a lookup table lock here. This does not affect setScalarRange, // but blocks setWholeScalarRange which gets called by ParaView overrides our // setting when a workspace is loaded for the first time. - lookupTable->setScalarRangeLock(TRUE); + lookupTable->setScalarRangeLock(true); representation->getProxy()->UpdateVTKObjects(); representation->renderViewEventually(); From 1fa60d864765d9efdc6f090bfb02a78bc24869bd Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Fri, 30 Jan 2015 12:46:14 +0000 Subject: [PATCH 054/275] Re #9556 Some bugs fixed and unit test updated --- .../CurveFitting/src/DynamicKuboToyabe.cpp | 10 ++--- .../CurveFitting/test/DynamicKuboToyabeTest.h | 38 ++++++++++++++++--- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp index e3005d9c51c0..f28e0f075a8e 100644 --- a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp @@ -48,10 +48,11 @@ double midpnt(double func(const double, const double, const double), const double a, const double b, const int n, const double g, const double w0) { // quote & modified from numerical recipe 2nd edtion (page147) + static double s; if (n==1) { - double s1 = (b-a)*func(0.5*(a+b),g,w0); - return (s1); + s = (b-a)*func(0.5*(a+b),g,w0); + return (s); } else { double x, tnm, sum, del, ddel; int it, j; @@ -67,7 +68,6 @@ double midpnt(double func(const double, const double, const double), sum += func(x,g,w0); x += del; } - static double s; s=(s+(b-a)*sum/tnm)/3.0; return s; } @@ -114,8 +114,8 @@ double integrate (double func(const double, const double, const double), int j; double ss,dss; double h[JMAXP+1], s[JMAXP]; - - h[0] = 1.0; + + h[1] = 1.0; for (j=1; j<= JMAX; j++) { s[j]=midpnt(func,a,b,j,g,w0); if (j >= K) { diff --git a/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h b/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h index efddce67e31f..0eaef5a0d20d 100644 --- a/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/DynamicKuboToyabeTest.h @@ -80,7 +80,35 @@ class DynamicKuboToyabeTest : public CxxTest::TestSuite TS_ASSERT_DELTA( y[4], 0.317374, 0.000001); } - void xtestDKTFunction() + void testZNDKTFunction() + { + // Test Dynamic Kubo Toyabe (DKT) for non-zero Field and Zero Nu (ZN) + const double asym = 1.0; + const double delta = 0.39; + const double field = 0.1; + const double nu = 0.0; + + DynamicKuboToyabe dkt; + dkt.initialize(); + dkt.setParameter("Asym", asym); + dkt.setParameter("Delta",delta ); + dkt.setParameter("Field",field); + dkt.setParameter("Nu", nu); + + // define 1d domain of 5 points in interval [0,5] + Mantid::API::FunctionDomain1DVector x(0,5,5); + Mantid::API::FunctionValues y(x); + + TS_ASSERT_THROWS_NOTHING(dkt.function(x,y)); + + TS_ASSERT_DELTA( y[0], 1.000000, 0.000001); + TS_ASSERT_DELTA( y[1], 0.784636, 0.000001); + TS_ASSERT_DELTA( y[2], 0.353978, 0.000001); + TS_ASSERT_DELTA( y[3], 0.073286, 0.000001); + TS_ASSERT_DELTA( y[4], 0.055052, 0.000001); + } + + void testDKTFunction() { // Test Dynamic Kubo Toyabe (DKT) (non-zero Field, non-zero Nu) const double asym = 1.0; @@ -102,10 +130,10 @@ class DynamicKuboToyabeTest : public CxxTest::TestSuite TS_ASSERT_THROWS_NOTHING(dkt.function(x,y)); TS_ASSERT_DELTA( y[0], 1.000000, 0.000001); - TS_ASSERT_DELTA( y[1], 0.816422, 0.000001); - TS_ASSERT_DELTA( y[2], 0.503185, 0.000001); - TS_ASSERT_DELTA( y[3], 0.274738, 0.000001); - TS_ASSERT_DELTA( y[4], 0.152792, 0.000001); + TS_ASSERT_DELTA( y[1], 0.822498, 0.000001); + TS_ASSERT_DELTA( y[2], 0.518536, 0.000001); + TS_ASSERT_DELTA( y[3], 0.295988, 0.000001); + TS_ASSERT_DELTA( y[4], 0.175489, 0.000001); } From 96e3a4c2482ff2d39a10084b4a61d716ce7aeaad Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Mon, 2 Feb 2015 08:16:21 +0000 Subject: [PATCH 055/275] Re #9556 Fixing title overline in rst --- Code/Mantid/docs/source/fitfunctions/DynamicKuboToyabe.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Mantid/docs/source/fitfunctions/DynamicKuboToyabe.rst b/Code/Mantid/docs/source/fitfunctions/DynamicKuboToyabe.rst index 206be446c5e1..85aeb26ddd97 100644 --- a/Code/Mantid/docs/source/fitfunctions/DynamicKuboToyabe.rst +++ b/Code/Mantid/docs/source/fitfunctions/DynamicKuboToyabe.rst @@ -1,8 +1,8 @@ .. _func-DynamicKuboToyabe: -================ +================= DynamicKuboToyabe -================ +================= .. index:: DynamicKuboToyabe From f21317e6df5442a2c8cd0fc8bd9760627a59b934 Mon Sep 17 00:00:00 2001 From: Tobias Richter Date: Mon, 2 Feb 2015 15:48:19 +0100 Subject: [PATCH 056/275] add python-sphinx-bootstrap-theme That would require a version bump, but I've yet to understand this versioned directory hierarchy. --- .../deb/mantid-developer/mantid-developer-1.2.3/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Mantid/Build/dev-packages/deb/mantid-developer/mantid-developer-1.2.3/DEBIAN/control b/Code/Mantid/Build/dev-packages/deb/mantid-developer/mantid-developer-1.2.3/DEBIAN/control index b8a48ac71c23..5d0abce474b7 100644 --- a/Code/Mantid/Build/dev-packages/deb/mantid-developer/mantid-developer-1.2.3/DEBIAN/control +++ b/Code/Mantid/Build/dev-packages/deb/mantid-developer/mantid-developer-1.2.3/DEBIAN/control @@ -3,7 +3,7 @@ Version: 1.2.3 Section: main Priority: optional Architecture: all -Depends: git, clang, cmake-qt-gui(>=2.8.12), qt4-qmake, qt4-dev-tools, libqt4-dbg, libpoco-dev(>=1.4.2), libboost-all-dev, libboost-dbg, libnexus0-dev, libgoogle-perftools-dev, libqwt5-qt4-dev, libqwtplot3d-qt4-dev, python-qt4-dev, libgsl0-dev, liboce-visualization-dev, libmuparser-dev, python-numpy, libssl-dev, libqscintilla2-dev, texlive,texlive-latex-extra, dvipng, libhdf4-dev, doxygen, python-sphinx, python-scipy, ipython-qtconsole (>=1.2.0), libhdf5-dev, libhdf4-dev, libpococrypto11-dbg, libpocodata11-dbg, libpocofoundation11-dbg, libpocomysql11-dbg, libpoconet11-dbg, libpoconetssl11-dbg, libpocoodbc11-dbg, libpocosqlite11-dbg, libpocoutil11-dbg, libpocoxml11-dbg, libpocozip11-dbg, python-qt4-dbg, qt4-default, ninja-build, libjsoncpp-dev, python-dateutil +Depends: git, clang, cmake-qt-gui(>=2.8.12), qt4-qmake, qt4-dev-tools, libqt4-dbg, libpoco-dev(>=1.4.2), libboost-all-dev, libboost-dbg, libnexus0-dev, libgoogle-perftools-dev, libqwt5-qt4-dev, libqwtplot3d-qt4-dev, python-qt4-dev, libgsl0-dev, liboce-visualization-dev, libmuparser-dev, python-numpy, libssl-dev, libqscintilla2-dev, texlive, texlive-latex-extra, dvipng, libhdf4-dev, doxygen, python-sphinx, python-scipy, ipython-qtconsole (>=1.2.0), libhdf5-dev, libhdf4-dev, libpococrypto11-dbg, libpocodata11-dbg, libpocofoundation11-dbg, libpocomysql11-dbg, libpoconet11-dbg, libpoconetssl11-dbg, libpocoodbc11-dbg, libpocosqlite11-dbg, libpocoutil11-dbg, libpocoxml11-dbg, libpocozip11-dbg, python-qt4-dbg, qt4-default, ninja-build, libjsoncpp-dev, python-dateutil, python-sphinx-bootstrap-theme Installed-Size: 0 Maintainer: Mantid Project Description: Installs all packages required for a Mantid developer From 181786d098a396955fb749343bd495fff104543b Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Thu, 5 Feb 2015 10:02:08 +0000 Subject: [PATCH 057/275] Moved indirect algo out of workflow folder Removed Start/EndTime function calls Refs #11015 --- .../{WorkflowAlgorithms => }/IndirectTransmission.py | 6 ------ 1 file changed, 6 deletions(-) rename Code/Mantid/Framework/PythonInterface/plugins/algorithms/{WorkflowAlgorithms => }/IndirectTransmission.py (98%) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectTransmission.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/IndirectTransmission.py similarity index 98% rename from Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectTransmission.py rename to Code/Mantid/Framework/PythonInterface/plugins/algorithms/IndirectTransmission.py index defedca18768..f708e716043e 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectTransmission.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/IndirectTransmission.py @@ -60,10 +60,6 @@ def PyInit(self): def PyExec(self): - from IndirectCommon import StartTime, EndTime - - StartTime('IndirectTransmission') - instrument_name = self.getPropertyValue('Instrument') analyser = self.getPropertyValue('Analyser') reflection = self.getPropertyValue('Reflection') @@ -150,8 +146,6 @@ def PyExec(self): self.setProperty("OutputWorkspace", table_ws) - EndTime('IndirectTransmission') - def _create_instrument_workspace(self, instrument_name): """ From 11d85e6a37f0eb9cd5afd4d005d9d0066a85df44 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Thu, 5 Feb 2015 10:48:58 +0000 Subject: [PATCH 058/275] Added new sample transmission calculation Refs #11015 --- .../algorithms/CalculateSampleTransmission.py | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 Code/Mantid/Framework/PythonInterface/plugins/algorithms/CalculateSampleTransmission.py diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CalculateSampleTransmission.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CalculateSampleTransmission.py new file mode 100644 index 000000000000..3325ab785069 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CalculateSampleTransmission.py @@ -0,0 +1,94 @@ +from mantid.simpleapi import * +from mantid.api import * +from mantid.kernel import * +import math +import numpy as np + + +class CalculateSampleTransmission(PythonAlgorithm): + + def category(self): + return 'Sample' + + + def summary(self): + return 'Calculates the scattering & transmission for a given sample material and size over a given wavelength range.' + + + def PyInit(self): + self.declareProperty(name='WavelengthRange', defaultValue='', validator=StringMandatoryValidator(), + doc='Wavelength range to calculate transmission for.') + + self.declareProperty(name='ChemicalFormula', defaultValue='', validator=StringMandatoryValidator(), + doc='Sample chemical formula') + + self.declareProperty(name='NumberDensity', defaultValue=0.1, + doc='Number denisty (atoms/Angstrom^3). Default=0.1') + + self.declareProperty(name='Thickness', defaultValue=0.1, + doc='Sample thickness (cm). Default=0.1') + + self.declareProperty(MatrixWorkspaceProperty('OutputWorkspace', '', Direction.Output), + doc='Outputs the sample transmission over the wavelength range as a function of wavelength.') + + + def PyExec(self): + self._setup() + + # Create the workspace and set the sample material + CreateWorkspace(OutputWorkspace=self._output_ws, NSpec=2, DataX=[0, 0], DataY=[0, 0]) + Rebin(InputWorkspace=self._output_ws, OutputWorkspace=self._output_ws, Params=self._bin_params) + SetSampleMaterial(InputWorkspace=self._output_ws, ChemicalFormula=self._chamical_formula) + ConvertToPointData(InputWorkspace=self._output_ws, OutputWorkspace=self._output_ws) + + ws = mtd[self._output_ws] + wavelengths = ws.readX(0) + transmission_data = np.zeros(len(wavelengths)) + scattering_data = np.zeros(len(wavelengths)) + + # Calculate transmission and scattering for each wavelength point + for idx in range(0, len(wavelengths)): + transmission, scattering = self._calculate_at_wavelength(wavelengths[idx]) + transmission_data[idx] = transmission + scattering_data[idx] = scattering + + ws.setY(0, transmission_data) + ws.setY(1, scattering_data) + + self.setProperty('OutputWorkspace', self._output_ws) + + + def _setup(self): + """ + Gets algorithm properties. + """ + + self._bin_params = self.getPropertyValue('WavelengthRange') + self._chamical_formula = self.getPropertyValue('ChemicalFormula') + self._density = self.getProperty('NumberDensity').value + self._thickness = self.getProperty('Thickness').value + self._output_ws = self.getPropertyValue('OutputWorkspace') + + + def _calculate_at_wavelength(self, wavelength): + """ + Calculates transmission and scattering at a given wavelength. + + @param wavelength Wavelength at which to calculate (in Angstrom) + @return Tuple of transmission and scattering + """ + + material = mtd[self._output_ws].mutableSample().getMaterial() + + absorption_x_section = material.absorbXSection() * wavelength + total_x_section = absorption_x_section + material.totalScatterXSection() + + transmission = math.exp(-self._density * total_x_section * self._thickness) + scattering = 1.0 - math.exp(-self._density * material.totalScatterXSection() * self._thickness) + + return transmission, scattering + + + +# Register algorithm with Mantid +AlgorithmFactory.subscribe(CalculateSampleTransmission) From 9c8c4babbbdc7a509012dd6c367a2d4cf6a6b4f3 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Thu, 5 Feb 2015 11:01:03 +0000 Subject: [PATCH 059/275] Added unit test for new calculation algorithm Refs #11015 --- .../python/plugins/algorithms/CMakeLists.txt | 1 + .../CalculateSampleTransmissionTest.py | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CalculateSampleTransmissionTest.py diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt index 582f2cc6ecd2..1050ad04e1b0 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt @@ -3,6 +3,7 @@ ## set ( TEST_PY_FILES + CalculateSampleTransmissionTest.py CheckForSampleLogsTest.py ConjoinSpectraTest.py CorrectLogTimesTest.py diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CalculateSampleTransmissionTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CalculateSampleTransmissionTest.py new file mode 100644 index 000000000000..022ed03a3030 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CalculateSampleTransmissionTest.py @@ -0,0 +1,34 @@ +import unittest +import numpy as np +import mantid.simpleapi +from mantid.simpleapi import CalculateSampleTransmission + + +class CalculateSampleTransmissionTest(unittest.TestCase): + + def test_sample_transmission_calculation(self): + """ + Test a transmission calculation using IRIS, graphite, 002. + """ + + # Using water sample + formula = "H2-O" + density = 0.1 + thickness = 0.1 + + ws = CalculateSampleTransmission(WavelengthRange='5.0,0.2,7.0', ChemicalFormula=formula, + NumberDensity=density, Thickness=thickness) + + self.assertEqual(ws.getNumberHistograms(), 2) + + expected_trans = [0.564272, 0.564022, 0.563772, 0.563522, 0.563272, 0.563022, 0.562772, 0.562523, 0.562273, 0.562024] + expected_scatt = [0.429309, 0.429309, 0.429309, 0.429309, 0.429309, 0.429309, 0.429309, 0.429309, 0.429309, 0.429309] + trans = ws.readY(0) + scatt = ws.readY(1) + + np.testing.assert_array_almost_equal(trans, expected_trans, decimal=4) + np.testing.assert_array_almost_equal(scatt, expected_scatt, decimal=4) + + +if __name__=="__main__": + unittest.main() From 1229e81c5478ef34d9b55c2e65ddb26964ae7855 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Thu, 5 Feb 2015 11:26:14 +0000 Subject: [PATCH 060/275] Update documentation for new algorithm Refs #11015 --- .../CalculateSampleTransmission-v1.rst | 58 +++++++++++++++++++ .../algorithms/IndirectTransmission-v1.rst | 15 +++-- 2 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 Code/Mantid/docs/source/algorithms/CalculateSampleTransmission-v1.rst diff --git a/Code/Mantid/docs/source/algorithms/CalculateSampleTransmission-v1.rst b/Code/Mantid/docs/source/algorithms/CalculateSampleTransmission-v1.rst new file mode 100644 index 000000000000..1c23cbd58680 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/CalculateSampleTransmission-v1.rst @@ -0,0 +1,58 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Calculates the theoretical scattering & transmission for a given sample over a +given wavelength range. + +The sample chemical formula is input for the :ref:`SetSampleMaterial +` algorithm to calculate the cross-sections. The sample +number density & thickness is input to then calculate the percentage scattering +& transmission. + +Usage +----- + +**Example - Running CalculateSampleTransmission.** + +.. testcode:: ExCalculateSampleTransmissionSimple + + ws = CalculateSampleTransmission(WavelengthRange='2.0, 0.1, 10.0', ChemicalFormula='H2-O') + + print 'Transmission: %f, %f, %f ...' % tuple(ws.readY(0)[:3]) + print 'Scattering: %f, %f, %f ...' % tuple(ws.readY(1)[:3]) + + +Output: + +.. testoutput:: ExCalculateSampleTransmissionSimple + + Transmission: 0.568102, 0.567976, 0.567851 ... + Scattering: 0.429309, 0.429309, 0.429309 ... + + +**Example - Running CalculateSampleTransmission with a specified number density and thickness.** + +.. testcode:: ExCalculateSampleTransmissionParams + + ws = CalculateSampleTransmission(WavelengthRange='2.0, 0.1, 10.0', ChemicalFormula='H2-O', + NumberDensity=0.2, Thickness=0.58) + + print 'Transmission: %f, %f, %f ...' % tuple(ws.readY(0)[:3]) + print 'Scattering: %f, %f, %f ...' % tuple(ws.readY(1)[:3]) + +Output: + +.. testoutput:: ExCalculateSampleTransmissionParams + + Transmission: 0.001417, 0.001413, 0.001410 ... + Scattering: 0.998506, 0.998506, 0.998506 ... + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/IndirectTransmission-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectTransmission-v1.rst index 10e07d97855c..f705195562b0 100644 --- a/Code/Mantid/docs/source/algorithms/IndirectTransmission-v1.rst +++ b/Code/Mantid/docs/source/algorithms/IndirectTransmission-v1.rst @@ -9,12 +9,15 @@ Description ----------- -Calculates the scattering & transmission for Indirect Geometry -spectrometers. The sample chemical formula is input for the -SetSampleMaterial algorithm to calculate the cross-sections. The -instrument analyser reflection is selected to obtain the wavelength to -calculate the absorption cross-section. The sample number density & -thickness is input to then calculate the percentage scattering & +Calculates the scattering & transmission for Indirect Geometry spectrometers at +the elastic peak, as the transmission variation over wavelength is not +substantial. + +The sample chemical formula is input for the :ref:`SetSampleMaterial +` algorithm to calculate the cross-sections. The +instrument analyser reflection is selected to obtain the wavelength of the +elastic peak to calculate the absorption cross-section. The sample number +density & thickness is input to then calculate the percentage scattering & transmission. Usage From 31cac43d029bb829e0f3286a0d08be6fe5466056 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Thu, 5 Feb 2015 11:53:23 +0000 Subject: [PATCH 061/275] Update algorithm validation Refs #11015 --- .../algorithms/CalculateSampleTransmission.py | 16 +++++++++- .../CalculateSampleTransmissionTest.py | 32 ++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CalculateSampleTransmission.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CalculateSampleTransmission.py index 3325ab785069..c88d3bf4f803 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CalculateSampleTransmission.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CalculateSampleTransmission.py @@ -32,6 +32,20 @@ def PyInit(self): doc='Outputs the sample transmission over the wavelength range as a function of wavelength.') + def validateInputs(self): + issues = dict() + + density = self.getProperty('NumberDensity').value + if(density < 0.0): + issues['NumberDensity'] = 'NumberDensity must be positive' + + thickness = self.getProperty('Thickness').value + if(thickness < 0.0): + issues['Thickness'] = 'Thickness must be positive' + + return issues + + def PyExec(self): self._setup() @@ -75,7 +89,7 @@ def _calculate_at_wavelength(self, wavelength): Calculates transmission and scattering at a given wavelength. @param wavelength Wavelength at which to calculate (in Angstrom) - @return Tuple of transmission and scattering + @return Tuple of transmission and scattering percentages """ material = mtd[self._output_ws].mutableSample().getMaterial() diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CalculateSampleTransmissionTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CalculateSampleTransmissionTest.py index 022ed03a3030..ba4c419bbc3d 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CalculateSampleTransmissionTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CalculateSampleTransmissionTest.py @@ -8,7 +8,7 @@ class CalculateSampleTransmissionTest(unittest.TestCase): def test_sample_transmission_calculation(self): """ - Test a transmission calculation using IRIS, graphite, 002. + Test a basic transmission calculation. """ # Using water sample @@ -30,5 +30,35 @@ def test_sample_transmission_calculation(self): np.testing.assert_array_almost_equal(scatt, expected_scatt, decimal=4) + def test_validate_density(self): + """ + Tests validation on NumberDensity property. + """ + + # Using water sample + formula = "H2-O" + density = -0.1 + thickness = 0.1 + + self.assertRaises(RuntimeError, CalculateSampleTransmission, + WavelengthRange='5.0,0.2,7.0', ChemicalFormula=formula, + NumberDensity=density, Thickness=thickness) + + + def test_validate_thickness(self): + """ + Tests validation on Thickness property. + """ + + # Using water sample + formula = "H2-O" + density = 0.1 + thickness = -0.1 + + self.assertRaises(RuntimeError, CalculateSampleTransmission, + WavelengthRange='5.0,0.2,7.0', ChemicalFormula=formula, + NumberDensity=density, Thickness=thickness) + + if __name__=="__main__": unittest.main() From 6ae76a4695198ea69d5f24fb53d028e17d5af271 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Thu, 5 Feb 2015 12:04:45 +0000 Subject: [PATCH 062/275] Fix UI issues in calibration tab Refs #10513 --- .../Indirect/IndirectCalibration.h | 1 - .../Indirect/IndirectCalibration.ui | 6 +++++ .../src/Indirect/IndirectCalibration.cpp | 25 +++---------------- 3 files changed, 9 insertions(+), 23 deletions(-) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.h index c01b42bbd5d2..a878370e0f69 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.h @@ -48,7 +48,6 @@ namespace CustomInterfaces virtual bool validate(); private slots: - void algorithmsComplete(bool error); void calPlotRaw(); void calPlotEnergy(); void calMinChanged(double); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.ui index adbfa401df8b..01698de191a2 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.ui @@ -75,6 +75,9 @@ 999.990000000000009 + + 1.0 + @@ -161,6 +164,9 @@ 999.990000000000009 + + 1.0 + diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectCalibration.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectCalibration.cpp index cedeaa92d211..f49891b9a7b3 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectCalibration.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectCalibration.cpp @@ -165,8 +165,6 @@ namespace CustomInterfaces void IndirectCalibration::run() { - connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(algorithmsComplete(bool))); - // Get properties QString firstFile = m_uiForm.leRunNo->getFirstFilename(); QString filenames = m_uiForm.leRunNo->getFilenames().join(","); @@ -224,10 +222,6 @@ namespace CustomInterfaces { QString resolutionWsName = outputWorkspaceNameStem + "_res"; - QString scaleFactor("1.0"); - if(m_uiForm.ckResolutionScale->isChecked() && !m_uiForm.spResolutionScale->text().isEmpty()) - scaleFactor = m_uiForm.spResolutionScale->text(); - QString resDetectorRange = QString::number(m_dblManager->value(m_properties["ResSpecMin"])) + "," + QString::number(m_dblManager->value(m_properties["ResSpecMax"])); @@ -249,12 +243,14 @@ namespace CustomInterfaces resAlg->setProperty("RebinParam", rebinString.toStdString()); resAlg->setProperty("DetectorRange", resDetectorRange.toStdString()); resAlg->setProperty("BackgroundRange", background.toStdString()); - resAlg->setProperty("ScaleFactor", m_uiForm.spScale->value()); resAlg->setProperty("Smooth", m_uiForm.ckSmoothResolution->isChecked()); resAlg->setProperty("Verbose", m_uiForm.ckVerbose->isChecked()); resAlg->setProperty("Plot", m_uiForm.ckPlot->isChecked()); resAlg->setProperty("Save", m_uiForm.ckSave->isChecked()); + if(m_uiForm.ckResolutionScale->isChecked()) + resAlg->setProperty("ScaleFactor", m_uiForm.spScale->value()); + m_batchAlgoRunner->addAlgorithm(resAlg); // When creating resolution file take the resolution workspace as the result @@ -264,21 +260,6 @@ namespace CustomInterfaces m_batchAlgoRunner->executeBatchAsync(); } - void IndirectCalibration::algorithmsComplete(bool error) - { - if(error) - return; - - QString firstFile = m_uiForm.leRunNo->getFirstFilename(); - QFileInfo firstFileInfo(firstFile); - /* QString calFileName = firstFileInfo.baseName() + "_" + m_uiForm.iicInstrumentConfiguration->getAnalyserName() + m_uiForm.iicInstrumentConfiguration->getReflectionName() + "_calib.nxs"; */ - - /* m_uiForm.ind_calibFile->setFileTextWithSearch(calFileName); */ - /* m_uiForm.ckUseCalib->setChecked(true); */ - - disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(algorithmsComplete(bool))); - } - bool IndirectCalibration::validate() { MantidQt::CustomInterfaces::UserInputValidator uiv; From 995ce4a0b2b40dbbbf13d977f60447ef636e0546 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Thu, 5 Feb 2015 12:29:16 +0000 Subject: [PATCH 063/275] Support plotting both pre and post scale on res Refs #10513 --- .../WorkflowAlgorithms/IndirectResolution.py | 9 ---- .../Indirect/IndirectCalibration.h | 1 + .../src/Indirect/IndirectCalibration.cpp | 42 +++++++++++++++++-- .../algorithms/IndirectResolution-v1.rst | 2 - 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectResolution.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectResolution.py index 38fb54891c2e..ba5a95326fba 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectResolution.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectResolution.py @@ -38,7 +38,6 @@ def PyInit(self): self.declareProperty(name='RebinParam', defaultValue='', doc='Rebinning parameters (min,width,max)') self.declareProperty(name='ScaleFactor', defaultValue=1.0, doc='Factor to scale resolution curve by') - self.declareProperty(name='Smooth', defaultValue=False, doc='Apply WienerSmooth to resolution') self.declareProperty(name='Verbose', defaultValue=False, doc='Print more information to results log') self.declareProperty(name='Plot', defaultValue=False, doc='Plot resolution curve') @@ -75,11 +74,6 @@ def PyExec(self): Rebin(InputWorkspace=self._out_ws, OutputWorkspace=self._out_ws, Params=self._rebin_string) - if self._smooth: - WienerSmooth(InputWorkspace=self._out_ws, OutputWorkspace='__smooth_temp') - CopyLogs(InputWorkspace=self._out_ws, OutputWorkspace='__smooth_temp') - RenameWorkspace(InputWorkspace='__smooth_temp', OutputWorkspace=self._out_ws) - self._post_process() self.setProperty('OutputWorkspace', self._out_ws) @@ -102,7 +96,6 @@ def _setup(self): self._background = self.getProperty('BackgroundRange').value self._rebin_string = self.getProperty('RebinParam').value self._scale_factor = self.getProperty('ScaleFactor').value - self._smooth = self.getProperty('Smooth').value self._verbose = self.getProperty('Verbose').value self._plot = self.getProperty('Plot').value @@ -119,8 +112,6 @@ def _post_process(self): if use_scale_factor: AddSampleLog(Workspace=self._out_ws, LogName='scale_factor', LogType='Number', LogText=str(self._scale_factor)) - AddSampleLog(Workspace=self._out_ws, LogName='res_smoothing_applied', LogType='String', LogText=str(self._smooth)) - AddSampleLog(Workspace=self._out_ws, LogName='back_start', LogType='Number', LogText=str(self._background[0])) AddSampleLog(Workspace=self._out_ws, LogName='back_end', LogType='Number', LogText=str(self._background[1])) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.h index a878370e0f69..295f3e5229b3 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.h @@ -48,6 +48,7 @@ namespace CustomInterfaces virtual bool validate(); private slots: + void algorithmComplete(bool error); void calPlotRaw(); void calPlotEnergy(); void calMinChanged(double); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectCalibration.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectCalibration.cpp index f49891b9a7b3..da7ccae4204c 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectCalibration.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectCalibration.cpp @@ -150,6 +150,8 @@ namespace CustomInterfaces // Nudge resCheck to ensure res range selectors are only shown when Create RES file is checked resCheck(m_uiForm.ckCreateResolution->isChecked()); + + connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(algorithmComplete(bool))); } //---------------------------------------------------------------------------------------------- @@ -232,27 +234,48 @@ namespace CustomInterfaces QString background = QString::number(m_dblManager->value(m_properties["ResStart"])) + "," + QString::number(m_dblManager->value(m_properties["ResEnd"])); + bool smooth = m_uiForm.ckSmoothResolution->isChecked(); + Mantid::API::IAlgorithm_sptr resAlg = Mantid::API::AlgorithmManager::Instance().create("IndirectResolution", -1); resAlg->initialize(); resAlg->setProperty("InputFiles", filenames.toStdString()); - resAlg->setProperty("OutputWorkspace", resolutionWsName.toStdString()); resAlg->setProperty("Instrument", getInstrumentConfiguration()->getInstrumentName().toStdString()); resAlg->setProperty("Analyser", getInstrumentConfiguration()->getAnalyserName().toStdString()); resAlg->setProperty("Reflection", getInstrumentConfiguration()->getReflectionName().toStdString()); resAlg->setProperty("RebinParam", rebinString.toStdString()); resAlg->setProperty("DetectorRange", resDetectorRange.toStdString()); resAlg->setProperty("BackgroundRange", background.toStdString()); - resAlg->setProperty("Smooth", m_uiForm.ckSmoothResolution->isChecked()); resAlg->setProperty("Verbose", m_uiForm.ckVerbose->isChecked()); - resAlg->setProperty("Plot", m_uiForm.ckPlot->isChecked()); resAlg->setProperty("Save", m_uiForm.ckSave->isChecked()); if(m_uiForm.ckResolutionScale->isChecked()) resAlg->setProperty("ScaleFactor", m_uiForm.spScale->value()); + if(smooth) + { + resAlg->setProperty("OutputWorkspace", resolutionWsName.toStdString() + "_pre_smooth"); + } + else + { + resAlg->setProperty("OutputWorkspace", resolutionWsName.toStdString()); + resAlg->setProperty("Plot", m_uiForm.ckPlot->isChecked()); + } + m_batchAlgoRunner->addAlgorithm(resAlg); + if(smooth) + { + Mantid::API::IAlgorithm_sptr smoothAlg = Mantid::API::AlgorithmManager::Instance().create("WienerSmooth"); + smoothAlg->initialize(); + smoothAlg->setProperty("OutputWorkspace", resolutionWsName.toStdString()); + + BatchAlgorithmRunner::AlgorithmRuntimeProps smoothAlgInputProps; + smoothAlgInputProps["InputWorkspace"] = resolutionWsName.toStdString() + "_pre_smooth"; + + m_batchAlgoRunner->addAlgorithm(smoothAlg, smoothAlgInputProps); + } + // When creating resolution file take the resolution workspace as the result m_pythonExportWsName = resolutionWsName.toStdString(); } @@ -260,6 +283,19 @@ namespace CustomInterfaces m_batchAlgoRunner->executeBatchAsync(); } + void IndirectCalibration::algorithmComplete(bool error) + { + if(error) + return; + + // Plot the smoothed workspace if required + if(m_uiForm.ckSmoothResolution->isChecked() && m_uiForm.ckPlot->isChecked()) + { + std::string pyInput = "from mantidplot import plotSpectrum\nplotSpectrum(['" + m_pythonExportWsName + "', '" + m_pythonExportWsName + "_pre_smooth'], 0)\n"; + m_pythonRunner.runPythonCode(QString::fromStdString(pyInput)); + } + } + bool IndirectCalibration::validate() { MantidQt::CustomInterfaces::UserInputValidator uiv; diff --git a/Code/Mantid/docs/source/algorithms/IndirectResolution-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectResolution-v1.rst index 27efd1d06062..6bb35679ff6e 100644 --- a/Code/Mantid/docs/source/algorithms/IndirectResolution-v1.rst +++ b/Code/Mantid/docs/source/algorithms/IndirectResolution-v1.rst @@ -11,8 +11,6 @@ Description Creates a resolution workspace for an inelastic indirect sample run. -See `Indirect:Calibration `_. - Usage ----- From fe24fcdb29cbb90d1cf945246d4ce7364879b0b9 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Thu, 5 Feb 2015 13:13:02 +0000 Subject: [PATCH 064/275] Re #10894 Removing try blocks that hide actual error messages --- .../src/PlotAsymmetryByLogValue.cpp | 71 +++++++------------ 1 file changed, 26 insertions(+), 45 deletions(-) diff --git a/Code/Mantid/Framework/Algorithms/src/PlotAsymmetryByLogValue.cpp b/Code/Mantid/Framework/Algorithms/src/PlotAsymmetryByLogValue.cpp index 20afdb2e61f9..bc9cb6bda5c6 100644 --- a/Code/Mantid/Framework/Algorithms/src/PlotAsymmetryByLogValue.cpp +++ b/Code/Mantid/Framework/Algorithms/src/PlotAsymmetryByLogValue.cpp @@ -304,16 +304,11 @@ void PlotAsymmetryByLogValue::exec() { */ void PlotAsymmetryByLogValue::loadCorrectionsFromFile (Workspace_sptr &customDeadTimes, std::string deadTimeFile ) { - try{ - IAlgorithm_sptr loadDeadTimes = createChildAlgorithm("LoadNexusProcessed"); - loadDeadTimes->setPropertyValue("Filename", deadTimeFile); - loadDeadTimes->setProperty("OutputWorkspace", customDeadTimes); - loadDeadTimes->executeAsChildAlg(); - customDeadTimes = loadDeadTimes->getProperty("OutputWorkspace"); - } - catch (...){ - throw std::runtime_error("Unable to load corrections from specified file\n"); - } + IAlgorithm_sptr loadDeadTimes = createChildAlgorithm("LoadNexusProcessed"); + loadDeadTimes->setPropertyValue("Filename", deadTimeFile); + loadDeadTimes->setProperty("OutputWorkspace", customDeadTimes); + loadDeadTimes->executeAsChildAlg(); + customDeadTimes = loadDeadTimes->getProperty("OutputWorkspace"); } /** Populate output workspace with results * @param outWS :: [input/output] Output workspace to populate @@ -397,24 +392,17 @@ void PlotAsymmetryByLogValue::applyDeadtimeCorr (Workspace_sptr &loadedWs, Works ScopedWorkspace ws(loadedWs); ScopedWorkspace dt(deadTimes); - try - { - IAlgorithm_sptr applyCorr = AlgorithmManager::Instance().create("ApplyDeadTimeCorr"); - applyCorr->setLogging(false); - applyCorr->setRethrows(true); - applyCorr->setPropertyValue("InputWorkspace", ws.name()); - applyCorr->setPropertyValue("OutputWorkspace", ws.name()); - applyCorr->setProperty("DeadTimeTable", dt.name()); - applyCorr->execute(); - // Workspace should've been replaced in the ADS by ApplyDeadTimeCorr, so - // need to - // re-assign it - loadedWs = ws.retrieve(); - } - catch (...) - { - throw std::runtime_error("Unable to apply corrections\n"); - } + IAlgorithm_sptr applyCorr = AlgorithmManager::Instance().create("ApplyDeadTimeCorr"); + applyCorr->setLogging(false); + applyCorr->setRethrows(true); + applyCorr->setPropertyValue("InputWorkspace", ws.name()); + applyCorr->setPropertyValue("OutputWorkspace", ws.name()); + applyCorr->setProperty("DeadTimeTable", dt.name()); + applyCorr->execute(); + // Workspace should've been replaced in the ADS by ApplyDeadTimeCorr, so + // need to + // re-assign it + loadedWs = ws.retrieve(); } /** Group detectors from specified file @@ -429,23 +417,16 @@ void PlotAsymmetryByLogValue::groupDetectors (Workspace_sptr &loadedWs, Workspac ScopedWorkspace grouping(loadedDetGrouping); ScopedWorkspace outWS; - try - { - IAlgorithm_sptr applyGrouping = AlgorithmManager::Instance().create("MuonGroupDetectors"); - applyGrouping->setLogging(false); - applyGrouping->setRethrows(true); - - applyGrouping->setPropertyValue("InputWorkspace", inWS.name()); - applyGrouping->setPropertyValue("DetectorGroupingTable", grouping.name()); - applyGrouping->setPropertyValue("OutputWorkspace", outWS.name()); - applyGrouping->execute(); - - loadedWs = outWS.retrieve(); - } - catch (...) - { - throw std::runtime_error("Unable to group detectors.\n\nPlease specify grouping manually."); - } + IAlgorithm_sptr applyGrouping = AlgorithmManager::Instance().create("MuonGroupDetectors"); + applyGrouping->setLogging(false); + applyGrouping->setRethrows(true); + + applyGrouping->setPropertyValue("InputWorkspace", inWS.name()); + applyGrouping->setPropertyValue("DetectorGroupingTable", grouping.name()); + applyGrouping->setPropertyValue("OutputWorkspace", outWS.name()); + applyGrouping->execute(); + + loadedWs = outWS.retrieve(); } /** Calculate the integral asymmetry for a workspace. * The calculation is done by MuonAsymmetryCalc and SimpleIntegration From 7b032eda266295a71d9c1c79f7c3194b805988e3 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Thu, 5 Feb 2015 13:31:37 +0000 Subject: [PATCH 065/275] Clarify what Fold Frames actually does Refs #11017 --- .../Indirect/IndirectConvertToEnergy.ui | 3 +-- .../docs/source/interfaces/Indirect_DataReduction.rst | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectConvertToEnergy.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectConvertToEnergy.ui index c5be848f4b93..c0b72ee847eb 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectConvertToEnergy.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectConvertToEnergy.ui @@ -890,8 +890,7 @@ true - If this box is unchecked and the raw files are determined to contain multiple frames, then the reduction process will end at the step where they would have been folded together. -Later steps in the process (saving, renaming) will not be done. + <html><head/><body><p>If checked, multiple-framed data will be folded back into a single spectrum.<br/>Otherwise data is left as is and multiple frames are named giving the frame number at the end of the workspace name.</p></body></html> Fold Multiple Frames diff --git a/Code/Mantid/docs/source/interfaces/Indirect_DataReduction.rst b/Code/Mantid/docs/source/interfaces/Indirect_DataReduction.rst index c4a8c609315a..6f0d3fa22673 100644 --- a/Code/Mantid/docs/source/interfaces/Indirect_DataReduction.rst +++ b/Code/Mantid/docs/source/interfaces/Indirect_DataReduction.rst @@ -108,9 +108,9 @@ Plot Output Allows the result to be plotted as either a spectrum plot or contour plot. Fold Multiple Frames - This option is only relevant for TOSCA. If unchecked, then reduction on - multiply-framed data will cease at the point where the frames would have been - merged. + This option is only relevant for TOSCA. If checked, then multiple-framed data + will be folded back into a single spectra, if unchecked the frames wil lbe + left as is with the frame number given at the end of the workspace name. Output in :math:`cm^{-1}` Converts the units of the energy axis from :math:`meV` to wave number From b40185d37f02e4f987226c7ddfab1015258a4d05 Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Thu, 5 Feb 2015 13:49:00 +0000 Subject: [PATCH 066/275] Handle fold frames based on IPF Refs #11017 --- .../src/Indirect/IndirectConvertToEnergy.cpp | 6 ++++++ .../CustomInterfaces/src/Indirect/IndirectDataReduction.cpp | 1 + Code/Mantid/instrument/TFXA_Parameters.xml | 4 ++++ Code/Mantid/instrument/TFXA_Parameters_Post-1993-10-06.xml | 4 ++++ Code/Mantid/instrument/TOSCA_Parameters.xml | 3 +++ Code/Mantid/instrument/TOSCA_Parameters_TOSCA-1.xml | 3 +++ 6 files changed, 21 insertions(+) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectConvertToEnergy.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectConvertToEnergy.cpp index 4dc803fcd85e..a1c490794499 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectConvertToEnergy.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectConvertToEnergy.cpp @@ -283,6 +283,12 @@ namespace CustomInterfaces bool defaultOptions = instDetails["save-ascii-choice"] == "true"; m_uiForm.ckSaveASCII->setChecked(defaultOptions); } + + if(!instDetails["fold-frames-choice"].isEmpty()) + { + bool defaultOptions = instDetails["fold-frames-choice"] == "true"; + m_uiForm.ckFold->setChecked(defaultOptions); + } } /** diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataReduction.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataReduction.cpp index 59b94a4b612e..3f88108cc96c 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataReduction.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataReduction.cpp @@ -258,6 +258,7 @@ std::map IndirectDataReduction::getInstrumentDetails() ipfElements.push_back("rebin-default"); ipfElements.push_back("cm-1-convert-choice"); ipfElements.push_back("save-ascii-choice"); + ipfElements.push_back("fold-frames-choice"); // In the IRIS IPF there is no fmica component if(instrumentName == "IRIS" && analyser == "fmica") diff --git a/Code/Mantid/instrument/TFXA_Parameters.xml b/Code/Mantid/instrument/TFXA_Parameters.xml index 5a63efa980fa..99740aea3036 100644 --- a/Code/Mantid/instrument/TFXA_Parameters.xml +++ b/Code/Mantid/instrument/TFXA_Parameters.xml @@ -29,6 +29,10 @@ + + + + diff --git a/Code/Mantid/instrument/TFXA_Parameters_Post-1993-10-06.xml b/Code/Mantid/instrument/TFXA_Parameters_Post-1993-10-06.xml index a8e215fa8354..3a4c07aac335 100644 --- a/Code/Mantid/instrument/TFXA_Parameters_Post-1993-10-06.xml +++ b/Code/Mantid/instrument/TFXA_Parameters_Post-1993-10-06.xml @@ -29,6 +29,10 @@ + + + + diff --git a/Code/Mantid/instrument/TOSCA_Parameters.xml b/Code/Mantid/instrument/TOSCA_Parameters.xml index 82e58f9f0d34..ab712fcba5b9 100644 --- a/Code/Mantid/instrument/TOSCA_Parameters.xml +++ b/Code/Mantid/instrument/TOSCA_Parameters.xml @@ -27,6 +27,9 @@ + + + loading nexus file: ' + nexus_file_numerator EventDataWks = LoadEventNexus(Filename=nexus_file_numerator) - + self.is_nexus_detector_rotated_flag = self.isNexusTakeAfterRefDate(EventDataWks.getRun().getProperty('run_start').value) if self.is_nexus_detector_rotated_flag: @@ -431,7 +431,7 @@ def _createIntegratedWorkspace(self, y_axis[y, :] += InputWorkspace.readY(index)[:] y_error_axis[y, :] += ((InputWorkspace.readE(index)[:]) * (InputWorkspace.readE(index)[:])) - + else: for x in range(304): for y in y_range: @@ -566,13 +566,13 @@ def _removeBackground(self, peak_array = zeros(nbr_tof) peak_array_error = zeros(nbr_tof) - bMinBack = False; - bMaxBack = False; + bMinBack = False + bMaxBack = False - min_back = 0; - min_back_error = 0; - max_back = 0; - max_back_error = 0; + min_back = 0 + min_back_error = 0 + max_back = 0 + max_back_error = 0 for t in (range(nbr_tof-1)): @@ -616,8 +616,8 @@ def _removeBackground(self, [final_value, final_error] = self.sumWithError(new_tmp_peak, new_tmp_peak_error) - peak_array[t] = final_value; - peak_array_error[t] = final_error; + peak_array[t] = final_value + peak_array_error[t] = final_error # make new workspace @@ -1247,7 +1247,7 @@ def calculate(string_runs=None, """ - list_attenuator = None; + list_attenuator = None #use default string files if not provided if (string_runs is None): @@ -1284,7 +1284,7 @@ def calculate(string_runs=None, if (list_attenuator is None): # list_attenuator = [0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4] - list_attenuator = [0, 1, 1, 1, 1, 1]; + list_attenuator = [0, 1, 1, 1, 1, 1] if (list_peak_back is None): list_peak_back = zeros((len(list_runs), 4)) #[peak_min, peak_max, back_min, back_max] diff --git a/Code/Mantid/Framework/PythonInterface/plugins/functions/ChudleyElliot.py b/Code/Mantid/Framework/PythonInterface/plugins/functions/ChudleyElliot.py index b53bc6465092..ec44cf7b469a 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/functions/ChudleyElliot.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/functions/ChudleyElliot.py @@ -53,8 +53,8 @@ def functionDeriv1D(self, xvals, jacobian): for x in xvals: s = math.sin(x*length)/(x*length) h = (1.0-s)/tau - jacobian.set(i,0,-h/tau); - jacobian.set(i,1,(math.cos(x*length)-s)/(length*tau)); + jacobian.set(i,0,-h/tau) + jacobian.set(i,1,(math.cos(x*length)-s)/(length*tau)) i += 1 # Required to have Mantid recognise the new function diff --git a/Code/Mantid/Framework/PythonInterface/plugins/functions/DSFinterp1DFit.py b/Code/Mantid/Framework/PythonInterface/plugins/functions/DSFinterp1DFit.py index 00b807febc9a..5f5028b06537 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/functions/DSFinterp1DFit.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/functions/DSFinterp1DFit.py @@ -31,139 +31,139 @@ class DSFinterp1DFit(IFunction1D): - def category(self): - return 'QuasiElastic' + def category(self): + return 'QuasiElastic' - def init(self): - '''Declare parameters and attributes that participate in the fitting''' + def init(self): + '''Declare parameters and attributes that participate in the fitting''' # Active fitting parameters - self.declareParameter('Intensity', 1.0, 'Intensity') - self.declareParameter('TargetParameter', 1.0, 'Target value of the structure factor parameter') - - self.declareAttribute('InputWorkspaces','') - self.declareAttribute('LoadErrors', False) - self.declareAttribute('WorkspaceIndex', 0) - self.declareAttribute('ParameterValues', '') - self.declareAttribute('LocalRegression', True) - self.declareAttribute('RegressionType', 'quadratic') - self.declareAttribute('RegressionWindow', 6) + self.declareParameter('Intensity', 1.0, 'Intensity') + self.declareParameter('TargetParameter', 1.0, 'Target value of the structure factor parameter') + + self.declareAttribute('InputWorkspaces','') + self.declareAttribute('LoadErrors', False) + self.declareAttribute('WorkspaceIndex', 0) + self.declareAttribute('ParameterValues', '') + self.declareAttribute('LocalRegression', True) + self.declareAttribute('RegressionType', 'quadratic') + self.declareAttribute('RegressionWindow', 6) # "private" attributes associated to the declare function attributes - self._InputWorkspaces = None - self._LoadErrors = None - self._WorkspaceIndex = None - self._ParameterValues = None - self._fmin = None - self._fmax = None - self._LocalRegression = None - self._RegressionType = None - self._RegressionTypes = set(['linear','quadratic']) #valid syntaxfor python >= 2.6 - self._RegressionWindow = None - self._minWindow = { 'linear':3, 'quadratic':4 } + self._InputWorkspaces = None + self._LoadErrors = None + self._WorkspaceIndex = None + self._ParameterValues = None + self._fmin = None + self._fmax = None + self._LocalRegression = None + self._RegressionType = None + self._RegressionTypes = set(['linear','quadratic']) #valid syntaxfor python >= 2.6 + self._RegressionWindow = None + self._minWindow = { 'linear':3, 'quadratic':4 } # channelgroup to interpolate values - self._channelgroup = None - self._xvalues = None #energies of the channels - - def setAttributeValue(self, name, value): - if name == "InputWorkspaces": - self._InputWorkspaces = value.split() - if ',' in value: - self._InputWorkspaces = [x.strip() for x in value.split(',')] - elif name == 'LoadErrors': - self._LoadErrors= bool(value) - elif name == 'WorkspaceIndex': - self._WorkspaceIndex = int(value) - elif name == 'ParameterValues': - self._ParameterValues = [ float(f) for f in value.split() ] - self._fmin = min(self._ParameterValues) - self._fmax = max(self._ParameterValues) - elif name == 'LocalRegression': - self._LocalRegression = bool(value) - elif name == 'RegressionType': - self._RegressionType = value.lower() - elif name == 'RegressionWindow': - self._RegressionWindow = value - - def validateParams(self): - '''Check parameters within expected range''' - intensity = self.getParameterValue('Intensity') - if intensity <=0: - message = 'Parameter Intensity in DSFinterp1DFit must be positive. Got {0} instead'.format(intensity) - logger.error(message) - return None - f = self.getParameterValue('TargetParameter') - if f < self._fmin or f > self._fmax: - message = 'TargetParameter {0} is out of bounds [{1}, {2}]. Applying penalty...'.format(f, self._fmin, self._fmax) - logger.error(message) - return None - return {'Intensity':intensity, 'TargetParameter':f} - - - def function1D(self, xvals): - ''' Fit using the interpolated structure factor ''' - p=self.validateParams() - if not p: - return numpy.zeros(len(xvals), dtype=float) # return zeros if parameters not valid + self._channelgroup = None + self._xvalues = None #energies of the channels + + def setAttributeValue(self, name, value): + if name == "InputWorkspaces": + self._InputWorkspaces = value.split() + if ',' in value: + self._InputWorkspaces = [x.strip() for x in value.split(',')] + elif name == 'LoadErrors': + self._LoadErrors= bool(value) + elif name == 'WorkspaceIndex': + self._WorkspaceIndex = int(value) + elif name == 'ParameterValues': + self._ParameterValues = [ float(f) for f in value.split() ] + self._fmin = min(self._ParameterValues) + self._fmax = max(self._ParameterValues) + elif name == 'LocalRegression': + self._LocalRegression = bool(value) + elif name == 'RegressionType': + self._RegressionType = value.lower() + elif name == 'RegressionWindow': + self._RegressionWindow = value + + def validateParams(self): + '''Check parameters within expected range''' + intensity = self.getParameterValue('Intensity') + if intensity <=0: + message = 'Parameter Intensity in DSFinterp1DFit must be positive. Got {0} instead'.format(intensity) + logger.error(message) + return None + f = self.getParameterValue('TargetParameter') + if f < self._fmin or f > self._fmax: + message = 'TargetParameter {0} is out of bounds [{1}, {2}]. Applying penalty...'.format(f, self._fmin, self._fmax) + logger.error(message) + return None + return {'Intensity':intensity, 'TargetParameter':f} + + + def function1D(self, xvals): + ''' Fit using the interpolated structure factor ''' + p=self.validateParams() + if not p: + return numpy.zeros(len(xvals), dtype=float) # return zeros if parameters not valid # The first time the function is called requires initialization of the interpolator - if self._channelgroup == None: + if self._channelgroup == None: # Check consistency of the input # check InputWorkspaces have at least the workspace index - for w in self._InputWorkspaces: - if mtd[w].getNumberHistograms() <= self._WorkspaceIndex: - message = 'Numer of histograms in Workspace {0} does not allow for workspace index {1}'.format(w,self._WorkspaceIndex) - logger.error(message) - raise IndexError(message) + for w in self._InputWorkspaces: + if mtd[w].getNumberHistograms() <= self._WorkspaceIndex: + message = 'Numer of histograms in Workspace {0} does not allow for workspace index {1}'.format(w,self._WorkspaceIndex) + logger.error(message) + raise IndexError(message) # check number of input workspaces and parameters is the same - if len(self._ParameterValues) != len(self._InputWorkspaces): - message = 'Number of InputWorkspaces and ParameterValues should be the same. Found {0} and {1}, respectively'.format(len(self._InputWorkspaces), len(self._ParameterValues)) - logger.error(message) - raise ValueError(message) + if len(self._ParameterValues) != len(self._InputWorkspaces): + message = 'Number of InputWorkspaces and ParameterValues should be the same. Found {0} and {1}, respectively'.format(len(self._InputWorkspaces), len(self._ParameterValues)) + logger.error(message) + raise ValueError(message) # check the regression type is valid - if self._RegressionType not in self._RegressionTypes: - message = 'Regression type {0} not implemented. choose one of {1}'.format(self._RegressionType, ', '.join(self._RegressionTypes)) - logger.error(message) - raise NotImplementedError(message) + if self._RegressionType not in self._RegressionTypes: + message = 'Regression type {0} not implemented. choose one of {1}'.format(self._RegressionType, ', '.join(self._RegressionTypes)) + logger.error(message) + raise NotImplementedError(message) # check the regression window is appropriate for the regression type selected - if self._RegressionWindow < self._minWindow[self._RegressionType]: - message = 'RegressionWindow must be equal or bigger than {0} for regression type {1}'.format(self._minWindow[self._RegressionType], self._RegressionType) - logger.error(message) - raise ValueError(message) + if self._RegressionWindow < self._minWindow[self._RegressionType]: + message = 'RegressionWindow must be equal or bigger than {0} for regression type {1}'.format(self._minWindow[self._RegressionType], self._RegressionType) + logger.error(message) + raise ValueError(message) # Initialize the energies of the channels with the first of the input workspaces - self._xvalues = numpy.copy( mtd[ self._InputWorkspaces[0] ].dataX(self._WorkspaceIndex) ) - if len(self._xvalues) == 1+ len( mtd[ self._InputWorkspaces[0] ].dataY(self._WorkspaceIndex) ): - self._xvalues = (self._xvalues[1:]+self._xvalues[:-1])/2.0 # Deal with histogram data + self._xvalues = numpy.copy( mtd[ self._InputWorkspaces[0] ].dataX(self._WorkspaceIndex) ) + if len(self._xvalues) == 1+ len( mtd[ self._InputWorkspaces[0] ].dataY(self._WorkspaceIndex) ): + self._xvalues = (self._xvalues[1:]+self._xvalues[:-1])/2.0 # Deal with histogram data # Initialize the channel group - nf = len(self._ParameterValues) + nf = len(self._ParameterValues) # Load the InputWorkspaces into a group of dynamic structure factors - from dsfinterp.dsf import Dsf - from dsfinterp.dsfgroup import DsfGroup - dsfgroup = DsfGroup() - for idsf in range(nf): - dsf = Dsf() - dsf.SetIntensities( mtd[ self._InputWorkspaces[idsf] ].dataY(self._WorkspaceIndex) ) - dsf.errors = None # do not incorporate error data - if self._LoadErrors: - dsf.SetErrors(mtd[ self._InputWorkspaces[idsf] ].dataE(self._WorkspaceIndex)) - dsf.SetFvalue( self._ParameterValues[idsf] ) - dsfgroup.InsertDsf(dsf) + from dsfinterp.dsf import Dsf + from dsfinterp.dsfgroup import DsfGroup + dsfgroup = DsfGroup() + for idsf in range(nf): + dsf = Dsf() + dsf.SetIntensities( mtd[ self._InputWorkspaces[idsf] ].dataY(self._WorkspaceIndex) ) + dsf.errors = None # do not incorporate error data + if self._LoadErrors: + dsf.SetErrors(mtd[ self._InputWorkspaces[idsf] ].dataE(self._WorkspaceIndex)) + dsf.SetFvalue( self._ParameterValues[idsf] ) + dsfgroup.InsertDsf(dsf) # Create the interpolator - from dsfinterp.channelgroup import ChannelGroup - self._channelgroup = ChannelGroup() - self._channelgroup.InitFromDsfGroup(dsfgroup) - if self._LocalRegression: - self._channelgroup.InitializeInterpolator(running_regr_type=self._RegressionType, windowlength=self._RegressionWindow) - else: - self._channelgroup.InitializeInterpolator(windowlength=0) + from dsfinterp.channelgroup import ChannelGroup + self._channelgroup = ChannelGroup() + self._channelgroup.InitFromDsfGroup(dsfgroup) + if self._LocalRegression: + self._channelgroup.InitializeInterpolator(running_regr_type=self._RegressionType, windowlength=self._RegressionWindow) + else: + self._channelgroup.InitializeInterpolator(windowlength=0) # channel group has been initialized, so evaluate the interpolator - dsf = self._channelgroup(p['TargetParameter']) + dsf = self._channelgroup(p['TargetParameter']) # Linear interpolation between the energies of the channels and the xvalues we require # NOTE: interpolator evaluates to zero for any of the xvals outside of the domain defined by self._xvalues - intensities_interpolator = interp1d(self._xvalues, p['Intensity']*dsf.intensities, kind='linear') - return intensities_interpolator(xvals) # can we pass by reference? + intensities_interpolator = interp1d(self._xvalues, p['Intensity']*dsf.intensities, kind='linear') + return intensities_interpolator(xvals) # can we pass by reference? # Required to have Mantid recognize the new function try: - import dsfinterp - FunctionFactory.subscribe(DSFinterp1DFit) + import dsfinterp + FunctionFactory.subscribe(DSFinterp1DFit) except: - logger.debug('Failed to subscribe fit function DSFinterp1DFit; Python package dsfinterp may be missing (https://pypi.python.org/pypi/dsfinterp)') - pass + logger.debug('Failed to subscribe fit function DSFinterp1DFit; Python package dsfinterp may be missing (https://pypi.python.org/pypi/dsfinterp)') + pass diff --git a/Code/Mantid/Framework/PythonInterface/plugins/functions/Examples/Example1DFunction.py b/Code/Mantid/Framework/PythonInterface/plugins/functions/Examples/Example1DFunction.py index 314e436eaadd..7286ee94c80f 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/functions/Examples/Example1DFunction.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/functions/Examples/Example1DFunction.py @@ -53,8 +53,8 @@ def functionDeriv1D(self, xvals, jacobian): """ i = 0 for x in xvals: - jacobian.set(i,0,1); - jacobian.set(i,1,x); + jacobian.set(i,0,1) + jacobian.set(i,1,x) i += 1 # Required to have Mantid recognise the new function diff --git a/Code/Mantid/Framework/PythonInterface/plugins/functions/Examples/ExamplePeakFunction.py b/Code/Mantid/Framework/PythonInterface/plugins/functions/Examples/ExamplePeakFunction.py index a24fe9fc4d2c..2564aacabb9c 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/functions/Examples/ExamplePeakFunction.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/functions/Examples/ExamplePeakFunction.py @@ -49,7 +49,7 @@ def functionLocal(self, xvals): height = self.getParameterValue("Height") # Can also be retrieve by index self.getParameterValue(0) peak_centre = self.getParameterValue("PeakCentre") sigma = self.getParameterValue("Sigma") - weight = math.pow(1./sigma,2); + weight = math.pow(1./sigma,2) # Here you can use the NTerms attr if required by # using self._nterms: see setAttributeValue below or @@ -68,10 +68,10 @@ def functionDerivLocal(self, xvals, jacobian): ip = The index of the parameter value whose partial derivative this corresponds to value = The value of the derivative """ - height = self.getParameterValue("Height"); - peak_centre = self.getParameterValue("PeakCentre"); + height = self.getParameterValue("Height") + peak_centre = self.getParameterValue("PeakCentre") sigma = self.getParameterValue("Sigma") - weight = math.pow(1./sigma,2); + weight = math.pow(1./sigma,2) # X index i = 0 diff --git a/Code/Mantid/Framework/PythonInterface/plugins/functions/FickDiffusion.py b/Code/Mantid/Framework/PythonInterface/plugins/functions/FickDiffusion.py index bc57736a6c8d..250651bd0a91 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/functions/FickDiffusion.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/functions/FickDiffusion.py @@ -43,7 +43,7 @@ def function1D(self, xvals): def functionDeriv1D(self, xvals, jacobian): i = 0 for x in xvals: - jacobian.set(i,0,2.0*x); + jacobian.set(i,0,2.0*x) i += 1 # Required to have Mantid recognise the new function diff --git a/Code/Mantid/Framework/PythonInterface/plugins/functions/Guinier.py b/Code/Mantid/Framework/PythonInterface/plugins/functions/Guinier.py index 71916353ad6d..96cc08f561d0 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/functions/Guinier.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/functions/Guinier.py @@ -30,7 +30,7 @@ class Guinier(IFunction1D): """ Provide a Guinier fit function for SANS - + I(q) = I(0) exp(-R^2 q^2 / 3) """ def category(self): @@ -58,7 +58,7 @@ def functionDeriv1D(self, xvals, jacobian): rg = self.getParameterValue('Rg') for x in xvals: jacobian.set(i,0, math.exp(-(rg*x)**2/3.0 ) ) - jacobian.set(i,1, -self.getParameterValue("Scale") * math.exp(-(rg*x)**2/3.0 )*2.0/3.0*rg*x*x ); + jacobian.set(i,1, -self.getParameterValue("Scale") * math.exp(-(rg*x)**2/3.0 )*2.0/3.0*rg*x*x ) i += 1 # Required to have Mantid recognise the new function diff --git a/Code/Mantid/Framework/PythonInterface/plugins/functions/GuinierPorod.py b/Code/Mantid/Framework/PythonInterface/plugins/functions/GuinierPorod.py index d567938f179e..c8ee3122b5dc 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/functions/GuinierPorod.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/functions/GuinierPorod.py @@ -30,7 +30,7 @@ class GuinierPorod(IFunction1D): """ Provide a Guinier-Porod model for SANS. - + See Hammouda, J. Appl. Cryst. (2010) 43, 716-719 """ def category(self): @@ -55,7 +55,7 @@ def _boundary_conditions(self, qval): m = self.getParameterValue('M') if Rg<=0: return True if m3.0: return True + if s>3.0: return True return False def _guinier_porod_core(self, qval): @@ -70,7 +70,7 @@ def _guinier_porod_core(self, qval): if self._boundary_conditions(qval): return 0.0 q1 = math.sqrt((m-s)*n/2.0)/Rg if qval < q1: - return math.pow(qval,-s)*math.exp((-qval*qval*Rg*Rg)/n) + return math.pow(qval,-s)*math.exp((-qval*qval*Rg*Rg)/n) else: return math.pow(qval,-m)*math.pow(Rg,s-m)*math.exp((s-m)/2.0)*math.pow((m-s)*n/2.0,(m-s)/2.0) @@ -93,13 +93,13 @@ def _first_derivative_dim(self, qval): result = (2.0*s-m-3.0)/(2.0*(3.0-s)) - 0.5*(math.log(m-s)+math.log(3-s)) result += math.log(Rg) + math.log(2.0) + 1.0 return result * math.pow(qval,-m) * math.pow(Rg,s-m) * math.exp((s-m)/2.0) * math.pow((m-s)*n/2.0,(m-s)/2.0) - - + + def _first_derivative_m(self, qval): """ Compute the first derivative dI/dM @param qval: q-value to evaluate at - + Derivatives can be obtained here: http://www.derivative-calculator.net/#expr=%28%28m-s%29%283-s%29%2F2%29%5E%28%28m%20-%20s%29%2F2%29q%5E-mr%5E%28s-m%29exp%28%28s-m%29%2F2%29&diffvar=m """ @@ -115,7 +115,7 @@ def _first_derivative_m(self, qval): result = -math.log(qval) - math.log(Rg) - math.log(2.0) - 1.0 result += ( (math.log(m-s)+math.log(3-s))/2.0 + 0.5 ) return result * math.pow(qval,-m) * math.pow(Rg,s-m) * math.exp((s-m)/2.0) * math.pow((m-s)*n/2.0,(m-s)/2.0) - + def _first_derivative_rg(self, qval): """ Compute the first derivative dI/d(Rg) @@ -133,7 +133,7 @@ def _first_derivative_rg(self, qval): else: return math.pow(qval,-m)*math.exp((s-m)/2.0)*math.pow(((m-s)*n/2.0), ((m-s)/2.0))*(s-m)*math.pow(Rg,(s-m-1)) - + def function1D(self, xvals): """ Evaluate the model @@ -143,7 +143,7 @@ def function1D(self, xvals): scale = self.getParameterValue('Scale') bgd = self.getParameterValue('Background') - output = np.zeros(len(xvals), dtype=float) + output = np.zeros(len(xvals), dtype=float) for i in range(len(xvals)): output[i] = scale * self._guinier_porod_core(xvals[i]) + bgd return output @@ -164,4 +164,4 @@ def functionDeriv1D(self, xvals, jacobian): i += 1 # Required to have Mantid recognise the new function -FunctionFactory.subscribe(GuinierPorod) \ No newline at end of file +FunctionFactory.subscribe(GuinierPorod) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/functions/HallRoss.py b/Code/Mantid/Framework/PythonInterface/plugins/functions/HallRoss.py index 719057b103e6..9c83e34f4822 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/functions/HallRoss.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/functions/HallRoss.py @@ -56,8 +56,8 @@ def functionDeriv1D(self, xvals, jacobian): for x in xvals: ex = math.exp(-l*x*x) h = (1.0-ex)/tau - jacobian.set(i,0,-h/tau); - jacobian.set(i,1,x*x*ex/tau); + jacobian.set(i,0,-h/tau) + jacobian.set(i,1,x*x*ex/tau) i += 1 # Required to have Mantid recognise the new function diff --git a/Code/Mantid/Framework/PythonInterface/plugins/functions/Lorentz.py b/Code/Mantid/Framework/PythonInterface/plugins/functions/Lorentz.py index c8814de43f78..17835da7dba4 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/functions/Lorentz.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/functions/Lorentz.py @@ -30,7 +30,7 @@ class Lorentz(IFunction1D): """ Provide a Lorentz model for SANS - + I(q) = scale / ( 1 + q^2 L^2 ) + background """ diff --git a/Code/Mantid/Framework/PythonInterface/plugins/functions/Porod.py b/Code/Mantid/Framework/PythonInterface/plugins/functions/Porod.py index 6f2f280682c5..47de2227a9e7 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/functions/Porod.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/functions/Porod.py @@ -30,7 +30,7 @@ class Porod(IFunction1D): """ Provide a Porod model for SANS - + I(q) = C/q^4 + background """ def category(self): diff --git a/Code/Mantid/Framework/PythonInterface/plugins/functions/TeixeiraWater.py b/Code/Mantid/Framework/PythonInterface/plugins/functions/TeixeiraWater.py index 815faac3bc8f..a3ebf62a493b 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/functions/TeixeiraWater.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/functions/TeixeiraWater.py @@ -55,8 +55,8 @@ def functionDeriv1D(self, xvals, jacobian): i = 0 for x in xvals: h = x*x*length/(tau*(1+x*x*length)) - jacobian.set(i,0,-h/tau); - jacobian.set(i,1,h*(1.0-h*tau)/length); + jacobian.set(i,0,-h/tau) + jacobian.set(i,1,h*(1.0-h*tau)/length) i += 1 # Required to have Mantid recognise the new function diff --git a/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoMaps_All.py b/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoMaps_All.py index bbcc5e81cd3d..71136bf0bd72 100644 --- a/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoMaps_All.py +++ b/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoMaps_All.py @@ -372,10 +372,10 @@ def findThoseTubesThatNeedSpecialCareForCalibration(filename): data = numpy.zeros((n,5)) line = 0 for row in peakTable: - data_row = [row['Peak%d'%(i)] for i in [1,2,3,4,5]] - data[line,:] = data_row - peaksId[line] = row['TubeId'] - line+=1 + data_row = [row['Peak%d'%(i)] for i in [1,2,3,4,5]] + data[line,:] = data_row + peaksId[line] = row['TubeId'] + line+=1 # data now has all the peaks positions for each tube # the mean value is the expected value for the peak position for each tube expected_peak_pos = numpy.mean(data,axis=0) diff --git a/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoMerlin.py b/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoMerlin.py index dddf9ce9f258..966213c22bcb 100644 --- a/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoMerlin.py +++ b/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoMerlin.py @@ -53,10 +53,10 @@ def analisePeakTable(pTable, peaksName='Peaks'): data = numpy.zeros((n,peaks)) line = 0 for row in pTable: - data_row = [row['Peak%d'%(i)] for i in range(1,peaks+1)] - data[line,:] = data_row - peaksId[line] = row['TubeId'] - line+=1 + data_row = [row['Peak%d'%(i)] for i in range(1,peaks+1)] + data[line,:] = data_row + peaksId[line] = row['TubeId'] + line+=1 # data now has all the peaks positions for each tube # the mean value is the expected value for the peak position for each tube expected_peak_pos = numpy.mean(data,axis=0) @@ -73,60 +73,60 @@ def analisePeakTable(pTable, peaksName='Peaks'): def calibrateMerlin(filename): # == Set parameters for calibration == - rangeLower = 3000 # Integrate counts in each spectra from rangeLower to rangeUpper - rangeUpper = 20000 # + rangeLower = 3000 # Integrate counts in each spectra from rangeLower to rangeUpper + rangeUpper = 20000 # # Get calibration raw file and integrate it - rawCalibInstWS = LoadRaw(filename) #'raw' in 'rawCalibInstWS' means unintegrated. - print "Integrating Workspace" - CalibInstWS = Integration( rawCalibInstWS, RangeLower=rangeLower, RangeUpper=rangeUpper ) - DeleteWorkspace(rawCalibInstWS) - print "Created workspace (CalibInstWS) with integrated data from run and instrument to calibrate" + rawCalibInstWS = LoadRaw(filename) #'raw' in 'rawCalibInstWS' means unintegrated. + print "Integrating Workspace" + CalibInstWS = Integration( rawCalibInstWS, RangeLower=rangeLower, RangeUpper=rangeUpper ) + DeleteWorkspace(rawCalibInstWS) + print "Created workspace (CalibInstWS) with integrated data from run and instrument to calibrate" # the known positions are given in pixels inside the tubes and transformed to provide the positions # with the center of the tube as the origin - knownPositions = 2.92713867188*(numpy.array([ 27.30074322, 92.5, 294.65178585, 362.37861919 , 512.77103043 ,663.41425323, 798.3223896, 930.9, 997.08480835])/1024 - 0.5) - funcForm = numpy.array([2,2,1,1,1,1,1,2,2],numpy.int8) + knownPositions = 2.92713867188*(numpy.array([ 27.30074322, 92.5, 294.65178585, 362.37861919 , 512.77103043 ,663.41425323, 798.3223896, 930.9, 997.08480835])/1024 - 0.5) + funcForm = numpy.array([2,2,1,1,1,1,1,2,2],numpy.int8) # The calibration will follow different steps for sets of tubes # For the door9, the best points to define the known positions are the 1st edge, 5 peaks, last edge. - points7 = knownPositions[[0,2,3,4,5,6,8]] - points7func = funcForm[[0,2,3,4,5,6,8]] + points7 = knownPositions[[0,2,3,4,5,6,8]] + points7func = funcForm[[0,2,3,4,5,6,8]] - door9pos = points7 - door9func = points7func - CalibratedComponent = 'MERLIN/door9' # door9 + door9pos = points7 + door9func = points7func + CalibratedComponent = 'MERLIN/door9' # door9 # == Get the calibration and put results into calibration table == # also put peaks into PeakFile - calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, door9pos, door9func, + calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, door9pos, door9func, outputPeak=True, margin=30, rangeList=range(20) # because 20, 21, 22, 23 are defective detectors ) - print "Got calibration (new positions of detectors) and put slit peaks into file TubeDemoMerlin01.txt" - analisePeakTable(peakTable, 'door9_tube1_peaks') + print "Got calibration (new positions of detectors) and put slit peaks into file TubeDemoMerlin01.txt" + analisePeakTable(peakTable, 'door9_tube1_peaks') # For the door8, the best points to define the known positions are the 1st edge, 5 peaks, last_edge - door8pos = points7 - door8func = points7func - CalibratedComponent = 'MERLIN/door8' - calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, door8pos, + door8pos = points7 + door8func = points7func + CalibratedComponent = 'MERLIN/door8' + calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, door8pos, door8func, outputPeak = True, #change to peakTable to append to peakTable calibTable = calibrationTable, margin = 30) - analisePeakTable(peakTable, 'door8_peaks') + analisePeakTable(peakTable, 'door8_peaks') # For the doors 7,6,5,4, 2, 1 we may use the 9 points - doorpos = knownPositions - doorfunc = funcForm - CalibratedComponent = ['MERLIN/door%d'%(i) for i in [7,6,5,4, 2, 1]] - calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, doorpos, + doorpos = knownPositions + doorfunc = funcForm + CalibratedComponent = ['MERLIN/door%d'%(i) for i in [7,6,5,4, 2, 1]] + calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, doorpos, doorfunc, outputPeak = True, calibTable = calibrationTable, margin = 30) - analisePeakTable(peakTable, 'door1to7_peaks') + analisePeakTable(peakTable, 'door1to7_peaks') # The door 3 is a special case, because it is composed by diffent kind of tubes. # door 3 tubes: 5_8, 5_7, 5_6, 5_5, 5_4, 5_3, 5_2, 5_1, 4_8, 4_7, 4_6, 4_5, 4_4, 4_3, 4_2, 4_1, 3_8, 3_7, 3_6, 3_5, 3_4 @@ -138,87 +138,87 @@ def calibrateMerlin(filename): # NOTE: the smaller tubes they have length = 1.22879882813, but 1024 detectors # so we have to correct the known positiosn by multiplying by its lenght and dividing by the longer dimension - from tube_calib_fit_params import TubeCalibFitParams + from tube_calib_fit_params import TubeCalibFitParams # calibrating tubes 1_x - CalibratedComponent = ['MERLIN/door3/tube_1_%d'%(i) for i in range(1,9)] + CalibratedComponent = ['MERLIN/door3/tube_1_%d'%(i) for i in range(1,9)] - half_diff_center = (2.92713867188 -1.22879882813)/2 # difference among the expected center position for both tubes + half_diff_center = (2.92713867188 -1.22879882813)/2 # difference among the expected center position for both tubes # here a little bit of attempts is necessary. The efective center position and lengh is different for the calibrated tube, that # is the reason, the calibrated values of the smaller tube does not seems aligned with the others. By, finding the 'best' half_diff_center # value, the alignment occurs nicely. - half_diff_center = 0.835 # + half_diff_center = 0.835 # # the knownpositions were given with the center of the bigger tube as origin, to convert # to the center of the upper tube as origin is necessary to subtract them with the half_diff_center - doorpos = knownPositions[[5,6,7,8]] - half_diff_center - doorfunc = [1,1,2,2] + doorpos = knownPositions[[5,6,7,8]] - half_diff_center + doorfunc = [1,1,2,2] # for the smal tubes, automatically searching for the peak position in pixel was not working quite well, # so we will give the aproximate position for these tubes through fitPar argument - fitPar = TubeCalibFitParams([216, 527, 826, 989]) - fitPar.setAutomatic(True) + fitPar = TubeCalibFitParams([216, 527, 826, 989]) + fitPar.setAutomatic(True) - calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, doorpos, + calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, doorpos, doorfunc, outputPeak = True, fitPar = fitPar, calibTable = calibrationTable, margin = 30) - analisePeakTable(peakTable, 'door3_tube1_peaks') + analisePeakTable(peakTable, 'door3_tube1_peaks') # calibrating tubes 2_x - CalibratedComponent = ['MERLIN/door3/tube_2_%d'%(i) for i in range(1,9)] + CalibratedComponent = ['MERLIN/door3/tube_2_%d'%(i) for i in range(1,9)] # the knownpositions were given with the center of the bigger tube as origin, to convert # to the center of the lower tube as origin is necessary to sum them with (len_big - len_small)/2 - doorpos = knownPositions[[0,1,2,3]] + half_diff_center + doorpos = knownPositions[[0,1,2,3]] + half_diff_center # print doorpos - doorfunc = [2,2,1,1] + doorfunc = [2,2,1,1] # for the smal tubes, automatically searching for the peak position in pixel was not working quite well, # so we will give the aproximate position for these tubes through fitPar argument - fitPar = TubeCalibFitParams([50, 202, 664, 815]) - fitPar.setAutomatic(True) + fitPar = TubeCalibFitParams([50, 202, 664, 815]) + fitPar.setAutomatic(True) - calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, doorpos, + calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, doorpos, doorfunc, outputPeak = True, calibTable = calibrationTable, fitPar = fitPar, margin = 30) - analisePeakTable(peakTable, 'door3_tube2_peaks') + analisePeakTable(peakTable, 'door3_tube2_peaks') # calibrating tubes 3_3,3_2,3_1 - CalibratedComponent = ['MERLIN/door3/tube_3_%d'%(i) for i in [1,2,3]] - doorpos = knownPositions[[0,1,2,3,5,6,7,8]] - doorfunc = funcForm[[0,1,2,3,5,6,7,8]] - calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, doorpos, + CalibratedComponent = ['MERLIN/door3/tube_3_%d'%(i) for i in [1,2,3]] + doorpos = knownPositions[[0,1,2,3,5,6,7,8]] + doorfunc = funcForm[[0,1,2,3,5,6,7,8]] + calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, doorpos, doorfunc, outputPeak = True, calibTable = calibrationTable, margin = 30) - analisePeakTable(peakTable, 'door3_123_peaks') + analisePeakTable(peakTable, 'door3_123_peaks') # calibrating others inside door3 # 5_8, 5_7, 5_6, 5_5, 5_4, 5_3, 5_2, 5_1, 4_8, 4_7, 4_6, 4_5, 4_4, 4_3, 4_2, 4_1, 3_8, 3_7, 3_6, 3_5, 3_4 - part_3 = ['MERLIN/door3/tube_3_%d'%(i) for i in [4,5,6,7,8]] - part_4 = ['MERLIN/door3/tube_4_%d'%(i) for i in range(1,9)] - part_5 = ['MERLIN/door3/tube_5_%d'%(i) for i in range(1,9)] - CalibratedComponent = part_3 + part_4 + part_5 - doorpos = knownPositions - doorfunc = funcForm - calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, doorpos, + part_3 = ['MERLIN/door3/tube_3_%d'%(i) for i in [4,5,6,7,8]] + part_4 = ['MERLIN/door3/tube_4_%d'%(i) for i in range(1,9)] + part_5 = ['MERLIN/door3/tube_5_%d'%(i) for i in range(1,9)] + CalibratedComponent = part_3 + part_4 + part_5 + doorpos = knownPositions + doorfunc = funcForm + calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, doorpos, doorfunc, outputPeak = True, calibTable = calibrationTable, margin = 30) - analisePeakTable(peakTable, 'door3_peaks') + analisePeakTable(peakTable, 'door3_peaks') # == Apply the Calibation == - ApplyCalibration( Workspace=CalibInstWS, PositionTable=calibrationTable) - print "Applied calibration" + ApplyCalibration( Workspace=CalibInstWS, PositionTable=calibrationTable) + print "Applied calibration" # == Save workspace == #SaveNexusProcessed( CalibInstWS, 'TubeCalibDemoMerlinResult.nxs',"Result of Running TCDemoMerlin.py") @@ -226,5 +226,5 @@ def calibrateMerlin(filename): if __name__=="__main__": - filename = 'MER12024.raw' # Calibration run ( found in \\isis\inst$\NDXMERLIN\Instrument\data\cycle_11_5 ) - calibrateMerlin(filename) + filename = 'MER12024.raw' # Calibration run ( found in \\isis\inst$\NDXMERLIN\Instrument\data\cycle_11_5 ) + calibrateMerlin(filename) diff --git a/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoWish_5panels.py b/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoWish_5panels.py index 9fa967b803d5..9d4bec946929 100644 --- a/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoWish_5panels.py +++ b/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoWish_5panels.py @@ -68,7 +68,7 @@ def CalibrateWish( run_per_panel_list): # copy data from the current panel to the whole_instrument for i in range(tube_set.getNumTubes()): for spec_num in tube_set.getTube(i): - whole_instrument.setY(spec_num,ws.dataY(spec_num)) + whole_instrument.setY(spec_num,ws.dataY(spec_num)) # calibrate the whole_instrument with the last calibrated panel which has the calibration accumulation # of all the others @@ -80,5 +80,5 @@ def CalibrateWish( run_per_panel_list): if __name__ == "__main__": # this file is found on cycle_11_1 - run_per_panel_list = [ (17706, 'panel01'), (17705, 'panel02'), (17701, 'panel03'), (17702, 'panel04'), (17695, 'panel05')] - CalibrateWish(run_per_panel_list) + run_per_panel_list = [ (17706, 'panel01'), (17705, 'panel02'), (17701, 'panel03'), (17702, 'panel04'), (17695, 'panel05')] + CalibrateWish(run_per_panel_list) diff --git a/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoWish_Simple.py b/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoWish_Simple.py index 404bbd6ef09d..4736c9a00f24 100644 --- a/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoWish_Simple.py +++ b/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoWish_Simple.py @@ -67,6 +67,6 @@ def CalibrateWish( RunNumber, PanelNumber): # ==== End of CalibrateWish() ==== if __name__ == "__main__": # this file is found on cycle_11_1 - RunNumber = 17701 - PanelNumber = '03' - CalibrateWish(RunNumber, PanelNumber) + RunNumber = 17701 + PanelNumber = '03' + CalibrateWish(RunNumber, PanelNumber) diff --git a/Code/Mantid/scripts/Calibration/ideal_tube.py b/Code/Mantid/scripts/Calibration/ideal_tube.py index 086cb3c22de2..a77ce0b84e3d 100644 --- a/Code/Mantid/scripts/Calibration/ideal_tube.py +++ b/Code/Mantid/scripts/Calibration/ideal_tube.py @@ -6,7 +6,7 @@ # Author: Karl Palmen ISIS class IdealTube: - """ + """ The IdealTube specifies where the peaks formed by slits or edges should occur. They can be considered as the known positions as well. @@ -27,40 +27,40 @@ class IdealTube: * :meth:`~ideal_tube.IdealTube.getFunctionalForms` """ - def __init__( self ): + def __init__( self ): """ Create empty instance """ self.positions = numpy.ndarray((0)) # position of the points in metres self.functionalForms = [] # function form of points 1=peak 2=edge. peaks assumed if []. - def setArray ( self, array ): - """ + def setArray ( self, array ): + """ Construct an ideal tube directly from an array of positions :param points: Array of points where the peaks should be in Metres """ - self.positions =numpy.array( array) + self.positions =numpy.array( array) - def setForm(self, form): - """Define the functional form for the peaks""" - self.functionalForms = form + def setForm(self, form): + """Define the functional form for the peaks""" + self.functionalForms = form - def setPositionsAndForm ( self, pos, form ): - """ + def setPositionsAndForm ( self, pos, form ): + """ Construct and ideal tube directly from an array of positions and functional forms :param pos: Array of points where the peaks or edges should be in Metres :param form: Array of functional forms of the points 1=peak, 2=edge """ - self.positions = numpy.array(pos ) - self.functionalForms = form + self.positions = numpy.array(pos ) + self.functionalForms = form - def constructTubeFor3PointsMethod( self, idealAP, idealBP, idealCP, activeTubeLen ): - """ + def constructTubeFor3PointsMethod( self, idealAP, idealBP, idealCP, activeTubeLen ): + """ Construct and ideal tube for Merlin 3-point calibration :param idealAP: Ideal left (AP) in pixels @@ -70,22 +70,22 @@ def constructTubeFor3PointsMethod( self, idealAP, idealBP, idealCP, activeTubeLe """ #Contruct Ideal tube for 3 point calibration of MERLIN standard tube (code could be put into a function) - pixelLen = activeTubeLen/1024 # Pixel length + pixelLen = activeTubeLen/1024 # Pixel length # we then convert idealAP, idealCP and idealBP to Y coordinates and put into ideal tube array - self.positions = numpy.array([ idealAP*pixelLen - activeTubeLen/2, idealCP*pixelLen - activeTubeLen/2, idealBP*pixelLen - activeTubeLen/2]) - self.functionalForms = [ 2, 1, 2 ] + self.positions = numpy.array([ idealAP*pixelLen - activeTubeLen/2, idealCP*pixelLen - activeTubeLen/2, idealBP*pixelLen - activeTubeLen/2]) + self.functionalForms = [ 2, 1, 2 ] - def getArray( self ): - """ + def getArray( self ): + """ Reurn the array of of points where the peaks should be in Metres """ - return self.positions + return self.positions - def getFunctionalForms( self ): - """ + def getFunctionalForms( self ): + """ Reurn the array of of points where the peaks should be in Metres """ - return self.functionalForms + return self.functionalForms diff --git a/Code/Mantid/scripts/Calibration/tube_calib.py b/Code/Mantid/scripts/Calibration/tube_calib.py index cc6aeda7652c..91c3f8fd5b7a 100644 --- a/Code/Mantid/scripts/Calibration/tube_calib.py +++ b/Code/Mantid/scripts/Calibration/tube_calib.py @@ -43,9 +43,9 @@ def createTubeCalibtationWorkspaceByWorkspaceIndexList ( integratedWorkspace, ou pixel = 1 #integratedWorkspace. for i in workspaceIndexList: - pixelNumbers.append(pixel) - pixel = pixel + 1 - integratedPixelCounts.append( integratedWorkspace.dataY(i)[0] ) + pixelNumbers.append(pixel) + pixel = pixel + 1 + integratedPixelCounts.append( integratedWorkspace.dataY(i)[0] ) CreateWorkspace(dataX=pixelNumbers,dataY=integratedPixelCounts, OutputWorkspace=outputWorkspace) #if (showPlot): @@ -210,20 +210,20 @@ def getPoints ( IntegratedWorkspace, funcForms, fitParams, whichTube, showPlot=F # Loop over the points for i in range(len(funcForms)): - if funcForms[i] == 2: + if funcForms[i] == 2: # find the edge position - peakIndex = fitEdges(fitParams, i, getPointsWs, calibPointWs) - else: - peakIndex = fitGaussian(fitParams, i, getPointsWs, calibPointWs) + peakIndex = fitEdges(fitParams, i, getPointsWs, calibPointWs) + else: + peakIndex = fitGaussian(fitParams, i, getPointsWs, calibPointWs) # get the peak centre - peakCentre = mtd[calibPointWs + '_Parameters'].row(peakIndex).items()[1][1] - results.append(peakCentre) + peakCentre = mtd[calibPointWs + '_Parameters'].row(peakIndex).items()[1][1] + results.append(peakCentre) - if showPlot: - ws = mtd[calibPointWs + '_Workspace'] - fitt_y_values.append(copy.copy(ws.dataY(1))) - fitt_x_values.append(copy.copy(ws.dataX(1))) + if showPlot: + ws = mtd[calibPointWs + '_Workspace'] + fitt_y_values.append(copy.copy(ws.dataY(1))) + fitt_x_values.append(copy.copy(ws.dataX(1))) if showPlot: FittedData = CreateWorkspace(numpy.hstack(fitt_x_values), @@ -329,10 +329,10 @@ def correctTubeToIdealTube( tubePoints, idealTubePoints, nDets, TestMode=False, # Fit quadratic to ideal tube points CreateWorkspace(dataX=usedTubePoints,dataY=usedIdealTubePoints, OutputWorkspace="PolyFittingWorkspace") try: - Fit(InputWorkspace="PolyFittingWorkspace",Function='name=Polynomial,n=%d'%(polinFit),StartX=str(0.0),EndX=str(nDets),Output="QF") + Fit(InputWorkspace="PolyFittingWorkspace",Function='name=Polynomial,n=%d'%(polinFit),StartX=str(0.0),EndX=str(nDets),Output="QF") except: - print "Fit failed" - return [] + print "Fit failed" + return [] paramQF = mtd['QF_Parameters'] @@ -349,7 +349,7 @@ def correctTubeToIdealTube( tubePoints, idealTubePoints, nDets, TestMode=False, print "TestMode code" for i in range( len(usedTubePoints) ): #print "used point",i,"shoving pixel",int(usedTubePoints[i]) - xResult[ int(usedTubePoints[i]) ] = xResult[0] + xResult[ int(usedTubePoints[i]) ] = xResult[0] # print xResult return xResult @@ -383,8 +383,8 @@ def getCalibratedPixelPositions( ws, tubePts, idealTubePts, whichTube, peakTestM pixels = correctTubeToIdealTube ( tubePts, idealTubePts, nDets, TestMode=peakTestMode, polinFit=polinFit ) #print pixels if( len(pixels) != nDets): - print "Tube correction failed." - return detIDs, detPositions + print "Tube correction failed." + return detIDs, detPositions baseInstrument = ws.getInstrument().getBaseInstrument() # Get tube unit vector # get the detector from the baseInstrument, in order to get the positions @@ -502,9 +502,9 @@ def getCalibration( ws, tubeSet, calibTable, fitPar, iTube, peaksTable, print "Calibrating tube", i+1,"of",nTubes, tubeSet.getTubeName(i) if ( len(wht) < 1 ): - print "Unable to get any workspace indices (spectra) for this tube. Tube",tubeSet.getTubeName(i),"not calibrated." + print "Unable to get any workspace indices (spectra) for this tube. Tube",tubeSet.getTubeName(i),"not calibrated." #skip this tube - continue + continue # Calibribate the tube, if possible if (tubeSet.getTubeLength(i) <= excludeShortTubes): @@ -599,7 +599,7 @@ def getCalibrationFromPeakFile ( ws, calibTable, iTube, PeakFile ): calibTable.addRow ( nextRow ) if(nTubes == 0): - return + return # Delete temporary workspaces for getting new detector positions DeleteWorkspace('PolyFittingWorkspace') @@ -611,7 +611,7 @@ def getCalibrationFromPeakFile ( ws, calibTable, iTube, PeakFile ): ## implement this function def constructIdealTubeFromRealTube( ws, tube, fitPar, funcForm ): - """ + """ Construct an ideal tube from an actual tube (assumed ideal) :param ws: integrated workspace @@ -622,32 +622,32 @@ def constructIdealTubeFromRealTube( ws, tube, fitPar, funcForm ): """ # Get workspace indices - idealTube = IdealTube() + idealTube = IdealTube() - nTubes = tube.getNumTubes() - if(nTubes < 1): - raise RuntimeError("Invalid tube specification received by constructIdealTubeFromRealTube") - elif(nTubes > 1): - print "Specification has several tubes. The ideal tube will be based on the first tube",tube.getTubeName(0) + nTubes = tube.getNumTubes() + if(nTubes < 1): + raise RuntimeError("Invalid tube specification received by constructIdealTubeFromRealTube") + elif(nTubes > 1): + print "Specification has several tubes. The ideal tube will be based on the first tube",tube.getTubeName(0) - wht, _ = tube.getTube(0) + wht, _ = tube.getTube(0) # print wht # Check tube - if ( len(wht) < 1 ): + if ( len(wht) < 1 ): raise RuntimeError("Unable to get any workspace indices for this tube. Cannot use as ideal tube.") # Get actual tube on which ideal tube is based - actualTube = getPoints ( ws, funcForm, fitPar, wht) - print "Actual tube that ideal tube is to be based upon",actualTube + actualTube = getPoints ( ws, funcForm, fitPar, wht) + print "Actual tube that ideal tube is to be based upon",actualTube # Get ideal tube based on this actual tube - try: - idealTube.setArray(actualTube) - except: - msg = "Attempted to create ideal tube based on actual tube" + str(actualTube) - msg += "Unable to create ideal tube." - msg += "Please choose another tube for constructIdealTubeFromRealTube()." - raise RuntimeError(msg) - return idealTube + try: + idealTube.setArray(actualTube) + except: + msg = "Attempted to create ideal tube based on actual tube" + str(actualTube) + msg += "Unable to create ideal tube." + msg += "Please choose another tube for constructIdealTubeFromRealTube()." + raise RuntimeError(msg) + return idealTube diff --git a/Code/Mantid/scripts/Calibration/tube_spec.py b/Code/Mantid/scripts/Calibration/tube_spec.py index e22d27871c9e..4ce88e2224c2 100644 --- a/Code/Mantid/scripts/Calibration/tube_spec.py +++ b/Code/Mantid/scripts/Calibration/tube_spec.py @@ -91,7 +91,7 @@ def setTubeSpecByStringArray( self, tubeSpecArray ): """ for i in range(len(tubeSpecArray)): - self.setTubeSpecByString(tubeSpecArray[i]) + self.setTubeSpecByString(tubeSpecArray[i]) def getInstrumentName (self): @@ -107,26 +107,26 @@ def isTube(self, comp): """ # We simply assume it's a tube if it has a large number of children if( hasattr( comp, "nelements")): - return (comp.nelements() >= self.minNumDetsInTube ) + return (comp.nelements() >= self.minNumDetsInTube ) else: - return False + return False def searchForTubes(self, comp): - """ + """ Searches the component for tubes and saves them in array, appending if array is not empty. :param comp: the component """ # Go through all descendents that are not a descendent of a tube and if it's a tube, store and count it. - if self.isTube( comp ): - self.tubes.append( comp ) + if self.isTube( comp ): + self.tubes.append( comp ) #print "Tube found", comp.getName() # If not tube, Search children, if any - else: - if( hasattr( comp, "nelements")): - for i in range(comp.nelements()): - self.searchForTubes(comp[i]) + else: + if( hasattr( comp, "nelements")): + for i in range(comp.nelements()): + self.searchForTubes(comp[i]) def getNumTubes(self): @@ -144,7 +144,7 @@ def getNumTubes(self): return self.numTubes for i in range( len(comps)): - self.searchForTubes(comps[i]) + self.searchForTubes(comps[i]) self.numTubes = len(self.tubes) return self.numTubes @@ -165,7 +165,7 @@ def getComponent ( self ): comp = self.inst.getComponentByName(self.componentNameArray[0]) if( comp ): - self.componentArray.append(comp) + self.componentArray.append(comp) return self.componentArray[0] @@ -181,9 +181,9 @@ def getComponents ( self ): # We look for the components for i in range( len(self.componentNameArray)): - print "Looking for", self.componentNameArray[i] + print "Looking for", self.componentNameArray[i] - comp = self.inst.getComponentByName(self.componentNameArray[i]) + comp = self.inst.getComponentByName(self.componentNameArray[i]) if( comp ): self.componentArray.append(comp) @@ -214,11 +214,11 @@ def getDetectorInfoFromTube( self, tubeIx ): """ nTubes = self.getNumTubes() if(nTubes < 0): - print "Error in listing tubes" - return 0, 0, 1 + print "Error in listing tubes" + return 0, 0, 1 if(tubeIx < 0 or tubeIx >= nTubes): - print "Tube index",tubeIx,"out of range 0 to",nTubes - return 0, 0, 1 + print "Tube index",tubeIx,"out of range 0 to",nTubes + return 0, 0, 1 comp = self.tubes[tubeIx] @@ -228,15 +228,15 @@ def getDetectorInfoFromTube( self, tubeIx ): # Allow for reverse numbering of Detectors lastDet = comp[numDet-1].getID() if (lastDet < firstDet): - step = -1 - if( firstDet - lastDet + 1 != numDet): - print "Detector number range",firstDet-lastDet+1," not equal to number of detectors",numDet - print "Detectors not numbered continuously in this tube. Calibration will fail for this tube." + step = -1 + if( firstDet - lastDet + 1 != numDet): + print "Detector number range",firstDet-lastDet+1," not equal to number of detectors",numDet + print "Detectors not numbered continuously in this tube. Calibration will fail for this tube." else: - step = 1 - if( lastDet - firstDet + 1 != numDet): - print "Detector number range",lastDet-firstDet+1," not equal to number of detectors",numDet - print "Detectors not numbered continuously in this tube. Calibration will fail for this tube." + step = 1 + if( lastDet - firstDet + 1 != numDet): + print "Detector number range",lastDet-firstDet+1," not equal to number of detectors",numDet + print "Detectors not numbered continuously in this tube. Calibration will fail for this tube." #print "First dectector ", firstDet," Last detector ", firstDet+numDet-1, "Number of detectors ", numDet #print "First dectector ", firstDet," Last detector ", comp[numDet-1].getID() @@ -286,11 +286,11 @@ def getTubeName ( self, tubeIx ): """ nTubes = self.getNumTubes() if(nTubes < 0): - print "Error in listing tubes" - return 'Unknown' + print "Error in listing tubes" + return 'Unknown' if(tubeIx < 0 or tubeIx >= nTubes): - print "Tube index",tubeIx,"out of range 0 to",nTubes - return 'Unknown' + print "Tube index",tubeIx,"out of range 0 to",nTubes + return 'Unknown' comp = self.tubes[tubeIx] diff --git a/Code/Mantid/scripts/Engineering/EnginXUtils.py b/Code/Mantid/scripts/Engineering/EnginXUtils.py index 4aa0d044a4d7..15f74b45b94b 100644 --- a/Code/Mantid/scripts/Engineering/EnginXUtils.py +++ b/Code/Mantid/scripts/Engineering/EnginXUtils.py @@ -18,13 +18,13 @@ def getDetIDsForBank(bank): detIDs = set() for i in range(grouping.getNumberHistograms()): - if grouping.readY(i)[0] == bank: - detIDs.add(grouping.getDetector(i).getID()) + if grouping.readY(i)[0] == bank: + detIDs.add(grouping.getDetector(i).getID()) DeleteWorkspace(grouping) if len(detIDs) == 0: - raise Exception('Unknown bank') + raise Exception('Unknown bank') return detIDs @@ -34,11 +34,11 @@ def getWsIndicesForBank(bank, ws): detIDs = getDetIDsForBank(bank) def isIndexInBank(index): - try: - det = ws.getDetector(index) - return (det.getID() in detIDs) - except: - return False + try: + det = ws.getDetector(index) + return (det.getID() in detIDs) + except: + return False return filter(isIndexInBank, range(0, ws.getNumberHistograms())) diff --git a/Code/Mantid/scripts/FilterEvents.py b/Code/Mantid/scripts/FilterEvents.py index ef661b20f72e..3b14caff0bfe 100644 --- a/Code/Mantid/scripts/FilterEvents.py +++ b/Code/Mantid/scripts/FilterEvents.py @@ -2,13 +2,13 @@ from PyQt4 import QtGui import sys -def qapp(): - if QtGui.QApplication.instance(): - app = QtGui.QApplication.instance() - else: - app = QtGui.QApplication(sys.argv) +def qapp(): + if QtGui.QApplication.instance(): + app = QtGui.QApplication.instance() + else: + app = QtGui.QApplication(sys.argv) return app - + app = qapp() reducer = eventFilterGUI.MainWindow() #the main ui class in this file is called MainWindow diff --git a/Code/Mantid/scripts/FilterEvents/MplFigureCanvas.py b/Code/Mantid/scripts/FilterEvents/MplFigureCanvas.py index 183e6d9a55be..70749903430c 100644 --- a/Code/Mantid/scripts/FilterEvents/MplFigureCanvas.py +++ b/Code/Mantid/scripts/FilterEvents/MplFigureCanvas.py @@ -6,7 +6,7 @@ from matplotlib.figure import Figure class Qt4MplCanvas(FigureCanvas): - """ A customized Qt widget for matplotlib figure. + """ A customized Qt widget for matplotlib figure. It can be used to replace GraphicsView of QtGui """ def __init__(self, parent): @@ -21,7 +21,7 @@ def __init__(self, parent): self.setParent(parent) # Set size policy to be able to expanding and resizable with frame - FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding, + FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) FigureCanvas.updateGeometry(self) @@ -29,7 +29,7 @@ def __init__(self, parent): return def plot(self, x, y): - """ Plot a set of data + """ Plot a set of data Argument: - x: numpy array X - y: numpy array Y @@ -41,6 +41,6 @@ def plot(self, x, y): return def getPlot(self): - """ reture figure's axes to expose the matplotlib figure to PyQt client + """ reture figure's axes to expose the matplotlib figure to PyQt client """ return self.axes diff --git a/Code/Mantid/scripts/FilterEvents/Ui_MainWindow.py b/Code/Mantid/scripts/FilterEvents/Ui_MainWindow.py index 9b19740180a2..4f757a818fc9 100644 --- a/Code/Mantid/scripts/FilterEvents/Ui_MainWindow.py +++ b/Code/Mantid/scripts/FilterEvents/Ui_MainWindow.py @@ -7,8 +7,8 @@ # # WARNING! All changes made in this file will be lost! -from PyQt4 import QtCore, QtGui -from MplFigureCanvas import Qt4MplCanvas +from PyQt4 import QtCore, QtGui +from MplFigureCanvas import Qt4MplCanvas try: diff --git a/Code/Mantid/scripts/FilterEvents/eventFilterGUI.py b/Code/Mantid/scripts/FilterEvents/eventFilterGUI.py index 49d9cc7973c7..5a8a55e32d60 100644 --- a/Code/Mantid/scripts/FilterEvents/eventFilterGUI.py +++ b/Code/Mantid/scripts/FilterEvents/eventFilterGUI.py @@ -15,7 +15,7 @@ import mantid import mantid.simpleapi as api import mantid.kernel -from mantid.simpleapi import AnalysisDataService +from mantid.simpleapi import AnalysisDataService from mantid.kernel import ConfigService @@ -72,19 +72,19 @@ def XpaintEvent(self, e): return -class MainWindow(QtGui.QMainWindow): +class MainWindow(QtGui.QMainWindow): """ Class of Main Window (top) Copy to ui.setupUI # Version 3.0 + Import for Ui_MainWindow.py - from MplFigureCanvas import Qt4MplCanvas + from MplFigureCanvas import Qt4MplCanvas # Replace 'self.graphicsView = QtGui.QtGraphicsView' with the following self.graphicsView = Qt4MplCanvas(self.centralwidget) self.mainplot = self.graphicsView.getPlot() - + # Version 2.0 + Import import matplotlib from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas @@ -109,10 +109,10 @@ class MainWindow(QtGui.QMainWindow): self.ui.graphicsView.setGeometry(QtCore.QRect(40, 230, 821, 411)) self.ui.graphicsView.setObjectName(_fromUtf8("graphicsView")) - """ - + """ + def __init__(self, parent=None): - """ Intialization and set up + """ Intialization and set up """ # Base class QtGui.QMainWindow.__init__(self,parent) @@ -121,11 +121,11 @@ def __init__(self, parent=None): config = ConfigService.Instance() self._instrument = config["default.instrument"] - # Central widget + # Central widget self.centralwidget = QtGui.QWidget(self) - # UI Window (from Qt Designer) - self.ui = Ui_MainWindow() + # UI Window (from Qt Designer) + self.ui = Ui_MainWindow() self.ui.setupUi(self) # Do initialize plotting @@ -163,12 +163,12 @@ def __init__(self, parent=None): self.ui.horizontalSlider_2.setTracking(True) self.ui.horizontalSlider_2.setTickPosition(QSlider.NoTicks) self.connect(self.ui.horizontalSlider_2, SIGNAL('valueChanged(int)'), self.move_rightSlider) - - # self.connect(self.ui.lineEdit_3, QtCore.SIGNAL("textChanged(QString)"), - # self.set_startTime) + + # self.connect(self.ui.lineEdit_3, QtCore.SIGNAL("textChanged(QString)"), + # self.set_startTime) self.ui.lineEdit_3.setValidator(QtGui.QDoubleValidator(self.ui.lineEdit_3)) - self.connect(self.ui.pushButton_setT0, QtCore.SIGNAL("clicked()"), self.set_startTime) - # self.connect(self.ui.lineEdit_4, QtCore.SIGNAL("textChanged(QString)"), + self.connect(self.ui.pushButton_setT0, QtCore.SIGNAL("clicked()"), self.set_startTime) + # self.connect(self.ui.lineEdit_4, QtCore.SIGNAL("textChanged(QString)"), # self.set_stopTime) self.ui.lineEdit_4.setValidator(QtGui.QDoubleValidator(self.ui.lineEdit_4)) self.connect(self.ui.pushButton_setTf, QtCore.SIGNAL("clicked()"), self.set_stopTime) @@ -194,11 +194,11 @@ def __init__(self, parent=None): self.ui.lineEdit_7.setValidator(QtGui.QDoubleValidator(self.ui.lineEdit_7)) self.ui.lineEdit_8.setValidator(QtGui.QDoubleValidator(self.ui.lineEdit_8)) self.ui.lineEdit_9.setValidator(QtGui.QDoubleValidator(self.ui.lineEdit_9)) - - self.connect(self.ui.lineEdit_5, QtCore.SIGNAL("textChanged(QString)"), - self.set_minLogValue) - self.connect(self.ui.lineEdit_6, QtCore.SIGNAL("textChanged(QString)"), - self.set_maxLogValue) + + self.connect(self.ui.lineEdit_5, QtCore.SIGNAL("textChanged(QString)"), + self.set_minLogValue) + self.connect(self.ui.lineEdit_6, QtCore.SIGNAL("textChanged(QString)"), + self.set_maxLogValue) dirchangeops = ["Both", "Increase", "Decrease"] self.ui.comboBox_4.addItems(dirchangeops) @@ -230,7 +230,7 @@ def __init__(self, parent=None): self.ui.checkBox_from1.setChecked(False) self.ui.checkBox_groupWS.setChecked(True) - self.connect(self.ui.comboBox_tofCorr, SIGNAL('currentIndexChanged(int)'), self.showHideEi) + self.connect(self.ui.comboBox_tofCorr, SIGNAL('currentIndexChanged(int)'), self.showHideEi) self.connect(self.ui.pushButton_refreshCorrWSList, SIGNAL('clicked()'), self._searchTableWorkspaces) self.ui.lineEdit_Ei.setValidator(QtGui.QDoubleValidator(self.ui.lineEdit_Ei)) @@ -254,8 +254,8 @@ def __init__(self, parent=None): # Side information self.ui.label_mean.hide() self.ui.label_meanvalue.hide() - self.ui.label_avg.hide() - self.ui.label_timeAvgValue.hide() + self.ui.label_avg.hide() + self.ui.label_timeAvgValue.hide() self.ui.label_freq.hide() self.ui.label_freqValue.hide() self.ui.label_logname.hide() @@ -263,15 +263,15 @@ def __init__(self, parent=None): self.ui.label_logsize.hide() self.ui.label_logsizevalue.hide() - # Default + # Default self._defaultdir = os.getcwd() # self.ui.InputVal.setValidator(QtGui.QDoubleValidator(self.ui.InputVal)) - + # QtCore.QObject.connect(self.ui.convert, QtCore.SIGNAL("clicked()"), self.convert ) # QtCore.QObject.connect(self.ui.inputUnits, QtCore.SIGNAL("currentIndexChanged(QString)"), self.setInstrumentInputs ) # QtCore.QObject.connect(self.ui.outputUnits, QtCore.SIGNAL("currentIndexChanged(QString)"), self.setInstrumentInputs ) - # self.setInstrumentInputs() + # self.setInstrumentInputs() ##defaults @@ -284,7 +284,7 @@ def on_mouseDownEvent(self, event): x = event.xdata y = event.ydata - if x is not None and y is not None: + if x is not None and y is not None: msg = "You've clicked on a bar with coords:\n %f, %f" % (x, y) QMessageBox.information(self, "Click!", msg) @@ -302,7 +302,7 @@ def computeMock(self): vecx = [] vecy = [] - + x = x0 while x < xf: y = 0.0 @@ -317,9 +317,9 @@ def computeMock(self): def move_leftSlider(self): - """ Re-setup left range line in figure. - Triggered by a change in Qt Widget. NO EVENT is required. - """ + """ Re-setup left range line in figure. + Triggered by a change in Qt Widget. NO EVENT is required. + """ newx = self.ui.horizontalSlider.value() if newx <= self._rightSlideValue and newx != self._leftSlideValue: # Allowed value: move the value bar @@ -349,12 +349,12 @@ def set_startTime(self): """ inps = str(self.ui.lineEdit_3.text()) print "Starting time = %s" % (inps) - + xlim = self.ui.mainplot.get_xlim() if inps == "": # Empty. Use default newtime0 = xlim[0] - else: + else: newtime0 = float(inps) # Convert to integer slide value @@ -390,18 +390,18 @@ def set_startTime(self): self.ui.graphicsView.draw() - # Set the value to left slider + # Set the value to left slider self.ui.horizontalSlider.setValue(self._leftSlideValue) - # Reset the value of line edit - if resetT is True: + # Reset the value of line edit + if resetT is True: self.ui.lineEdit_3.setText(str(newtime0)) return def move_rightSlider(self): - """ Re-setup left range line in figure. - Triggered by a change in Qt Widget. NO EVENT is required. - """ + """ Re-setup left range line in figure. + Triggered by a change in Qt Widget. NO EVENT is required. + """ newx = self.ui.horizontalSlider_2.value() if newx >= self._leftSlideValue and newx != self._rightSlideValue: # Allowed value: move the value bar @@ -430,13 +430,13 @@ def set_stopTime(self): """ inps = str(self.ui.lineEdit_4.text()) print "Stopping time = %s" % (inps) - + xlim = self.ui.mainplot.get_xlim() if inps == "": # Empty. Use default newtimef = xlim[1] else: - # Parse + # Parse newtimef = float(inps) # Convert to integer slide value @@ -469,7 +469,7 @@ def set_stopTime(self): self.ui.graphicsView.draw() - # Set the value to left slider + # Set the value to left slider self.ui.horizontalSlider_2.setValue(self._rightSlideValue) # Reset to line edit @@ -479,9 +479,9 @@ def set_stopTime(self): return def move_lowerSlider(self): - """ Re-setup upper range line in figure. - Triggered by a change in Qt Widget. NO EVENT is required. - """ + """ Re-setup upper range line in figure. + Triggered by a change in Qt Widget. NO EVENT is required. + """ inewy = self.ui.verticalSlider_2.value() print "LowerSlider is set with value %d vs. class variable %d" % (inewy, self._lowerSlideValue) @@ -509,7 +509,7 @@ def move_lowerSlider(self): self.ui.graphicsView.draw() # Set line edit input - if setLineEdit is True: + if setLineEdit is True: # Change value to line edit (5) self.ui.lineEdit_5.setText(str(newy)) # Reset the class variable @@ -523,11 +523,11 @@ def set_minLogValue(self): print "Minimum Log Value = %s" %(str(self.ui.lineEdit_5.text())) ylim = self.ui.mainplot.get_ylim() - + if str(self.ui.lineEdit_5.text()) == "": # Empty. Default to minY newminY = ylim[0] - else: + else: # Non empty. Parse newminY = float(self.ui.lineEdit_5.text()) @@ -551,7 +551,7 @@ def set_minLogValue(self): # Move the vertical line lowerx = self.ui.mainplot.get_xlim() - lowery = [newminY, newminY] + lowery = [newminY, newminY] setp(self.lowerslideline, xdata=lowerx, ydata=lowery) self.ui.graphicsView.draw() @@ -568,9 +568,9 @@ def set_minLogValue(self): return def move_upperSlider(self): - """ Re-setup upper range line in figure. - Triggered by a change in Qt Widget. NO EVENT is required. - """ + """ Re-setup upper range line in figure. + Triggered by a change in Qt Widget. NO EVENT is required. + """ inewy = self.ui.verticalSlider.value() # Return w/o change @@ -640,7 +640,7 @@ def set_maxLogValue(self): # Move the vertical line upperx = self.ui.mainplot.get_xlim() - uppery = [newmaxY, newmaxY] + uppery = [newmaxY, newmaxY] setp(self.upperslideline, xdata=upperx, ydata=uppery) self.ui.graphicsView.draw() @@ -658,7 +658,7 @@ def set_maxLogValue(self): def browse_File(self): """ Open a file dialog to get file """ - filename = QtGui.QFileDialog.getOpenFileName(self, 'Input File Dialog', + filename = QtGui.QFileDialog.getOpenFileName(self, 'Input File Dialog', self._defaultdir, "Data (*.nxs *.dat);;All files (*.*)") self.ui.lineEdit.setText(str(filename)) @@ -699,10 +699,10 @@ def use_existWS(self): """ wsname = str(self.ui.comboBox.currentText()) - try: + try: dataws = AnalysisDataService.retrieve(wsname) self._importDataWorkspace(dataws) - except KeyError: + except KeyError: pass # Reset GUI @@ -725,7 +725,7 @@ def plotLogValue(self): vecvalue = samplelog.value # check - if len(vectimes) == 0: + if len(vectimes) == 0: print "Empty log!" # Convert absolute time to relative time in seconds @@ -748,7 +748,7 @@ def plotLogValue(self): self.ui.mainplot.set_xlim(xlim[0], xlim[1]) self.ui.mainplot.set_ylim(ylim[0], ylim[1]) - setp(self.mainline, xdata=vecreltimes, ydata=vecvalue) + setp(self.mainline, xdata=vecreltimes, ydata=vecvalue) samunit = samplelog.units if len(samunit) == 0: @@ -767,7 +767,7 @@ def plotLogValue(self): self.ui.verticalSlider_2.setValue(self._lowerSlideValue) self.ui.lineEdit_5.setText("") - setp(self.upperslideline, xdata=xlim, ydata=[ylim[1], ylim[1]]) + setp(self.upperslideline, xdata=xlim, ydata=[ylim[1], ylim[1]]) self._upperSlideValue = 100 self.ui.verticalSlider.setValue(self._upperSlideValue) self.ui.lineEdit_6.setText("") @@ -785,8 +785,8 @@ def plotLogValue(self): self.ui.label_mean.show() self.ui.label_meanvalue.show() - self.ui.label_avg.show() - self.ui.label_timeAvgValue.show() + self.ui.label_avg.show() + self.ui.label_timeAvgValue.show() self.ui.label_freq.show() self.ui.label_freqValue.show() self.ui.label_logname.show() @@ -803,7 +803,7 @@ def plotLogValue(self): # Set suggested processing scheme if numentries > HUGE_FAST: self.ui.checkBox_fastLog.setCheckState(True) - if numentries > HUGE_PARALLEL: + if numentries > HUGE_PARALLEL: self.ui.checkBox_doParallel.setCheckState(True) else: self.ui.checkBox_doParallel.setCheckState(False) @@ -817,7 +817,7 @@ def plotLogValue(self): def _importDataWorkspace(self, dataws): """ Import data workspace for filtering """ - if dataws is None: + if dataws is None: return # Plot time counts @@ -827,7 +827,7 @@ def _importDataWorkspace(self, dataws): failure! \n%s\n" % (str(dataws), errmsg) self._setErrorMsg(errmsg) return False - + # Import log self._sampleLogNames = [""] @@ -837,19 +837,19 @@ def _importDataWorkspace(self, dataws): pv = p.value if isinstance(pv, numpy.ndarray): times = p.times - if len(times) > 1: + if len(times) > 1: self._sampleLogNames.append(p.name) # ENDFOR(p) - # Set up sample log + # Set up sample log self.ui.comboBox_2.clear() self.ui.comboBox_2.addItems(self._sampleLogNames) # Side information self.ui.label_mean.hide() self.ui.label_meanvalue.hide() - self.ui.label_avg.hide() - self.ui.label_timeAvgValue.hide() + self.ui.label_avg.hide() + self.ui.label_timeAvgValue.hide() self.ui.label_freq.hide() self.ui.label_freqValue.hide() @@ -858,12 +858,12 @@ def _importDataWorkspace(self, dataws): self.ui.label_lognamevalue.hide() # Set dataws to class variable - self._dataWS = dataws + self._dataWS = dataws return True def scanEventWorkspaces(self): - """ + """ """ wsnames = AnalysisDataService.getObjectNames() @@ -874,7 +874,7 @@ def scanEventWorkspaces(self): eventwsnames.append(wsname) # ENDFOR - if len(eventwsnames) > 0: + if len(eventwsnames) > 0: self.ui.comboBox.clear() self.ui.comboBox.addItems(eventwsnames) @@ -894,7 +894,7 @@ def _loadFile(self, filename): if runnumber <= 0: print "Run number cannot be less or equal to zero. User gives %s. " % (filename) return None - else: + else: ishort = config.getInstrument(self._instrument).shortName() filename = "%s_%s" %(ishort, filename) wsname = filename + "_event" @@ -922,22 +922,22 @@ def _loadFile(self, filename): return None # Load - try: + try: ws = api.Load(Filename=filename, OutputWorkspace=wsname) except: ws = None return ws - + def _plotTimeCounts(self, wksp): - """ Plot time/counts + """ Plot time/counts """ import datetime # Rebin events by pulse time try: # Get run start and run stop - if wksp.getRun().hasProperty("run_start"): + if wksp.getRun().hasProperty("run_start"): runstart = wksp.getRun().getProperty("run_start").value else: runstart = wksp.getRun().getProperty("proton_charge").times[0] @@ -945,11 +945,11 @@ def _plotTimeCounts(self, wksp): runstart = str(runstart).split(".")[0].strip() runstop = str(runstop).split(".")[0].strip() - + t0 = datetime.datetime.strptime(runstart, "%Y-%m-%dT%H:%M:%S") tf = datetime.datetime.strptime(runstop, "%Y-%m-%dT%H:%M:%S") - - # Calcualte + + # Calcualte dt = tf-t0 timeduration = dt.days*3600*24 + dt.seconds @@ -959,7 +959,7 @@ def _plotTimeCounts(self, wksp): sumwsname = "_Summed_%s"%(str(wksp)) if AnalysisDataService.doesExist(sumwsname) is False: - sumws = api.RebinByPulseTimes(InputWorkspace=wksp, OutputWorkspace = sumwsname, + sumws = api.RebinByPulseTimes(InputWorkspace=wksp, OutputWorkspace = sumwsname, Params="0, %f, %d"%(timeres, timeduration)) sumws = api.SumSpectra(InputWorkspace=sumws, OutputWorkspace=str(sumws)) sumws = api.ConvertToPointData(InputWorkspace=sumws, OutputWorkspace=str(sumws)) @@ -976,7 +976,7 @@ def _plotTimeCounts(self, wksp): ymin = min(vecy) ymax = max(vecy) - # Reset graph + # Reset graph self.ui.mainplot.set_xlim(xmin, xmax) self.ui.mainplot.set_ylim(ymin, ymax) @@ -984,16 +984,16 @@ def _plotTimeCounts(self, wksp): self.ui.mainplot.set_ylabel('Counts', fontsize=13) # Set up main line - setp(self.mainline, xdata=vecx, ydata=vecy) + setp(self.mainline, xdata=vecx, ydata=vecy) # Reset slide newslidery = [min(vecy), max(vecy)] newleftx = xmin + (xmax-xmin)*self._leftSlideValue*0.01 - setp(self.leftslideline, xdata=[newleftx, newleftx], ydata=newslidery) + setp(self.leftslideline, xdata=[newleftx, newleftx], ydata=newslidery) newrightx = xmin + (xmax-xmin)*self._rightSlideValue*0.01 - setp(self.rightslideline, xdata=[newrightx, newrightx], ydata=newslidery) + setp(self.rightslideline, xdata=[newrightx, newrightx], ydata=newslidery) self.ui.graphicsView.draw() @@ -1020,7 +1020,7 @@ def filterByTime(self): title = str(self.ui.lineEdit_title.text()) - """ Debug + """ Debug for k in kwargs.keys(): print k, kwargs[k], type(kwargs[k]) print "Input workspace = ", str(self._dataWS) @@ -1073,7 +1073,7 @@ def filterByLogValue(self): if self.ui.lineEdit_8.text() != "": logvaluetol = float(self.ui.lineEdit_8.text()) kwargs["LogValueTolerance"] = logvaluetol - + splitwsname = str(self._dataWS) + "_splitters" splitinfowsname = str(self._dataWS) + "_info" @@ -1088,7 +1088,7 @@ def filterByLogValue(self): LogName = samplelog, InformationWorkspace = splitinfowsname, **kwargs) - try: + try: self.splitWksp(splitws, infows) except Exception as mtderror: self._setErrorMsg("Splitting Failed!\n %s" % (str(mtderror))) @@ -1119,19 +1119,19 @@ def splitWksp(self, splitws, infows): if len(outbasewsname) == 0: outbasewsname = "tempsplitted" self.ui.lineEdit_outwsname.setText(outbasewsname) - + api.FilterEvents( - InputWorkspace = self._dataWS, - SplitterWorkspace = splitws, - InformationWorkspace = infows, - OutputWorkspaceBaseName = outbasewsname, - GroupWorkspaces = dogroupws, - FilterByPulseTime = filterbypulse, - CorrectionToSample = corr2sample, - SpectrumWithoutDetector = how2skip, - SplitSampleLogs = splitsamplelog, - OutputWorkspaceIndexedFrom1 = startfrom1, - OutputTOFCorrectionWorkspace = 'TOFCorrTable', **kwargs) + InputWorkspace = self._dataWS, + SplitterWorkspace = splitws, + InformationWorkspace = infows, + OutputWorkspaceBaseName = outbasewsname, + GroupWorkspaces = dogroupws, + FilterByPulseTime = filterbypulse, + CorrectionToSample = corr2sample, + SpectrumWithoutDetector = how2skip, + SplitSampleLogs = splitsamplelog, + OutputWorkspaceIndexedFrom1 = startfrom1, + OutputTOFCorrectionWorkspace = 'TOFCorrTable', **kwargs) return @@ -1173,12 +1173,12 @@ def _searchTableWorkspaces(self): tablewsnames = [] for wsname in wsnames: wksp = AnalysisDataService.retrieve(wsname) - if isinstance(wksp, mantid.api._api.ITableWorkspace): + if isinstance(wksp, mantid.api._api.ITableWorkspace): tablewsnames.append(wsname) # ENDFOR self.ui.comboBox_corrWS.clear() - if len(tablewsnames) > 0: + if len(tablewsnames) > 0: self.ui.comboBox_corrWS.addItems(tablewsnames) return @@ -1193,7 +1193,7 @@ def _clearErrorMsg(self): def _setErrorMsg(self, errmsg): """ Clear error message - """ + """ #self.ui.plainTextEdit_ErrorMsg.setPlainText(errmsg) #self.ui.label_error.show() @@ -1206,7 +1206,7 @@ def _setErrorMsg(self, errmsg): def _resetGUI(self, resetfilerun=False, resetwslist=False): - """ Reset GUI including all text edits and etc. + """ Reset GUI including all text edits and etc. """ if resetfilerun is True: self.ui.lineEdit.clear() @@ -1231,7 +1231,7 @@ def _resetGUI(self, resetfilerun=False, resetwslist=False): ylim = self.ui.mainplot.get_ylim() miny = ylim[0] maxy = ylim[1] - xlim = self.ui.mainplot.get_xlim() + xlim = self.ui.mainplot.get_xlim() setp(self.lowerslideline, xdata=xlim, ydata=[miny, miny]) setp(self.upperslideline, xdata=xlim, ydata=[maxy, maxy]) self.ui.graphicsView.draw() @@ -1251,7 +1251,7 @@ def _resetGUI(self, resetfilerun=False, resetwslist=False): self.ui.checkBox_doParallel.setCheckState(False) self.ui.comboBox_skipSpectrum.setCurrentIndex(0) - + self.ui.checkBox_filterByPulse.setCheckState(False) self.ui.checkBox_from1.setCheckState(False) self.ui.checkBox_groupWS.setCheckState(True) diff --git a/Code/Mantid/scripts/Inelastic/Direct/CommonFunctions.py b/Code/Mantid/scripts/Inelastic/Direct/CommonFunctions.py index 478deaad9031..26d5a8e749fb 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/CommonFunctions.py +++ b/Code/Mantid/scripts/Inelastic/Direct/CommonFunctions.py @@ -7,7 +7,7 @@ class switch(object): - """ Helper class providing nice switch statement""" + """ Helper class providing nice switch statement""" def __init__(self, value): self.value = value self.fall = False @@ -16,7 +16,7 @@ def __iter__(self): """Return the match method once, then stop""" yield self.match raise StopIteration - + def match(self, *args): """Indicate whether or not to enter a case suite""" if self.fall or not args: @@ -25,4 +25,4 @@ def match(self, *args): self.fall = True return True else: - return False \ No newline at end of file + return False diff --git a/Code/Mantid/scripts/Inelastic/Direct/DirectEnergyConversion.py b/Code/Mantid/scripts/Inelastic/Direct/DirectEnergyConversion.py index b8f8a243a226..34d660382b0c 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/DirectEnergyConversion.py +++ b/Code/Mantid/scripts/Inelastic/Direct/DirectEnergyConversion.py @@ -26,7 +26,7 @@ def setup_reducer(inst_name,reload_instrument=False): class DirectEnergyConversion(object): """ - Performs a convert to energy assuming the provided instrument is + Performs a convert to energy assuming the provided instrument is an direct inelastic geometry instrument The class defines various methods to allow users to convert their @@ -34,7 +34,7 @@ class DirectEnergyConversion(object): Usage: >>red = DirectEnergyConversion('InstrumentName') - and then: + and then: >>red.convert_to_energy(wb_run,sample_run,ei_guess,rebin) or >>red.convert_to_energy(wb_run,sample_run,ei_guess,rebin,**arguments) @@ -42,7 +42,7 @@ class DirectEnergyConversion(object): >>red.convert_to_energy(wb_run,sample_run,ei_guess,rebin,mapfile,**arguments) or >>red.prop_man.sample_run = run number - >>red.prop_man.wb_run = Whitebeam + >>red.prop_man.wb_run = Whitebeam >>red.prop_man.incident_energy = energy guess >>red.prop_man.energy_bins = [min_val,step,max_val] >>red.convert_to_energy() @@ -51,14 +51,14 @@ class DirectEnergyConversion(object): Whitebeam run number or file name or workspace sample_run sample run number or file name or workspace ei_guess suggested value for incident energy of neutrons in direct inelastic instrument - energy_bins energy binning requested for resulting spe workspace. + energy_bins energy binning requested for resulting spe workspace. mapfile Mapfile -- if absent/'default' the defaults from IDF are used monovan_run If present will do the absolute units normalization. Number of additional parameters specified in **kwargs is usually requested for this. If they are absent, program uses defaults, but the defaults (e.g. sample_mass or sample_rmm ) are usually incorrect for a particular run. arguments The dictionary containing additional keyword arguments. - The list of allowed additional arguments is defined in InstrName_Parameters.xml + The list of allowed additional arguments is defined in InstrName_Parameters.xml file, located in: MantidPlot->View->Preferences->Mantid->Directories->Parameter Definitions @@ -87,13 +87,13 @@ class DirectEnergyConversion(object): bkgd_range =[15000,19000] :integration range for background tests - second_white - If provided an additional set of tests is performed on this. + second_white - If provided an additional set of tests is performed on this. (default = None) hardmaskPlus - A file specifying those spectra that should be masked without testing (default=None) tiny - Minimum threshold for acceptance (default = 1e-10) large - Maximum threshold for acceptance (default = 1e10) - bkgd_range - A list of two numbers indicating the background range + bkgd_range - A list of two numbers indicating the background range (default=instrument defaults) diag_van_median_rate_limit_lo - Lower bound defining outliers as fraction of median value (default = 0.01) diag_van_median_rate_limit_hi - Upper bound defining outliers as fraction of median value (default = 100.) @@ -133,7 +133,7 @@ class DirectEnergyConversion(object): """ #------------------------------------------------------------------------------- def diagnose(self, white,diag_sample=None,**kwargs): - """ run diagnostics on the provided workspaces. + """ run diagnostics on the provided workspaces. this method does some additional processing before moving on to the diagnostics: 1) Computes the white beam integrals, converting to energy @@ -177,325 +177,325 @@ def diagnose(self, white,diag_sample=None,**kwargs): bleed_pixels - If the bleed test is on then this is the number of pixels ignored within the bleed test diagnostic """ - lhs_names = funcreturns.lhs_info('names') - if len(lhs_names) > 0: - var_name = lhs_names[0] - else: - var_name = "diag_mask" + lhs_names = funcreturns.lhs_info('names') + if len(lhs_names) > 0: + var_name = lhs_names[0] + else: + var_name = "diag_mask" # modify properties using input arguments - self.prop_man.set_input_parameters(**kwargs) + self.prop_man.set_input_parameters(**kwargs) # obtain proper run descriptor in case it is not a run descriptor but # something else - white = self.get_run_descriptor(white) + white = self.get_run_descriptor(white) # return all diagnostics parameters - diag_params = self.prop_man.get_diagnostics_parameters() + diag_params = self.prop_man.get_diagnostics_parameters() - if self.use_hard_mask_only: - if mtd.doesExist('hard_mask_ws'): - diag_mask = mtd['hard_mask_ws'] - else: # build hard mask + if self.use_hard_mask_only: + if mtd.doesExist('hard_mask_ws'): + diag_mask = mtd['hard_mask_ws'] + else: # build hard mask # in this peculiar way we can obtain working mask which # accounts for initial data grouping in the # data file. SNS or 1 to 1 maps may probably avoid this # stuff and can load masks directly - white_data = white.get_ws_clone('white_ws_clone') + white_data = white.get_ws_clone('white_ws_clone') - diag_mask = LoadMask(Instrument=self.instr_name,InputFile=self.hard_mask_file, + diag_mask = LoadMask(Instrument=self.instr_name,InputFile=self.hard_mask_file, OutputWorkspace='hard_mask_ws') - MaskDetectors(Workspace=white_data, MaskedWorkspace=diag_mask) - DeleteWorkspace(diag_mask) - diag_mask,masked_list = ExtractMask(InputWorkspace=white_data) - DeleteWorkspace(Workspace='white_ws_clone') + MaskDetectors(Workspace=white_data, MaskedWorkspace=diag_mask) + DeleteWorkspace(diag_mask) + diag_mask,masked_list = ExtractMask(InputWorkspace=white_data) + DeleteWorkspace(Workspace='white_ws_clone') - return diag_mask + return diag_mask # Get the white beam vanadium integrals - whiteintegrals = self.do_white(white, None, None) # No grouping yet - if self.second_white: - second_white = self.second_white - other_whiteintegrals = self.do_white(PropertyManager.second_white, None, None) # No grouping yet - self.second_white = other_whiteintegrals + whiteintegrals = self.do_white(white, None, None) # No grouping yet + if self.second_white: + second_white = self.second_white + other_whiteintegrals = self.do_white(PropertyManager.second_white, None, None) # No grouping yet + self.second_white = other_whiteintegrals # Get the background/total counts from the sample run if present - if diag_sample: - diag_sample = self.get_run_descriptor(diag_sample) + if diag_sample: + diag_sample = self.get_run_descriptor(diag_sample) # If the bleed test is requested then we need to pass in the # sample_run as well - if self.bleed_test: + if self.bleed_test: # initiate reference to reducer to be able to work with Run # Descriptors - diagnostics.__Reducer__ = self - diag_params['sample_run'] = diag_sample + diagnostics.__Reducer__ = self + diag_params['sample_run'] = diag_sample # Set up the background integrals for diagnostic purposes - result_ws = self.normalise(diag_sample, self.normalise_method) + result_ws = self.normalise(diag_sample, self.normalise_method) #>>> here result workspace is being processed -- not touching #result ws - bkgd_range = self.background_test_range - background_int = Integration(result_ws, + bkgd_range = self.background_test_range + background_int = Integration(result_ws, RangeLower=bkgd_range[0],RangeUpper=bkgd_range[1], IncludePartialBins=True) - total_counts = Integration(result_ws, IncludePartialBins=True) - background_int = ConvertUnits(background_int, Target="Energy",EMode='Elastic', AlignBins=0) - self.prop_man.log("Diagnose: finished convertUnits ",'information') + total_counts = Integration(result_ws, IncludePartialBins=True) + background_int = ConvertUnits(background_int, Target="Energy",EMode='Elastic', AlignBins=0) + self.prop_man.log("Diagnose: finished convertUnits ",'information') - background_int *= self.scale_factor - diagnostics.normalise_background(background_int, whiteintegrals, + background_int *= self.scale_factor + diagnostics.normalise_background(background_int, whiteintegrals, diag_params.get('second_white',None)) - diag_params['background_int'] = background_int - diag_params['sample_counts'] = total_counts + diag_params['background_int'] = background_int + diag_params['sample_counts'] = total_counts # Check how we should run diag - diag_spectra_blocks = self.diag_spectra - if diag_spectra_blocks is None: + diag_spectra_blocks = self.diag_spectra + if diag_spectra_blocks is None: # Do the whole lot at once - diagnostics.diagnose(whiteintegrals, **diag_params) - else: - for index, bank in enumerate(diag_spectra_blocks): - diag_params['start_index'] = bank[0] - 1 - diag_params['end_index'] = bank[1] - 1 - diagnostics.diagnose(whiteintegrals, **diag_params) - - if 'sample_counts' in diag_params: - DeleteWorkspace(Workspace='background_int') - DeleteWorkspace(Workspace='total_counts') - if 'second_white' in diag_params: - DeleteWorkspace(Workspace=diag_params['second_white']) + diagnostics.diagnose(whiteintegrals, **diag_params) + else: + for index, bank in enumerate(diag_spectra_blocks): + diag_params['start_index'] = bank[0] - 1 + diag_params['end_index'] = bank[1] - 1 + diagnostics.diagnose(whiteintegrals, **diag_params) + + if 'sample_counts' in diag_params: + DeleteWorkspace(Workspace='background_int') + DeleteWorkspace(Workspace='total_counts') + if 'second_white' in diag_params: + DeleteWorkspace(Workspace=diag_params['second_white']) # Extract a mask workspace - diag_mask, det_ids = ExtractMask(InputWorkspace=whiteintegrals,OutputWorkspace=var_name) + diag_mask, det_ids = ExtractMask(InputWorkspace=whiteintegrals,OutputWorkspace=var_name) - DeleteWorkspace(Workspace=whiteintegrals) + DeleteWorkspace(Workspace=whiteintegrals) #TODO do we need this? #self.spectra_masks = diag_mask - return diag_mask + return diag_mask #------------------------------------------------------------------------------- def convert_to_energy(self,wb_run=None,sample_run=None,ei_guess=None,rebin=None,map_file=None, monovan_run=None,wb_for_monovan_run=None,**kwargs): - """ One step conversion of run into workspace containing information about energy transfer + """ One step conversion of run into workspace containing information about energy transfer - """ + """ # Support for old reduction interface: - self.prop_man.set_input_parameters_ignore_nan\ + self.prop_man.set_input_parameters_ignore_nan\ (wb_run=wb_run,sample_run=sample_run,incident_energy=ei_guess,energy_bins=rebin, map_file=map_file,monovan_run=monovan_run,wb_for_monovan_run=wb_for_monovan_run) # - self.prop_man.set_input_parameters(**kwargs) + self.prop_man.set_input_parameters(**kwargs) # output workspace name. - try: - n,r = funcreturns.lhs_info('both') - out_ws_name = r[0] - except: - out_ws_name = None + try: + n,r = funcreturns.lhs_info('both') + out_ws_name = r[0] + except: + out_ws_name = None # inform user on what parameters have changed from script or gui # if monovan present, check if abs_norm_ parameters are set - self.prop_man.log_changed_values('notice') - prop_man = self.prop_man + self.prop_man.log_changed_values('notice') + prop_man = self.prop_man #process complex parameters - start_time = time.time() + start_time = time.time() # check if reducer can find all non-run files necessary for the reduction # before starting long run. #TODO: # Reducer.check_necessary_files(monovan_run) - PropertyManager.sample_run.set_action_suffix('') - sample_ws = PropertyManager.sample_run.get_workspace() + PropertyManager.sample_run.set_action_suffix('') + sample_ws = PropertyManager.sample_run.get_workspace() # Update reduction properties which may change in the workspace but have # not been modified from input parameters. # E.g. detector number have changed - oldChanges = self.prop_man.getChangedProperties() - allChanges = self.prop_man.update_defaults_from_instrument(sample_ws.getInstrument()) - workspace_defined_prop = allChanges.difference(oldChanges) - if len(workspace_defined_prop) > 0: - prop_man.log("****************************************************************") - prop_man.log('*** Sample run {0} properties change default reduction properties: '.\ + oldChanges = self.prop_man.getChangedProperties() + allChanges = self.prop_man.update_defaults_from_instrument(sample_ws.getInstrument()) + workspace_defined_prop = allChanges.difference(oldChanges) + if len(workspace_defined_prop) > 0: + prop_man.log("****************************************************************") + prop_man.log('*** Sample run {0} properties change default reduction properties: '.\ format(PropertyManager.sample_run.get_ws_name())) - prop_man.log_changed_values('notice',False,oldChanges) - prop_man.log("****************************************************************") + prop_man.log_changed_values('notice',False,oldChanges) + prop_man.log("****************************************************************") - masking = None - masks_done = False - if not prop_man.run_diagnostics: - header = "*** Diagnostics including hard masking is skipped " - masks_done = True + masking = None + masks_done = False + if not prop_man.run_diagnostics: + header = "*** Diagnostics including hard masking is skipped " + masks_done = True #if Reducer.save_and_reuse_masks : # SAVE AND REUSE MASKS - if self.spectra_masks: - masks_done = True + if self.spectra_masks: + masks_done = True #-------------------------------------------------------------------------------------------------- # Diagnostics here # ------------------------------------------------------------------------------------------------- # diag the sample and detector vanadium. It will deal with hard mask only # if it is set that way - if not masks_done: - prop_man.log("======== Run diagnose for sample run ===========================",'notice') - masking = self.diagnose(PropertyManager.wb_run,PropertyManager.mask_run, + if not masks_done: + prop_man.log("======== Run diagnose for sample run ===========================",'notice') + masking = self.diagnose(PropertyManager.wb_run,PropertyManager.mask_run, second_white=None,print_diag_results=True) - if prop_man.use_hard_mask_only: - header = "*** Hard mask file applied to workspace with {0:d} spectra masked {1:d} spectra" - else: - header = "*** Diagnostics processed workspace with {0:d} spectra and masked {1:d} bad spectra" + if prop_man.use_hard_mask_only: + header = "*** Hard mask file applied to workspace with {0:d} spectra masked {1:d} spectra" + else: + header = "*** Diagnostics processed workspace with {0:d} spectra and masked {1:d} bad spectra" # diagnose absolute units: - if self.monovan_run != None : - if self.mono_correction_factor == None : - if self.use_sam_msk_on_monovan == True: - prop_man.log(' Applying sample run mask to mono van') - else: - if not self.use_hard_mask_only : # in this case the masking2 is different but + if self.monovan_run != None : + if self.mono_correction_factor == None : + if self.use_sam_msk_on_monovan == True: + prop_man.log(' Applying sample run mask to mono van') + else: + if not self.use_hard_mask_only : # in this case the masking2 is different but #points to the same #workspace # Should be better # solution for that. - prop_man.log("======== Run diagnose for monochromatic vanadium run ===========",'notice') + prop_man.log("======== Run diagnose for monochromatic vanadium run ===========",'notice') - masking2 = self.diagnose(PropertyManager.wb_for_monovan_run,PropertyManager.monovan_run, + masking2 = self.diagnose(PropertyManager.wb_for_monovan_run,PropertyManager.monovan_run, second_white = None,print_diag_results=True) - masking += masking2 - DeleteWorkspace(masking2) + masking += masking2 + DeleteWorkspace(masking2) - else: # if Reducer.mono_correction_factor != None : - pass + else: # if Reducer.mono_correction_factor != None : + pass # Very important statement propagating masks for further usage in # convert_to_energy. # This property is also directly accessible from GUI. - self.spectra_masks = masking + self.spectra_masks = masking # save mask if it does not exist and has been already loaded #if Reducer.save_and_reuse_masks and not masks_done: # SaveMask(InputWorkspace=masking,OutputFile = # mask_file_name,GroupedDetectors=True) - else: - header = '*** Using stored mask file for workspace with {0} spectra and {1} masked spectra' - masking = self.spectra_masks - + else: + header = '*** Using stored mask file for workspace with {0} spectra and {1} masked spectra' + masking = self.spectra_masks + # estimate and report the number of failing detectors - failed_sp_list,nMaskedSpectra = get_failed_spectra_list_from_masks(masking) - if masking: - nSpectra = masking.getNumberHistograms() - else: - nSpectra = 0 - prop_man.log(header.format(nSpectra,nMaskedSpectra),'notice') + failed_sp_list,nMaskedSpectra = get_failed_spectra_list_from_masks(masking) + if masking: + nSpectra = masking.getNumberHistograms() + else: + nSpectra = 0 + prop_man.log(header.format(nSpectra,nMaskedSpectra),'notice') #-------------------------------------------------------------------------------------------------- # now reduction #-------------------------------------------------------------------------------------------------- # SNS or GUI motor stuff - self.calculate_rotation(PropertyManager.sample_run.get_workspace()) + self.calculate_rotation(PropertyManager.sample_run.get_workspace()) # - if self.monovan_run != None: - MonovanCashNum = PropertyManager.monovan_run.run_number() - if self.mono_correction_factor: - calculate_abs_units = False # correction factor given, so no calculations - else: - calculate_abs_units = True - else: - MonovanCashNum = None - calculate_abs_units = False - PropertyManager.mono_correction_factor.set_cash_mono_run_number(MonovanCashNum) - - - if PropertyManager.incident_energy.multirep_mode(): - self._multirep_mode = True - ws_base = None - mono_ws_base = None - num_ei_cuts = len(self.incident_energy) - if self.check_background: + if self.monovan_run != None: + MonovanCashNum = PropertyManager.monovan_run.run_number() + if self.mono_correction_factor: + calculate_abs_units = False # correction factor given, so no calculations + else: + calculate_abs_units = True + else: + MonovanCashNum = None + calculate_abs_units = False + PropertyManager.mono_correction_factor.set_cash_mono_run_number(MonovanCashNum) + + + if PropertyManager.incident_energy.multirep_mode(): + self._multirep_mode = True + ws_base = None + mono_ws_base = None + num_ei_cuts = len(self.incident_energy) + if self.check_background: # find the count rate seen in the regions of the histograms # defined as the background regions, if the user defined such # region - ws_base = PropertyManager.sample_run.get_workspace() - bkgd_range = self.bkgd_range - bkgr_ws=self._find_or_build_bkgr_ws(ws_base,bkgd_range[0],bkgd_range[1]) - RenameWorkspace(InputWorkspace=bkgr_ws, OutputWorkspace='bkgr_ws_source') - # initialize list to store resulting workspaces to return - result = [] - else: - self._multirep_mode = False - num_ei_cuts = 0 - - cut_ind = 0 # do not do enumerate if it generates all sequence at once + ws_base = PropertyManager.sample_run.get_workspace() + bkgd_range = self.bkgd_range + bkgr_ws=self._find_or_build_bkgr_ws(ws_base,bkgd_range[0],bkgd_range[1]) + RenameWorkspace(InputWorkspace=bkgr_ws, OutputWorkspace='bkgr_ws_source') + # initialize list to store resulting workspaces to return + result = [] + else: + self._multirep_mode = False + num_ei_cuts = 0 + + cut_ind = 0 # do not do enumerate if it generates all sequence at once # -- code below uses current energy state from # PropertyManager.incident_energy - for ei_guess in PropertyManager.incident_energy: - cut_ind +=1 + for ei_guess in PropertyManager.incident_energy: + cut_ind +=1 #--------------- - if self._multirep_mode: - tof_range = self.find_tof_range_for_multirep(ws_base) - ws_base = PropertyManager.sample_run.chop_ws_part(ws_base,tof_range,self._do_early_rebinning,cut_ind,num_ei_cuts) - prop_man.log("*** Processing multirep chunk: #{0}/{1} for provisional energy: {2} meV".format(cut_ind,num_ei_cuts,ei_guess),'notice') + if self._multirep_mode: + tof_range = self.find_tof_range_for_multirep(ws_base) + ws_base = PropertyManager.sample_run.chop_ws_part(ws_base,tof_range,self._do_early_rebinning,cut_ind,num_ei_cuts) + prop_man.log("*** Processing multirep chunk: #{0}/{1} for provisional energy: {2} meV".format(cut_ind,num_ei_cuts,ei_guess),'notice') #--------------- #Run the conversion first on the sample - deltaE_ws_sample = self.mono_sample(PropertyManager.sample_run,ei_guess,PropertyManager.wb_run, + deltaE_ws_sample = self.mono_sample(PropertyManager.sample_run,ei_guess,PropertyManager.wb_run, self.map_file,masking) - + # calculate absolute units integral and apply it to the workspace - cashed_mono_int = PropertyManager.mono_correction_factor.get_val_from_cash(prop_man) - if MonovanCashNum != None or self.mono_correction_factor or cashed_mono_int : + cashed_mono_int = PropertyManager.mono_correction_factor.get_val_from_cash(prop_man) + if MonovanCashNum != None or self.mono_correction_factor or cashed_mono_int : # do not remove background from vanadium (sample background is not fit for that anyway) - current_bkg_opt = self.check_background - self.check_background= False - # what we want to do with absolute units: - if self.mono_correction_factor: # Correction provided. Just apply it - deltaE_ws_sample = self.apply_absolute_normalization(deltaE_ws_sample,PropertyManager.monovan_run, + current_bkg_opt = self.check_background + self.check_background= False + # what we want to do with absolute units: + if self.mono_correction_factor: # Correction provided. Just apply it + deltaE_ws_sample = self.apply_absolute_normalization(deltaE_ws_sample,PropertyManager.monovan_run, ei_guess,PropertyManager.wb_for_monovan_run) - elif cashed_mono_int: # Correction cashed from previous run - self.mono_correction_factor = cashed_mono_int - deltaE_ws_sample = self.apply_absolute_normalization(deltaE_ws_sample,PropertyManager.monovan_run, + elif cashed_mono_int: # Correction cashed from previous run + self.mono_correction_factor = cashed_mono_int + deltaE_ws_sample = self.apply_absolute_normalization(deltaE_ws_sample,PropertyManager.monovan_run, ei_guess,PropertyManager.wb_for_monovan_run) - self.mono_correction_factor = None - else: # Calculate corrections - if self._multirep_mode and calculate_abs_units: - mono_ws_base = PropertyManager.monovan_run.chop_ws_part(mono_ws_base,tof_range,self._do_early_rebinning, + self.mono_correction_factor = None + else: # Calculate corrections + if self._multirep_mode and calculate_abs_units: + mono_ws_base = PropertyManager.monovan_run.chop_ws_part(mono_ws_base,tof_range,self._do_early_rebinning, cut_ind,num_ei_cuts) - deltaE_ws_sample = self.apply_absolute_normalization(deltaE_ws_sample,PropertyManager.monovan_run, + deltaE_ws_sample = self.apply_absolute_normalization(deltaE_ws_sample,PropertyManager.monovan_run, ei_guess,PropertyManager.wb_for_monovan_run) - self.check_background = current_bkg_opt + self.check_background = current_bkg_opt # ensure that the sample_run name is intact with workspace - PropertyManager.sample_run.synchronize_ws(deltaE_ws_sample) + PropertyManager.sample_run.synchronize_ws(deltaE_ws_sample) # - ei = (deltaE_ws_sample.getRun().getLogData("Ei").value) + ei = (deltaE_ws_sample.getRun().getLogData("Ei").value) # PropertyManager.incident_energy.set_current(ei) # let's not do it -- # this makes subsequent calls to this method depend on # # previous calls - prop_man.log("*** Incident energy found for sample run: {0} meV".format(ei),'notice') + prop_man.log("*** Incident energy found for sample run: {0} meV".format(ei),'notice') # - self.save_results(deltaE_ws_sample) - if out_ws_name: - if self._multirep_mode: - result.append(deltaE_ws_sample) - else: # delete workspace if no output is requested - self.sample_run = None + self.save_results(deltaE_ws_sample) + if out_ws_name: + if self._multirep_mode: + result.append(deltaE_ws_sample) + else: # delete workspace if no output is requested + self.sample_run = None - results_name = deltaE_ws_sample.name() - if out_ws_name and not(self._multirep_mode): - if results_name != out_ws_name: - RenameWorkspace(InputWorkspace=results_name,OutputWorkspace=out_ws_name) - result = mtd[out_ws_name] - else: - pass + results_name = deltaE_ws_sample.name() + if out_ws_name and not(self._multirep_mode): + if results_name != out_ws_name: + RenameWorkspace(InputWorkspace=results_name,OutputWorkspace=out_ws_name) + result = mtd[out_ws_name] + else: + pass - end_time = time.time() - prop_man.log("*** Elapsed time = {0} sec".format(end_time - start_time),'notice') + end_time = time.time() + prop_man.log("*** Elapsed time = {0} sec".format(end_time - start_time),'notice') # Hack for multirep mode? # if mtd.doesExist('hard_mask_ws') == True: @@ -505,15 +505,15 @@ def convert_to_energy(self,wb_run=None,sample_run=None,ei_guess=None,rebin=None, # CLEAN-up (may be worth to do in separate procedure) # Currently clear masks unconditionally TODO: cash masks with appropriate # precautions - self.spectra_masks = None + self.spectra_masks = None #self.prop_man.wb_run = None # clean up memory of the wb run (only in #case of file based wb) - if 'bkgr_ws_source' in mtd: - DeleteWorkspace('bkgr_ws_source') + if 'bkgr_ws_source' in mtd: + DeleteWorkspace('bkgr_ws_source') - return result + return result def do_white(self, run, spectra_masks=None, map_file=None): """ @@ -552,7 +552,7 @@ def mono_sample(self, mono_run, ei_guess, white_run=None, map_file=None, #------------------------------------------------------------------------------- def calculate_rotation(self,sample_wkspace,motor=None, offset=None): """calculate psi from sample environment motor and offset - + TODO: should probably go to properties """ @@ -575,7 +575,7 @@ def calculate_rotation(self,sample_wkspace,motor=None, offset=None): self.prop_man.log("Could not find such sample environment log. Will use psi=motor_offset") motor_rotation = 0 else: - motor_rotation = float('nan') + motor_rotation = float('nan') self.prop_man.psi = motor_rotation + motor_offset #------------------------------------------------------------------------------- def get_ei(self, data_run, ei_guess): @@ -596,7 +596,7 @@ def get_ei(self, data_run, ei_guess): data_ws = data_run.get_workspace() monitor_ws = data_run.get_monitors_ws() if not monitor_ws: - raise RuntimeError("Can not find monitors workspace for workspace {0}, run N{1}".\ + raise RuntimeError("Can not find monitors workspace for workspace {0}, run N{1}".\ format(data_ws.name(),data_ws.getRunNumber())) separate_monitors = data_run.is_monws_separate() data_run.set_action_suffix('_shifted') @@ -622,8 +622,8 @@ def get_ei(self, data_run, ei_guess): # instrument is shifted in case it is shifted to this monitor (usual # case) #Find TOF range, correspondent to incident energy monitor peak - energy_rage = self.mon2_norm_energy_range - self._mon2_norm_time_range = self.get_TOF_for_energies(monitor_ws,energy_rage, + energy_rage = self.mon2_norm_energy_range + self._mon2_norm_time_range = self.get_TOF_for_energies(monitor_ws,energy_rage, [self.mon2_norm_spec],None,self._debug_mode) #end if separate_monitors: @@ -638,13 +638,13 @@ def get_ei(self, data_run, ei_guess): InstrumentParameter="DelayTime",Combine=True) # shift to monitor used to calculate energy transfer - spec_num = monitor_ws.getIndexFromSpectrumNumber(int(ei_mon_spectra[0])) + spec_num = monitor_ws.getIndexFromSpectrumNumber(int(ei_mon_spectra[0])) mon1_det = monitor_ws.getDetector(spec_num) mon1_pos = mon1_det.getPos() src_name = data_ws.getInstrument().getSource().getName() - MoveInstrumentComponent(Workspace=resultws_name,ComponentName= src_name, X=mon1_pos.getX(), + MoveInstrumentComponent(Workspace=resultws_name,ComponentName= src_name, X=mon1_pos.getX(), Y=mon1_pos.getY(), Z=mon1_pos.getZ(), RelativePosition=False) - + # data_run.synchronize_ws(mtd[resultws_name]) return ei, mon1_peak @@ -685,16 +685,16 @@ def normalise(self, run, method, range_offset=0.0,external_monitors_ws=None): method = method.lower() for case in common.switch(method): if case('monitor-1'): - method,old_ws_name = self._normalize_to_monitor1(run,old_ws_name, range_offset,external_monitors_ws) - break + method,old_ws_name = self._normalize_to_monitor1(run,old_ws_name, range_offset,external_monitors_ws) + break if case('monitor-2'): - method,old_ws_name = self._normalize_to_monitor2(run,old_ws_name, range_offset,external_monitors_ws) - break + method,old_ws_name = self._normalize_to_monitor2(run,old_ws_name, range_offset,external_monitors_ws) + break if case('current'): NormaliseByCurrent(InputWorkspace=old_ws_name,OutputWorkspace=old_ws_name) break if case(): # default - raise RuntimeError('Normalization method {0} not found. It must be one of monitor-1, monitor-2, current, or None'.format(method)) + raise RuntimeError('Normalization method {0} not found. It must be one of monitor-1, monitor-2, current, or None'.format(method)) #endCase @@ -706,32 +706,32 @@ def normalise(self, run, method, range_offset=0.0,external_monitors_ws=None): return output # def _normalize_to_monitor1(self,run,old_name,range_offset=0.0,external_monitor_ws=None): - """ Helper method implementing normalize_to_monitor1 """ + """ Helper method implementing normalize_to_monitor1 """ # get monitor's workspace separate_monitors = run.is_monws_separate() if external_monitor_ws: - separate_monitors = True - mon_ws = external_monitor_ws + separate_monitors = True + mon_ws = external_monitor_ws else: - mon_ws = run.get_monitors_ws() + mon_ws = run.get_monitors_ws() if not mon_ws: # no monitors - if self.__in_white_normalization: # we can normalize wb integrals by current separately as they often do not + if self.__in_white_normalization: # we can normalize wb integrals by current separately as they often do not # have monitors - self.normalise(run,'current',range_offset) - new_name = run.get_ws_name() - return ('current',new_name) - else: - raise RuntimeError('Normalise by monitor-1:: Workspace {0} for run {1} does not have monitors in it'\ + self.normalise(run,'current',range_offset) + new_name = run.get_ws_name() + return ('current',new_name) + else: + raise RuntimeError('Normalise by monitor-1:: Workspace {0} for run {1} does not have monitors in it'\ .format(run.get_ws_name(),run.__get__())) range = self.norm_mon_integration_range if self._debug_mode: - kwargs = {'NormFactorWS':'NormMon1_WS' + data_ws.getName()} + kwargs = {'NormFactorWS':'NormMon1_WS' + data_ws.getName()} else: - kwargs = {} + kwargs = {} mon_spect = self.prop_man.mon1_norm_spec if separate_monitors: @@ -746,36 +746,36 @@ def _normalize_to_monitor1(self,run,old_name,range_offset=0.0,external_monitor_w - NormaliseToMonitor(InputWorkspace=old_name,OutputWorkspace=old_name, IntegrationRangeMin=range_min, + NormaliseToMonitor(InputWorkspace=old_name,OutputWorkspace=old_name, IntegrationRangeMin=range_min, IntegrationRangeMax=range_max,IncludePartialBins=True,**kwargs) return ('monitor-1',old_name) # def _normalize_to_monitor2(self,run,old_name, range_offset=0.0,external_monitor_ws=None): - """ Helper method implementing normalize_to_monitor_2 """ + """ Helper method implementing normalize_to_monitor_2 """ # get monitor's workspace separate_monitors = run.is_monws_separate() if external_monitor_ws: - separate_monitors = True - mon_ws = external_monitor_ws + separate_monitors = True + mon_ws = external_monitor_ws else: - mon_ws = run.get_monitors_ws() + mon_ws = run.get_monitors_ws() + - if not mon_ws: # no monitors - if self.__in_white_normalization: # we can normalize wb integrals by current separately as they often do not + if self.__in_white_normalization: # we can normalize wb integrals by current separately as they often do not # have monitors - self.normalise(run,'current',range_offset) - new_name = run.get_ws_name() - return ('current',new_name) - else: - raise RuntimeError('Normalize by monitor-2:: Workspace {0} for run {1} does not have monitors in it'\ + self.normalise(run,'current',range_offset) + new_name = run.get_ws_name() + return ('current',new_name) + else: + raise RuntimeError('Normalize by monitor-2:: Workspace {0} for run {1} does not have monitors in it'\ .format(run.get_ws_name(),run.__get__())) # if self._debug_mode: - kwargs = {'NormFactorWS':'NormMon2_WS' + mon_ws.getName()} + kwargs = {'NormFactorWS':'NormMon2_WS' + mon_ws.getName()} else: - kwargs = {} + kwargs = {} mon_spect = self.prop_man.mon2_norm_spec mon_index = int(mon_ws.getIndexFromSpectrumNumber(mon_spect)) @@ -787,36 +787,36 @@ def _normalize_to_monitor2(self,run,old_name, range_offset=0.0,external_monitor_ #Find TOF range, correspondent to incident energy monitor peak if self._mon2_norm_time_range: # range has been found during ei-calculations - range = self._mon2_norm_time_range - range_min = range[0] + range_offset - range_max = range[1] + range_offset - self._mon2_norm_time_range = None + range = self._mon2_norm_time_range + range_min = range[0] + range_offset + range_max = range[1] + range_offset + self._mon2_norm_time_range = None else: - mon_ws_name = mon_ws.name() #monitor's workspace and detector's workspace are e - if mon_ws_name.find('_shifted') != -1: + mon_ws_name = mon_ws.name() #monitor's workspace and detector's workspace are e + if mon_ws_name.find('_shifted') != -1: # monitor-2 normalization ranges have to be identified before the # instrument is shifted - raise RuntimeError("Instrument have been shifted but no time range has been identified. Monitor-2 normalization can not be performed ") - else: + raise RuntimeError("Instrument have been shifted but no time range has been identified. Monitor-2 normalization can not be performed ") + else: # instrument and workspace shifted, so TOF will be calculated wrt # shifted instrument - energy_rage = self.mon2_norm_energy_range - TOF_range = self.get_TOF_for_energies(mon_ws,energy_rage,[mon_spect],None,self._debug_mode) - range_min = TOF_range[0] - range_max = TOF_range[1] + energy_rage = self.mon2_norm_energy_range + TOF_range = self.get_TOF_for_energies(mon_ws,energy_rage,[mon_spect],None,self._debug_mode) + range_min = TOF_range[0] + range_max = TOF_range[1] # Normalize to monitor 2 - NormaliseToMonitor(InputWorkspace=old_name,OutputWorkspace=old_name,IntegrationRangeMin=range_min, + NormaliseToMonitor(InputWorkspace=old_name,OutputWorkspace=old_name,IntegrationRangeMin=range_min, IntegrationRangeMax=range_max,IncludePartialBins=True,**kwargs) return ('monitor-2',old_name) #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- def find_tof_range_for_multirep(self,workspace): - """ Find range of tof-s (and time bin size) corresponding to the + """ Find range of tof-s (and time bin size) corresponding to the energy range requested - """ + """ if not workspace: - workspace = PropertyManager.sample_run.get_workspace() + workspace = PropertyManager.sample_run.get_workspace() spectra_id = self.prop_man.multirep_tof_specta_list if not spectra_id: @@ -839,32 +839,32 @@ def process_block(tof_range): nBlocks = len(spectra_id) if nBlocks > 1: - tof_min,t_step,tof_max = process_block(TOF_range[0]) - for ind in xrange(1,nBlocks): - tof_min1,t_step1,tof_max1 = process_block(TOF_range[ind]) - tof_min = min(tof_min,tof_min1) - tof_max = max(tof_max,tof_max1) - t_step = min(t_step,t_step1) + tof_min,t_step,tof_max = process_block(TOF_range[0]) + for ind in xrange(1,nBlocks): + tof_min1,t_step1,tof_max1 = process_block(TOF_range[ind]) + tof_min = min(tof_min,tof_min1) + tof_max = max(tof_max,tof_max1) + t_step = min(t_step,t_step1) else: - tof_min,t_step,tof_max = process_block(TOF_range) + tof_min,t_step,tof_max = process_block(TOF_range) #end return (tof_min,t_step,tof_max) # @staticmethod def get_TOF_for_energies(workspace,energy_list,specID_list,ei=None,debug_mode=False): - """ Method to find what TOF range corresponds to given energy range + """ Method to find what TOF range corresponds to given energy range for given workspace and detectors. Input: - workspace pointer to workspace with instrument attached. + workspace pointer to workspace with instrument attached. energy_list the list of input energies to process - detID_list list of detectors to find - ei incident energy. If present, TOF range is calculated in direct mode, + detID_list list of detectors to find + ei incident energy. If present, TOF range is calculated in direct mode, if not -- elastic mode - Returns: - list of TOF corresponding to input energies list. - """ + Returns: + list of TOF corresponding to input energies list. + """ template_ws_name = '_energy_range_ws' range_ws_name = '_TOF_range_ws' y = [1] * (len(energy_list) - 1) @@ -913,8 +913,8 @@ def save_results(self, workspace, save_file=None, formats=None): else: pass - prop_man = self.prop_man - + prop_man = self.prop_man + save_file,ext = os.path.splitext(save_file) if len(ext) > 1: formats.add(ext[1:]) @@ -923,27 +923,27 @@ def save_results(self, workspace, save_file=None, formats=None): for file_format in formats: for case in common.switch(file_format): if case('nxspe'): - filename = save_file + '.nxspe' - name_supported = name_orig.replace('/','of') - if name_supported != name_orig: - RenameWorkspace(InputWorkspace=name_orig,OutputWorkspace=name_supported) - SaveNXSPE(InputWorkspace=name_supported,Filename= filename, KiOverKfScaling=prop_man.apply_kikf_correction,psi=prop_man.psi) - if name_supported != name_orig: - RenameWorkspace(InputWorkspace=name_supported,OutputWorkspace=name_orig) - break + filename = save_file + '.nxspe' + name_supported = name_orig.replace('/','of') + if name_supported != name_orig: + RenameWorkspace(InputWorkspace=name_orig,OutputWorkspace=name_supported) + SaveNXSPE(InputWorkspace=name_supported,Filename= filename, KiOverKfScaling=prop_man.apply_kikf_correction,psi=prop_man.psi) + if name_supported != name_orig: + RenameWorkspace(InputWorkspace=name_supported,OutputWorkspace=name_orig) + break if case('spe'): - filename = save_file + '.spe' - SaveSPE(InputWorkspace=workspace,Filename= filename) - break + filename = save_file + '.spe' + SaveSPE(InputWorkspace=workspace,Filename= filename) + break if case('nxs'): - filename = save_file + '.nxs' - SaveNexus(InputWorkspace=workspace,Filename= filename) - break + filename = save_file + '.nxs' + SaveNexus(InputWorkspace=workspace,Filename= filename) + break if case(): # default, could also just omit condition or 'if True' - prop_man.log("Unknown file format {0} requested to save results. No saving performed this format".format(file_format)) + prop_man.log("Unknown file format {0} requested to save results. No saving performed this format".format(file_format)) ######### - @property + @property def prop_man(self): """ Return property manager containing DirectEnergyConversion parameters """ return self._propMan @@ -958,7 +958,7 @@ def prop_man(self,value): ######### @property def spectra_masks(self): - """ The property keeps a workspace with masks, stored for further usage """ + """ The property keeps a workspace with masks, stored for further usage """ # check if spectra masks is defined if hasattr(self,'_spectra_masks'): @@ -968,7 +968,7 @@ def spectra_masks(self): @spectra_masks.setter def spectra_masks(self,value): - """ set up spectra masks """ + """ set up spectra masks """ self._spectra_masks = value #------------------------------------------------------------------------------- def apply_absolute_normalization(self,sample_ws,monovan_run=None,ei_guess=None,wb_mono=None): @@ -1017,7 +1017,7 @@ def apply_absolute_normalization(self,sample_ws,monovan_run=None,ei_guess=None,w # workspace is not good for further processing any more mono_run_num = PropertyManager.monovan_run.run_number() prop_man.monovan_run = None # delete everything from memory - prop_man.monovan_run = mono_run_num + prop_man.monovan_run = mono_run_num #end prop_man.log('*** Using {0} value : {1} of absolute units correction factor (TGP)'.format(abs_norm_factor_is,absnorm_factor),'notice') prop_man.log('*******************************************************************************************','notice') @@ -1053,30 +1053,30 @@ def get_abs_normalization_factor(self,deltaE_wkspaceName,ei_monovan): data_ws = Integration(InputWorkspace=deltaE_wkspaceName,OutputWorkspace='van_int',RangeLower=minmax[0],RangeUpper=minmax[1],IncludePartialBins='1') - + nhist = data_ws.getNumberHistograms() # extract wb integrals for combined spectra signal = [] error = [] izerc = 0 for i in range(nhist): - try: - det = data_ws.getDetector(i) - except Exception: - continue - if det.isMasked(): - continue - sig = data_ws.readY(i)[0] - err = data_ws.readE(i)[0] - if sig != sig: #ignore NaN (hopefully it will mean mask some day) - continue - if ((err <= 0) or (sig <= 0)): # count Inf and negative||zero readings. Presence of this indicates that + try: + det = data_ws.getDetector(i) + except Exception: + continue + if det.isMasked(): + continue + sig = data_ws.readY(i)[0] + err = data_ws.readE(i)[0] + if sig != sig: #ignore NaN (hopefully it will mean mask some day) + continue + if ((err <= 0) or (sig <= 0)): # count Inf and negative||zero readings. Presence of this indicates that # something went wrong - izerc+=1 - continue + izerc+=1 + continue - signal.append(sig) - error.append(err) + signal.append(sig) + error.append(err) #---------------- Loop finished norm_factor = {} @@ -1135,11 +1135,11 @@ def get_abs_normalization_factor(self,deltaE_wkspaceName,ei_monovan): # check for NaN if (norm_factor['LibISIS'] != norm_factor['LibISIS']) | (izerc != 0): # It is an error, print diagnostics: - if (norm_factor['LibISIS'] != norm_factor['LibISIS']): - log_value = '\n--------> Absolute normalization factor is NaN <----------------------------------------------\n' - else: - log_value = '\n--------> Warning, Monovanadium has zero spectra <--------------------------------------------\n' - log1_value = \ + if (norm_factor['LibISIS'] != norm_factor['LibISIS']): + log_value = '\n--------> Absolute normalization factor is NaN <----------------------------------------------\n' + else: + log_value = '\n--------> Warning, Monovanadium has zero spectra <--------------------------------------------\n' + log1_value = \ "--------> Processing workspace: {0}\n"\ "--------> Monovan Integration range : min={1}, max={2} (meV)\n"\ "--------> Summed: {3} spectra with total signal: {4} and error: {5}\n"\ @@ -1151,8 +1151,8 @@ def get_abs_normalization_factor(self,deltaE_wkspaceName,ei_monovan): "--------> Abs norm factors: TGP : {11}\n"\ .format(deltaE_wkspaceName,minmax[0],minmax[1],nhist,sum(signal),sum(error),izerc,scale_factor, norm_factor['LibISIS'],norm_factor['SigSq'],norm_factor['Poisson'],norm_factor['TGP']) - log_value = log_value + log1_value - propman.log(log_value,'error') + log_value = log_value + log1_value + propman.log(log_value,'error') else: if not self._debug_mode: DeleteWorkspace(Workspace=deltaE_wkspaceName) @@ -1195,14 +1195,14 @@ def __init__(self, instr_name=None,reload_instrument=False): #end def __getattr__(self,attr_name): - """ overloaded to return values of properties non-existing in the class dictionary + """ overloaded to return values of properties non-existing in the class dictionary from the property manager class except this property already have descriptor in self class - """ - if attr_name in self._descriptors: - return object.__getattr__(self,attr_name) - else: - return getattr(self._propMan,attr_name) + """ + if attr_name in self._descriptors: + return object.__getattr__(self,attr_name) + else: + return getattr(self._propMan,attr_name) def __setattr__(self,attr_name,attr_value): """ overloaded to prohibit adding non-starting with _properties to the class instance @@ -1216,7 +1216,7 @@ def __setattr__(self,attr_name,attr_value): object.__setattr__(self,attr_name,attr_value) else: setattr(self._propMan,attr_name,attr_value) - + def initialise(self, instr,reload_instrument=False): """ Initialize the private attributes of the class and the nullify the attributes which expected @@ -1259,20 +1259,20 @@ def setup_instrument_properties(self, workspace=None,reload_instrument=False): instrument = workspace.getInstrument() name = instrument.getName() if name != self.prop_man.instr_name: - self.prop_man = PropertyManager(name,workspace) + self.prop_man = PropertyManager(name,workspace) + - def get_run_descriptor(self,run): - """ Spawn temporary run descriptor for input data given in format, - different from run descriptor. Return existing run descriptor, + """ Spawn temporary run descriptor for input data given in format, + different from run descriptor. Return existing run descriptor, if it is what provided. """ - if not isinstance(run,RunDescriptor): - tRun = copy.copy(PropertyManager._tmp_run) - tRun.__set__(None,run) - return tRun - else: - return run + if not isinstance(run,RunDescriptor): + tRun = copy.copy(PropertyManager._tmp_run) + tRun.__set__(None,run) + return tRun + else: + return run # # ------------------------------------------------------------------------------------------- # This actually does the conversion for the mono-sample and @@ -1333,10 +1333,10 @@ def _do_mono_ISIS(self, data_run, ei_guess, energy_bins = PropertyManager.energy_bins.get_abs_range(self.prop_man) if energy_bins: - Rebin(InputWorkspace=result_name,OutputWorkspace=result_name,Params= energy_bins,PreserveEvents=False) - if bkgr_ws: # remove background after converting units and rebinning - RemoveBackground(InputWorkspace=result_name,OutputWorkspace=result_name,BkgWorkspace=bkgr_ws,EMode='Direct') - DeleteWorkspace(bkgr_ws) + Rebin(InputWorkspace=result_name,OutputWorkspace=result_name,Params= energy_bins,PreserveEvents=False) + if bkgr_ws: # remove background after converting units and rebinning + RemoveBackground(InputWorkspace=result_name,OutputWorkspace=result_name,BkgWorkspace=bkgr_ws,EMode='Direct') + DeleteWorkspace(bkgr_ws) else: pass # TODO: investigate way of removing background from event workspace if we want # result to be an event workspace @@ -1345,35 +1345,35 @@ def _do_mono_ISIS(self, data_run, ei_guess, if self.apply_detector_eff and energy_bins: #should detector efficiency work on event workspace too? At the moment it is #not (01/02/2015) - DetectorEfficiencyCor(InputWorkspace=result_name,OutputWorkspace=result_name) - self.prop_man.log("_do_mono: finished DetectorEfficiencyCor for : " + result_name,'information') + DetectorEfficiencyCor(InputWorkspace=result_name,OutputWorkspace=result_name) + self.prop_man.log("_do_mono: finished DetectorEfficiencyCor for : " + result_name,'information') ############# data_run.synchronize_ws(mtd[result_name]) - return + return #------------------------------------------------------------------------------- def _find_or_build_bkgr_ws(self,result_ws,bkg_range_min=None,bkg_range_max=None,time_shift=0): - """ Method calculates background workspace or restore workspace with + """ Method calculates background workspace or restore workspace with the same name as the one produced by this method from ADS - """ + """ if not bkg_range_min or not bkg_range_max: bkg_range_min,bkg_range_max = self.bkgd_range bkg_range_min += time_shift bkg_range_max += time_shift - # has to have specific name for this all working. This ws is build at the beginning of + # has to have specific name for this all working. This ws is build at the beginning of # multirep run if 'bkgr_ws_source' in mtd: bkgr_ws = CloneWorkspace(InputWorkspace='bkgr_ws_source',OutputWorkspace='bkgr_ws') - if time_shift != 0: # Workspace has probably been shifted, so to have correct units conversion + if time_shift != 0: # Workspace has probably been shifted, so to have correct units conversion # one needs to do appropriate shift here as well - CopyInstrumentParameters(result_ws,bkgr_ws) + CopyInstrumentParameters(result_ws,bkgr_ws) # Adjust the TOF such that the first monitor peak is at t=0 - ScaleX(InputWorkspace=bkgr_ws,OutputWorkspace='bkgr_ws',Operation="Add",Factor=time_shift, + ScaleX(InputWorkspace=bkgr_ws,OutputWorkspace='bkgr_ws',Operation="Add",Factor=time_shift, InstrumentParameter="DelayTime",Combine=True) else: - bkgr_ws = Rebin(result_ws,Params=[bkg_range_min,(bkg_range_max - bkg_range_min) * 1.001,bkg_range_max],PreserveEvents=False) - bkgr_ws = self.normalise(bkgr_ws, self.normalise_method, time_shift) + bkgr_ws = Rebin(result_ws,Params=[bkg_range_min,(bkg_range_max - bkg_range_min) * 1.001,bkg_range_max],PreserveEvents=False) + bkgr_ws = self.normalise(bkgr_ws, self.normalise_method, time_shift) return bkgr_ws @@ -1386,13 +1386,13 @@ def _do_mono(self, run, ei_guess, """ if (self._do_ISIS_reduction): - self._do_mono_ISIS(run,ei_guess, + self._do_mono_ISIS(run,ei_guess, white_run, map_file, spectra_masks, Tzero) else: - result_name = run.set_action_suffix('_spe') - self._do_mono_SNS(run,result_name,ei_guess, + result_name = run.set_action_suffix('_spe') + self._do_mono_SNS(run,result_name,ei_guess, white_run, map_file, spectra_masks, Tzero) - run.synchronize_ws() + run.synchronize_ws() prop_man = self.prop_man result_name = run.get_ws_name() @@ -1405,8 +1405,8 @@ def _do_mono(self, run, ei_guess, # Make sure that our binning is consistent if prop_man.energy_bins: - bins = PropertyManager.energy_bins.get_abs_range(prop_man) - Rebin(InputWorkspace=result_name,OutputWorkspace= result_name,Params=bins) + bins = PropertyManager.energy_bins.get_abs_range(prop_man) + Rebin(InputWorkspace=result_name,OutputWorkspace= result_name,Params=bins) # Masking and grouping result_ws = mtd[result_name] @@ -1442,12 +1442,12 @@ def _get_wb_inegrals(self,run): old_log_val = targ_ws.getRun().getLogData(done_Log).value done_log_VAL = self._build_white_tag() if old_log_val == done_log_VAL: - run.synchronize_ws(targ_ws) - if self._keep_wb_workspace: + run.synchronize_ws(targ_ws) + if self._keep_wb_workspace: result = run.get_ws_clone() - else: + else: result = run.get_workspace() - return result + return result else: DeleteWorkspace(Workspace=new_ws_name) else: @@ -1483,7 +1483,7 @@ def _get_wb_inegrals(self,run): return result #------------------------------------------------------------------------------- def _build_white_tag(self): - """ build tag indicating wb-integration ranges """ + """ build tag indicating wb-integration ranges """ low,upp = self.wb_integr_range white_tag = 'NormBy:{0}_IntergatedIn:{1:0>10.2f}:{2:0>10.2f}'.format(self.normalise_method,low,upp) return white_tag @@ -1502,7 +1502,7 @@ def get_failed_spectra_list_from_masks(masked_wksp): failed_spectra = [] if masked_wksp is None: - return (failed_spectra,0) + return (failed_spectra,0) masking_wksp,sp_list = ExtractMask(masked_wksp) DeleteWorkspace(masking_wksp) @@ -1514,4 +1514,4 @@ def get_failed_spectra_list_from_masks(masked_wksp): #----------------------------------------------------------------- if __name__ == "__main__": pass - #unittest.main() \ No newline at end of file + #unittest.main() diff --git a/Code/Mantid/scripts/Inelastic/Direct/NonIDF_Properties.py b/Code/Mantid/scripts/Inelastic/Direct/NonIDF_Properties.py index 4ff69c2b4c71..7fcdcf165c34 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/NonIDF_Properties.py +++ b/Code/Mantid/scripts/Inelastic/Direct/NonIDF_Properties.py @@ -3,13 +3,13 @@ class NonIDF_Properties(object): - """ Class defines the interface for main properties, used in reduction, and not described in + """ Class defines the interface for main properties, used in reduction, and not described in IDF ( Instrument_Properties.xml file) - These properties are main set of properties, user have to set up - for reduction to work with defaults. + These properties are main set of properties, user have to set up + for reduction to work with defaults. - The example of such properties are run numbers, energy bins and incident energies. + The example of such properties are run numbers, energy bins and incident energies. """ # logging levels available for user @@ -21,9 +21,9 @@ class NonIDF_Properties(object): "debug" : (5,lambda (msg): logger.debug(msg))} - def __init__(self,Instrument,run_workspace=None): + def __init__(self,Instrument,run_workspace=None): """ initialize main properties, defined by the class - @parameter Instrument -- name or pointer to the instrument, + @parameter Instrument -- name or pointer to the instrument, deployed in reduction """ # @@ -35,14 +35,14 @@ def __init__(self,Instrument,run_workspace=None): object.__setattr__(self,'_log_to_mantid',False) object.__setattr__(self,'_current_log_level',3) - + object.__setattr__(self,'_psi',float('NaN')) # SNS motor stuff which is difficult to test as I've never seen it object.__setattr__(self,'_motor_name',None) object.__setattr__(self,'_motor_offset',0) object.__setattr__(self,'_save_file_name',None) - + self._set_instrument_and_facility(Instrument,run_workspace) # set up descriptors holder class reference @@ -68,8 +68,8 @@ def log(self, msg,level="notice"): logger(msg) else: # TODO: reconcile this with Mantid. - if lev <= self._current_log_level: - print msg + if lev <= self._current_log_level: + print msg #----------------------------------------------------------------------------- # Complex properties with personal descriptors #----------------------------------------------------------------------------- @@ -93,8 +93,8 @@ def log(self, msg,level="notice"): wb_for_monovan_run = RunDescriptorDependent(wb_run,"MV_WB_"," white beam run used to calculate monovanadium integrals.\n If not explicitly set, white beam for processing run is used") # TODO: do something about it. Second white is explicitly used in # diagnostics but not accessed at all - second_white = RunDescriptor("Second white beam currently unused in the workflow despite being referred to in Diagnostics. Should it be used for Monovan Diagnostics?") - # + second_white = RunDescriptor("Second white beam currently unused in the workflow despite being referred to in Diagnostics. Should it be used for Monovan Diagnostics?") + # _tmp_run = RunDescriptor("_TMP","Property used for storing intermediate run data during reduction") # property responsible for summing runs sum_runs = SumRuns(sample_run) @@ -106,7 +106,7 @@ def getDefaultParameterValue(self,par_name): def instrument(self): if self._pInstrument is None: raise KeyError("Attempt to use uninitialized property manager") - else: + else: return self._pInstrument # #----------------------------------------------------------------------------------- @@ -122,7 +122,7 @@ def print_diag_results(self,value): # ----------------------------------------------------------------------------- @property def log_to_mantid(self): - """ Property specify if high level log should be printed to stdout or added to common Mantid log""" + """ Property specify if high level log should be printed to stdout or added to common Mantid log""" return self._log_to_mantid @log_to_mantid.setter @@ -130,11 +130,11 @@ def log_to_mantid(self,val): object.__setattr__(self,'_log_to_mantid',bool(val)) # ----------------------------------------------------------------------------- #----------------------------------------------------------------------------------- - @property + @property def psi(self): """ rotation angle (not available from IDF)""" return self._psi - @psi.setter + @psi.setter def psi(self,value): """set rotation angle (not available from IDF). This value will be saved into NXSpe file""" object.__setattr__(self,'_psi',value) @@ -170,7 +170,7 @@ def _set_instrument_and_facility(self,Instrument,run_workspace=None): if isinstance(Instrument,geometry._geometry.Instrument): instrument = Instrument instr_name = instrument.getFullName() - try: + try: new_name,full_name,facility_ = prop_helpers.check_instrument_name(None,instr_name) except KeyError: # the instrument pointer is not found in any facility but we have it after all new_name = instr_name @@ -185,7 +185,7 @@ def _set_instrument_and_facility(self,Instrument,run_workspace=None): idf_file = api.ExperimentInfo.getInstrumentFilename(full_name) tmp_ws_name = '__empty_' + full_name if not mtd.doesExist(tmp_ws_name): - LoadEmptyInstrument(Filename=idf_file,OutputWorkspace=tmp_ws_name) + LoadEmptyInstrument(Filename=idf_file,OutputWorkspace=tmp_ws_name) instrument = mtd[tmp_ws_name].getInstrument() else: raise TypeError(' neither correct instrument name nor instrument pointer provided as instrument parameter') @@ -195,7 +195,7 @@ def _set_instrument_and_facility(self,Instrument,run_workspace=None): object.__setattr__(self,'_facility',facility_) object.__setattr__(self,'_short_instr_name',new_name) - + diff --git a/Code/Mantid/scripts/Inelastic/Direct/PropertiesDescriptors.py b/Code/Mantid/scripts/Inelastic/Direct/PropertiesDescriptors.py index 6cd58050e8b7..b2efa1f7dcbc 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/PropertiesDescriptors.py +++ b/Code/Mantid/scripts/Inelastic/Direct/PropertiesDescriptors.py @@ -1,6 +1,6 @@ """ File contains collection of Descriptors used to define complex - properties in NonIDF_Properties and PropertyManager classes -""" + properties in NonIDF_Properties and PropertyManager classes +""" import os from mantid.simpleapi import * @@ -17,7 +17,7 @@ class PropDescriptor(object): """ Class provides common custom interface for property descriptors """ def dependencies(self): - """ Returns the list of other properties names, this property depends on""" + """ Returns the list of other properties names, this property depends on""" return [] # end PropDescriptor @@ -26,12 +26,12 @@ def dependencies(self): #----------------------------------------------------------------------------------------- #----------------------------------------------------------------------------------------- class SumRuns(PropDescriptor): - """ Boolean property specifies if list of files provided as input for sample_run property - should be summed. + """ Boolean property specifies if list of files provided as input for sample_run property + should be summed. - It also specifies various auxiliary operations, defined for summing runs, so property + It also specifies various auxiliary operations, defined for summing runs, so property is deeply entangled with the sample_run property - """ + """ def __init__(self,sample_run_prop): # internal reference to sample run property self._sample_run = sample_run_prop @@ -47,28 +47,28 @@ def __init__(self,sample_run_prop): # def __get__(self,instance,holder_class): - if not self._holder: - self._holder = holder_class - if instance is None: - return self - return self._sum_runs + if not self._holder: + self._holder = holder_class + if instance is None: + return self + return self._sum_runs # def __set__(self,instance,value): if not self._holder: - from Direct.PropertyManager import PropertyManager - self._holder = PropertyManager - + from Direct.PropertyManager import PropertyManager + self._holder = PropertyManager + old_value = self._sum_runs if isinstance(value,bool): self._sum_runs = value self._last_ind2sum = -1 elif isinstance(value,int): if value > 0: - self._last_ind2sum = int(value) - 1 - self._sum_runs = True + self._last_ind2sum = int(value) - 1 + self._sum_runs = True else: - self._last_ind2sum = -1 - self._sum_runs = False + self._last_ind2sum = -1 + self._sum_runs = False else: self._sum_runs = bool(value) self._last_ind2sum = -1 @@ -76,29 +76,29 @@ def __set__(self,instance,value): if old_value != self._sum_runs: if len(self._run_numbers) > 0 and self._sum_runs: # clear previous state of sample_run - ind = self.get_last_ind2sum() - self._sample_run.__set__(None,self._run_numbers[ind]) + ind = self.get_last_ind2sum() + self._sample_run.__set__(None,self._run_numbers[ind]) # def set_list2add(self,runs_to_add,fnames=None,fext=None): - """Set run numbers to add together with possible file guess-es """ - if not isinstance(runs_to_add,list): - raise KeyError('Can only set list of run numbers to add') - runs = [] - for item in runs_to_add: - runs.append(int(item)) - self._run_numbers = runs - if fnames: - self._file_guess = fnames - if len(self._file_guess) != len(self._run_numbers): - self._file_guess = [''] * len(self._run_numbers) - - if fext: - self._fext = fext - if len(self._fext) != len(self._run_numbers): - self._fext = [''] * len(self._run_numbers) + """Set run numbers to add together with possible file guess-es """ + if not isinstance(runs_to_add,list): + raise KeyError('Can only set list of run numbers to add') + runs = [] + for item in runs_to_add: + runs.append(int(item)) + self._run_numbers = runs + if fnames: + self._file_guess = fnames + if len(self._file_guess) != len(self._run_numbers): + self._file_guess = [''] * len(self._run_numbers) + + if fext: + self._fext = fext + if len(self._fext) != len(self._run_numbers): + self._fext = [''] * len(self._run_numbers) # def clear_sum(self): - """Clear all defined summation""" + """Clear all defined summation""" # if last_to_sum is -1, sum all run list provided self._last_ind2sum = -1 self._sum_runs = False @@ -107,14 +107,14 @@ def clear_sum(self): self._fext = [] # def get_last_ind2sum(self): - """Get last run number contributing to sum""" + """Get last run number contributing to sum""" if self._last_ind2sum > 0: - return self._last_ind2sum + return self._last_ind2sum else: - return len(self._run_numbers) - 1 + return len(self._run_numbers) - 1 # def set_last_ind2sum(self,run_number): - """Check and set last number, contributing to summation + """Check and set last number, contributing to summation if this number is out of summation range, clear the summation """ run_number = int(run_number) @@ -126,15 +126,15 @@ def set_last_ind2sum(self,run_number): return 0 # def get_run_list2sum(self): - """Get run numbers of the files to be summed together """ + """Get run numbers of the files to be summed together """ num_to_load = len(self._run_numbers) if self._last_ind2sum > 0 and self._last_ind2sum < num_to_load: - num_to_load = self._last_ind2sum + num_to_load = self._last_ind2sum return self._run_numbers[:num_to_load] # def load_and_sum_runs(self,inst_name,monitors_with_ws): - """ Load multiple runs and sum them together """ + """ Load multiple runs and sum them together """ logger = lambda mess : (getattr(getattr(self,'_holder'),'log')\ (self._sample_run._holder,mess)) @@ -157,27 +157,27 @@ def load_and_sum_runs(self,inst_name,monitors_with_ws): for ind,run_num in enumerate(runs_to_load[1:num_to_load]): - file_h = os.path.join(self._file_guess[ind + 1],'{0}{1}{2}'.\ + file_h = os.path.join(self._file_guess[ind + 1],'{0}{1}{2}'.\ format(inst_name,run_num,self._fext[ind + 1])) - logger("*** Adding #{0}/{1}, run N: {2} ".\ + logger("*** Adding #{0}/{1}, run N: {2} ".\ format(ind + 2,num_to_load,run_num)) - term_name = '{0}_ADDITIVE_#{1}/{2}'.format(inst_name,ind + 2,num_to_load)# + term_name = '{0}_ADDITIVE_#{1}/{2}'.format(inst_name,ind + 2,num_to_load)# - wsp = self._sample_run.load_file(inst_name,term_name,False, + wsp = self._sample_run.load_file(inst_name,term_name,False, monitors_with_ws,False,file_hint=file_h) - wsp_name = wsp.name() - wsp_mon_name = wsp_name + '_monitors' - Plus(LHSWorkspace=sum_ws_name,RHSWorkspace=wsp_name, + wsp_name = wsp.name() + wsp_mon_name = wsp_name + '_monitors' + Plus(LHSWorkspace=sum_ws_name,RHSWorkspace=wsp_name, OutputWorkspace=sum_ws_name,ClearRHSWorkspace=True) - AddedRunNumbers+=',{0}'.format(run_num) - if not monitors_with_ws: - Plus(LHSWorkspace=sum_mon_name,RHSWorkspace=wsp_mon_name, + AddedRunNumbers+=',{0}'.format(run_num) + if not monitors_with_ws: + Plus(LHSWorkspace=sum_mon_name,RHSWorkspace=wsp_mon_name, OutputWorkspace=sum_mon_name,ClearRHSWorkspace=True) - if wsp_name in mtd: - DeleteWorkspace(wsp_name) - if wsp_mon_name in mtd: - DeleteWorkspace(wsp_mon_name) + if wsp_name in mtd: + DeleteWorkspace(wsp_name) + if wsp_mon_name in mtd: + DeleteWorkspace(wsp_mon_name) logger("*** Summing multiple runs completed ****") AddSampleLog(Workspace=sum_ws_name,LogName = 'SumOfRuns:', @@ -185,7 +185,7 @@ def load_and_sum_runs(self,inst_name,monitors_with_ws): ws = mtd[sum_ws_name] return ws # - def sum_ext(self): + def sum_ext(self): if self._sum_runs: last = self.get_last_ind2sum() sum_ext = "SumOf{0}".format(len(self._run_numbers[:last + 1])) @@ -197,82 +197,82 @@ def get_runs(self): return self._run_numbers #-------------------------------------------------------------------------------------------------------------------- class IncidentEnergy(PropDescriptor): - """ Property for incident energy or range of incident energies to be processed + """ Property for incident energy or range of incident energies to be processed - Set it up to list of values (even with single value i.e. prop_man.incident_energy=[10]) + Set it up to list of values (even with single value i.e. prop_man.incident_energy=[10]) if the energy_bins property value to be treated as relative energy ranges. - Set it up to single value (e.g. prop_man.incident_energy=10) to treat energy energy_bins + Set it up to single value (e.g. prop_man.incident_energy=10) to treat energy energy_bins as absolute energy values """ - def __init__(self): + def __init__(self): self._incident_energy = 0 self._num_energies = 1 self._cur_iter_en = 0 def __get__(self,instance,owner=None): - """ return incident energy or list of incident energies """ + """ return incident energy or list of incident energies """ if instance is None: - return self + return self - return self._incident_energy + return self._incident_energy def __set__(self,instance,value): - """ Set up incident energy or range of energies in various formats """ - if value != None: - if isinstance(value,str): - if value.find('[') > -1: - energy_list = True - value = value.translate(None, '[]').strip() - else: - energy_list = False - en_list = str.split(value,',') - if len(en_list) > 1: - rez = [] - for en_str in en_list: - val = float(en_str) - rez.append(val) - self._incident_energy = rez - else: - if energy_list: - self._incident_energy = [float(value)] - else: - self._incident_energy = float(value) - else: - if isinstance(value,list): - rez = [] - for val in value: - en_val = float(val) - if en_val <= 0: - raise KeyError("Incident energy has to be positive, but is: {0} ".format(en_val)) + """ Set up incident energy or range of energies in various formats """ + if value != None: + if isinstance(value,str): + if value.find('[') > -1: + energy_list = True + value = value.translate(None, '[]').strip() + else: + energy_list = False + en_list = str.split(value,',') + if len(en_list) > 1: + rez = [] + for en_str in en_list: + val = float(en_str) + rez.append(val) + self._incident_energy = rez + else: + if energy_list: + self._incident_energy = [float(value)] else: - rez.append(en_val) - self._incident_energy = rez + self._incident_energy = float(value) else: - self._incident_energy = float(value) - else: - raise KeyError("Incident energy have to be positive number of list of positive numbers. Got None") - + if isinstance(value,list): + rez = [] + for val in value: + en_val = float(val) + if en_val <= 0: + raise KeyError("Incident energy has to be positive, but is: {0} ".format(en_val)) + else: + rez.append(en_val) + self._incident_energy = rez + else: + self._incident_energy = float(value) + else: + raise KeyError("Incident energy have to be positive number of list of positive numbers. Got None") + # - inc_en = self._incident_energy - if isinstance(inc_en,list): - self._num_energies = len(inc_en) - for en in inc_en: - if en <= 0: - raise KeyError("Incident energy have to be positive number of list of positive numbers." + " For input argument {0} got negative value {1}".format(value,en)) - else: - self._num_energies = 1 - if inc_en <= 0: - raise KeyError("Incident energy have to be positive number of list of positive numbers." + " For value {0} got negative {1}".format(value,inc_en)) - self._cur_iter_en = 0 - + inc_en = self._incident_energy + if isinstance(inc_en,list): + self._num_energies = len(inc_en) + for en in inc_en: + if en <= 0: + raise KeyError("Incident energy have to be positive number of list of positive numbers." + " For input argument {0} got negative value {1}".format(value,en)) + else: + self._num_energies = 1 + if inc_en <= 0: + raise KeyError("Incident energy have to be positive number of list of positive numbers." + " For value {0} got negative {1}".format(value,inc_en)) + self._cur_iter_en = 0 + def multirep_mode(self): - """ return true if energy is defined as list of energies and false otherwise """ + """ return true if energy is defined as list of energies and false otherwise """ if isinstance(self._incident_energy,list): return True else: return False def get_current(self): - """ Return current energy out of range of energies""" + """ Return current energy out of range of energies""" if isinstance(self._incident_energy,list): ind = self._cur_iter_en return self._incident_energy[ind] @@ -280,8 +280,8 @@ def get_current(self): return self._incident_energy # def set_current(self,value): - """ set current energy value (used in multirep mode) to - + """ set current energy value (used in multirep mode) to + """ if isinstance(self._incident_energy,list): ind = self._cur_iter_en @@ -296,28 +296,28 @@ def __iter__(self): return self def next(self): # Python 3: def __next__(self) - """ part of iterator """ + """ part of iterator """ self._cur_iter_en += 1 ind = self._cur_iter_en if ind < self._num_energies: - if isinstance(self._incident_energy,list): - return self._incident_energy[ind] - else: - return self._incident_energy + if isinstance(self._incident_energy,list): + return self._incident_energy[ind] + else: + return self._incident_energy else: - raise StopIteration + raise StopIteration # end IncidentEnergy #----------------------------------------------------------------------------------------- class EnergyBins(PropDescriptor): - """ Energy binning, requested for final converted to energy transfer workspace. + """ Energy binning, requested for final converted to energy transfer workspace. Provide it in the form: - [min_energy,step,max_energy] if energy to process (incident_energy property ) + [min_energy,step,max_energy] if energy to process (incident_energy property ) has a single value - or + or [min_rel_enrgy,rel_step,max_rel_energy] where rel_energy is relative energy - if energy(ies) to process are list of energies. The list of energies can + if energy(ies) to process are list of energies. The list of energies can consist of single value (e.g. prop_man.incident_energy=[100]) """ @@ -330,22 +330,22 @@ def __init__(self,IncidentEnergyProp): def __get__(self,instance,owner=None): """ binning range for the result of convertToenergy procedure or list of such ranges """ if instance is None: - return self + return self return self._energy_bins def __set__(self,instance,values): - if values != None: - if isinstance(values,str): - values = values.translate(None, '[]').strip() - lst = values.split(',') - self.__set__(instance,lst) - return - else: - value = values - if len(value) != 3: - raise KeyError("Energy_bin value has to be a tuple of 3 elements or string of 3 comma-separated numbers") - value = (float(value[0]),float(value[1]),float(value[2])) + if values != None: + if isinstance(values,str): + values = values.translate(None, '[]').strip() + lst = values.split(',') + self.__set__(instance,lst) + return + else: + value = values + if len(value) != 3: + raise KeyError("Energy_bin value has to be a tuple of 3 elements or string of 3 comma-separated numbers") + value = (float(value[0]),float(value[1]),float(value[2])) # Let's not support list of multiple absolute energy bins for the # time being # nBlocks = len(value) @@ -353,51 +353,51 @@ def __set__(self,instance,values): # raise KeyError("Energy_bin value has to be either list of # n-blocks of 3 number each or string representation of this list # with numbers separated by commas") - else: - value = None + else: + value = None #TODO: implement single value settings according to rebin? - self._energy_bins = value + self._energy_bins = value def get_abs_range(self,instance=None): - """ return energies related to incident energies either as - + """ return energies related to incident energies either as + """ if self._incident_energy.multirep_mode(): # Relative energy ei = self._incident_energy.get_current() if self._energy_bins: if self.is_range_valid(): - rez = self._calc_relative_range(ei) + rez = self._calc_relative_range(ei) else: - if instance: - instance.log("*** WARNING! Got energy_bins specified as absolute values in multirep mode.\n"\ + if instance: + instance.log("*** WARNING! Got energy_bins specified as absolute values in multirep mode.\n"\ " Will normalize these values by max value and treat as relative values ", "warning") - mult = self._range / self._energy_bins[2] - rez = self._calc_relative_range(ei,mult) + mult = self._range / self._energy_bins[2] + rez = self._calc_relative_range(ei,mult) return rez else: - return None + return None else: # Absolute energy ranges - if self.is_range_valid(): - return self._energy_bins - else: - if instance: - instance.log("*** WARNING! Requested maximum binning range exceeds incident energy!\n"\ + if self.is_range_valid(): + return self._energy_bins + else: + if instance: + instance.log("*** WARNING! Requested maximum binning range exceeds incident energy!\n"\ " Will normalize binning range by max value and treat as relative range", "warning") - mult = self._range / self._energy_bins[2] - ei = self._incident_energy.get_current() - return self._calc_relative_range(ei,mult) + mult = self._range / self._energy_bins[2] + ei = self._incident_energy.get_current() + return self._calc_relative_range(ei,mult) def is_range_valid(self): - """Method verifies if binning range is consistent with incident energy """ + """Method verifies if binning range is consistent with incident energy """ if self._incident_energy.multirep_mode(): return (self._energy_bins[2] <= self._range) else: return (self._energy_bins[2] <= self._incident_energy.get_current()) def _calc_relative_range(self,ei,range_mult=1): - """ """ + """ """ mult = range_mult * ei return (self._energy_bins[0] * mult ,self._energy_bins[1] * mult,self._energy_bins[2] * mult) @@ -410,16 +410,16 @@ class SaveFileName(PropDescriptor): See similar property get_sample_ws_name TODO: (leave only one) """ def __init__(self,Name=None): - self._file_name = Name + self._file_name = Name def __get__(self,instance,owner=None): if instance is None: - return self + return self if self._file_name: return self._file_name else: if instance.instr_name: - name = instance.short_inst_name + name = instance.short_inst_name else: name = '_EMPTY' @@ -443,26 +443,26 @@ def __set__(self,instance,value): #end SaveFileName #----------------------------------------------------------------------------------------- class InstrumentDependentProp(PropDescriptor): - """ Generic property describing some aspects of instrument (e.g. name, short name etc), + """ Generic property describing some aspects of instrument (e.g. name, short name etc), which are undefined if no instrument is defined """ def __init__(self,prop_name): self._prop_name = prop_name def __get__(self,instance,owner=None): - if instance is None: - return self + if instance is None: + return self - if instance._pInstrument is None: + if instance._pInstrument is None: raise KeyError("Attempt to use uninitialized property manager") - else: + else: return getattr(instance,self._prop_name) def __set__(self,instance,values): raise AttributeError("Property {0} can not be assigned".format(self._prop_name)) #end InstrumentDependentProp #----------------------------------------------------------------------------------------- def check_ei_bin_consistent(ei,binning_range): - """ function verifies if the energy binning is consistent with incident energies """ + """ function verifies if the energy binning is consistent with incident energies """ if isinstance(ei,list): for en in ei: range = binning_range[en] @@ -475,7 +475,7 @@ def check_ei_bin_consistent(ei,binning_range): return (True,'') #----------------------------------------------------------------------------------------- class VanadiumRMM(PropDescriptor): - """ define constant static rmm for vanadium """ + """ define constant static rmm for vanadium """ def __get__(self,instance,owner=None): """ return rmm for vanadium """ @@ -492,35 +492,35 @@ def __set__(self,instance,value): # PropertyManager #----------------------------------------------------------------------------------------- class mon2NormalizationEnergyRange(PropDescriptor): - """ Energy range to integrate signal on monitor 2 when normalized by this monitor - - This class contains relative range of energies in which the monitor-2 signal should - be integrated, and returns the energy range for integration according to + """ Energy range to integrate signal on monitor 2 when normalized by this monitor + + This class contains relative range of energies in which the monitor-2 signal should + be integrated, and returns the energy range for integration according to formula: range = [min_range*ei,max_range*ei] where ei is incident monitor energy - To find actual integration ranges one should convert these values into TOF (or + To find actual integration ranges one should convert these values into TOF (or convert monitor signal to energy) - """ + """ def __init__(self): # default range self._relative_range = [0.8,1.2] def __get__(self,instance,owner): - """ Return actual energy range from internal relative range and incident energy """ - if instance is None: - return self - return [self._relative_range[0] * instance.incident_energy,self._relative_range[1] * instance.incident_energy] + """ Return actual energy range from internal relative range and incident energy """ + if instance is None: + return self + return [self._relative_range[0] * instance.incident_energy,self._relative_range[1] * instance.incident_energy] def __set__(self,instance,val): - """ set detector calibration file using various formats """ - if isinstance(val,list): - self._relative_range = self._check_range(val,instance) - elif isinstance(val,str): - val = self._parce_string2list(val) - self.__set__(instance,val) - else: - raise KeyError('mon2_norm_energy_range needs to be initialized by two values.\n' + """ set detector calibration file using various formats """ + if isinstance(val,list): + self._relative_range = self._check_range(val,instance) + elif isinstance(val,str): + val = self._parce_string2list(val) + self.__set__(instance,val) + else: + raise KeyError('mon2_norm_energy_range needs to be initialized by two values.\n' 'Trying to assign value {0} of unknown type {1}'.format(val,type(val))) # def _check_range(self,val,instance): @@ -537,12 +537,12 @@ def _check_range(self,val,instance): instance.log(message,'warning') val2 = float(val[1]) if val2 < 1.1 or val2 > 1.9: - message = "Upper mon2_norm_energy_range describes upper limit of energy to integrate neutron signal after the chopper.\n"\ + message = "Upper mon2_norm_energy_range describes upper limit of energy to integrate neutron signal after the chopper.\n"\ "The limit is defined as (this value)*incident_energy. Are you sure you want to set this_value to {0}?\n".format(val2) - if val2 < 1: - raise KeyError(message) - else: - instance.log(message,'warning') + if val2 < 1: + raise KeyError(message) + else: + instance.log(message,'warning') return [val1,val2] # @@ -562,15 +562,15 @@ def __init__(self,availible_values,default_value): def __get__(self,instance,owner): """ Return current value for the property with range of values. """ if instance is None: - return self + return self return self._current_value def __set__(self,instance,val): - """ set detector calibration file using various formats """ - if val in self._availible_values: - self._current_value = val - else: - raise KeyError(' Property can not have value {0}'.format(val)) + """ set detector calibration file using various formats """ + if val in self._availible_values: + self._current_value = val + else: + raise KeyError(' Property can not have value {0}'.format(val)) #----------------------------------------------------------------------------------------- class DetCalFile(PropDescriptor): @@ -580,31 +580,31 @@ def __init__(self): def __get__(self,instance,owner): if instance is None: - return self + return self return self._det_cal_file def __set__(self,instance,val): - """ set detector calibration file using various formats """ - - if val is None or isinstance(val,api.Workspace) or isinstance(val,str): + """ set detector calibration file using various formats """ + + if val is None or isinstance(val,api.Workspace) or isinstance(val,str): # nothing provided or workspace provided or filename probably provided - if str(val) in mtd: + if str(val) in mtd: # workspace name provided val = mtd[str(val)] - self._det_cal_file = val - return - + self._det_cal_file = val + return - if isinstance(val,int): + + if isinstance(val,int): #if val in instance.all_run_numbers: TODO: retrieve workspace from #run numbers - file_hint = str(val) - file_name = FileFinder.findRuns(file_hint)[0] - self._det_cal_file = file_name - return + file_hint = str(val) + file_name = FileFinder.findRuns(file_hint)[0] + self._det_cal_file = file_name + return - raise NameError('Detector calibration file name can be a workspace name present in Mantid or string describing an file name') + raise NameError('Detector calibration file name can be a workspace name present in Mantid or string describing an file name') #if Reducer.det_cal_file != None : # if isinstance(Reducer.det_cal_file,str) and not Reducer.det_cal_file # in mtd : # it is a file @@ -628,56 +628,56 @@ def __init__(self,file_ext,doc_string=None): def __get__(self,instance,type=None): if instance is None: - return self + return self return self._file_name def __set__(self,instance,value): if value != None: - fileName, fileExtension = os.path.splitext(value) - if (not fileExtension): - value = value + self._file_ext + fileName, fileExtension = os.path.splitext(value) + if (not fileExtension): + value = value + self._file_ext self._file_name = value - + #end MapMaskFile #----------------------------------------------------------------------------------------- class HardMaskPlus(prop_helpers.ComplexProperty): - """ Legacy HardMaskPlus class which sets up hard_mask_file to file and use_hard_mask_only to True""" + """ Legacy HardMaskPlus class which sets up hard_mask_file to file and use_hard_mask_only to True""" def __init__(self): prop_helpers.ComplexProperty.__init__(self,['use_hard_mask_only','run_diagnostics']) def __get__(self,instance,type=None): if instance is None: - return self + return self return instance.hard_mask_file def __set__(self,instance,value): if value != None: - fileName, fileExtension = os.path.splitext(value) - if (not fileExtension): - value = value + '.msk' - instance.hard_mask_file = value - prop_helpers.ComplexProperty.__set__(self,instance.__dict__,[False,True]) + fileName, fileExtension = os.path.splitext(value) + if (not fileExtension): + value = value + '.msk' + instance.hard_mask_file = value + prop_helpers.ComplexProperty.__set__(self,instance.__dict__,[False,True]) else: - prop_helpers.ComplexProperty.__set__(self,instance.__dict__,[True,False]) + prop_helpers.ComplexProperty.__set__(self,instance.__dict__,[True,False]) try: - del instance.__changed_properties['hardmaskOnly'] + del instance.__changed_properties['hardmaskOnly'] except: - pass - + pass + #----------------------------------------------------------------------------------------- class HardMaskOnly(prop_helpers.ComplexProperty): """ Sets diagnostics algorithm to use hard mask file provided and to disable all other diagnostics routines It controls two options, where the first one is use_hard_mask_only=True/False, controls diagnostics algorithm - and another one: hard_mask_file provides file for masking. + and another one: hard_mask_file provides file for masking. """ def __init__(self): prop_helpers.ComplexProperty.__init__(self,['use_hard_mask_only','run_diagnostics']) def __get__(self,instance,type=None): if instance is None: - return self + return self return prop_helpers.gen_getter(instance.__dict__,'use_hard_mask_only') def __set__(self,instance,value): @@ -694,7 +694,7 @@ def __set__(self,instance,value): elif value.lower() in ['false','no']: use_hard_mask_only = False else: # it is probably a hard mask file provided: - instance.hard_mask_file = value + instance.hard_mask_file = value use_hard_mask_only = True hard_mask_file = instance.hard_mask_file #end @@ -707,9 +707,9 @@ def __set__(self,instance,value): run_diagnostics = True prop_helpers.ComplexProperty.__set__(self,instance.__dict__,[use_hard_mask_only,run_diagnostics]) try: - del instance.__changed_properties['hardmaskPlus'] + del instance.__changed_properties['hardmaskPlus'] except: - pass + pass #end HardMaskOnly #----------------------------------------------------------------------------------------- class MonovanIntegrationRange(prop_helpers.ComplexProperty): @@ -718,28 +718,28 @@ class MonovanIntegrationRange(prop_helpers.ComplexProperty): Defined either directly or as the function of the incident energy(s) - If list of incident energies is provided, map of ranges in the form 'ei'=range is returned + If list of incident energies is provided, map of ranges in the form 'ei'=range is returned """ def __init__(self,DepType=None): if DepType: self._rel_range = False prop_helpers.ComplexProperty.__init__(self,['monovan_lo_value','monovan_hi_value']) else: - self._rel_range = True + self._rel_range = True prop_helpers.ComplexProperty.__init__(self,['monovan_lo_frac','monovan_hi_frac']) pass def __get__(self,instance,owner): if instance is None: - return self + return self if isinstance(instance,dict): - ei = 1 - tDict = instance + ei = 1 + tDict = instance else: - ei = owner.incident_energy.get_current() - tDict = instance.__dict__ + ei = owner.incident_energy.get_current() + tDict = instance.__dict__ if self._rel_range: # relative range if ei is None: @@ -752,17 +752,17 @@ def __get__(self,instance,owner): def __set__(self,instance,value): if isinstance(instance,dict): - dDict = instance + dDict = instance else: - tDict = instance.__dict__ + tDict = instance.__dict__ if value is None: if (not self._rel_range): self._rel_range = True self._other_prop = ['monovan_lo_frac','monovan_hi_frac'] else: if self._rel_range: - self._rel_range = False - self._other_prop = ['monovan_lo_value','monovan_hi_value'] + self._rel_range = False + self._other_prop = ['monovan_lo_value','monovan_hi_value'] if isinstance(value,str): values = value.split(',') @@ -778,33 +778,33 @@ def __set__(self,instance,value): #----------------------------------------------------------------------------------------- class SpectraToMonitorsList(PropDescriptor): - """ property describes list of spectra, used as monitors to estimate incident energy - in a direct scattering experiment. + """ property describes list of spectra, used as monitors to estimate incident energy + in a direct scattering experiment. - Necessary when a detector working in event mode is used as monitor. Specifying this number would copy + Necessary when a detector working in event mode is used as monitor. Specifying this number would copy correspondent spectra to monitor workspace and rebin it according to monitors binning Written to work with old IDF too, where this property is absent. - """ - def __init__(self): - self._spectra_to_monitors_list = None + """ + def __init__(self): + self._spectra_to_monitors_list = None - def __get__(self,instance,type=None): - if instance is None: - return self - return self._spectra_to_monitors_list + def __get__(self,instance,type=None): + if instance is None: + return self + return self._spectra_to_monitors_list - def __set__(self,instance,spectra_list): + def __set__(self,instance,spectra_list): """ Sets copy spectra to monitors variable as a list of monitors using different forms of input """ self._spectra_to_monitors_list = self._convert_to_list(spectra_list) - def _convert_to_list(self,spectra_list): - """ convert any spectra_list representation into a list """ - if spectra_list is None: + def _convert_to_list(self,spectra_list): + """ convert any spectra_list representation into a list """ + if spectra_list is None: return None - if isinstance(spectra_list,str): + if isinstance(spectra_list,str): if spectra_list.lower() is 'none': result = None else: @@ -813,7 +813,7 @@ def _convert_to_list(self,spectra_list): for spectum in spectra : result.append(int(spectum)) - else: + else: if isinstance(spectra_list,list): if len(spectra_list) == 0: result = None @@ -823,23 +823,23 @@ def _convert_to_list(self,spectra_list): result.append(int(spectra_list[i])) else: result = [int(spectra_list)] - return result + return result #end SpectraToMonitorsList #----------------------------------------------------------------------------------------- class SaveFormat(PropDescriptor): # formats available for saving the data - save_formats = ['spe','nxspe','nxs'] - def __init__(self): - self._save_format = set() + save_formats = ['spe','nxspe','nxs'] + def __init__(self): + self._save_format = set() - def __get__(self,instance,type=None): + def __get__(self,instance,type=None): if instance is None: - return self + return self return self._save_format - def __set__(self,instance,value): + def __set__(self,instance,value): """ user can clear save formats by setting save_format=None or save_format = [] or save_format='' if empty string or empty list is provided as part of the list, all save_format-s set up earlier are cleared""" @@ -856,19 +856,19 @@ def __set__(self,instance,value): self.__set__(instance,subformats) return else: - value = subformats[0] + value = subformats[0] if not(value in SaveFormat.save_formats): instance.log("Trying to set saving in unknown format: \"" + str(value) + "\" No saving will occur for this format") return - else: + else: try: # set single default save format recursively - for val in value: + for val in value: self.__set__(instance,val) - return - except: - raise KeyError(' Attempting to set unknown saving format {0} of type {1}. Allowed values can be spe, nxspe or nxs'\ + return + except: + raise KeyError(' Attempting to set unknown saving format {0} of type {1}. Allowed values can be spe, nxspe or nxs'\ .format(value,type(value))) #end if different types self._save_format.add(value) @@ -876,9 +876,9 @@ def __set__(self,instance,value): #----------------------------------------------------------------------------------------- class DiagSpectra(PropDescriptor): - """ class describes spectra list which should be used in diagnostics + """ class describes spectra list which should be used in diagnostics - consist of tuples list where each tuple are the numbers + consist of tuples list where each tuple are the numbers indicating first-last spectra in the group. if None, all spectra are used in diagnostics @@ -888,7 +888,7 @@ def __init__(self): def __get__(self,instance,type=None): if instance is None: - return self + return self return self._diag_spectra @@ -919,27 +919,27 @@ def _process_spectra_list(self,specta_sring): #----------------------------------------------------------------------------------------- class BackbgroundTestRange(PropDescriptor): - """ The TOF range used in diagnostics to reject high background spectra. + """ The TOF range used in diagnostics to reject high background spectra. - Usually it is the same range as the TOF range used to remove - background (usually in powders) though it may be set up separately. + Usually it is the same range as the TOF range used to remove + background (usually in powders) though it may be set up separately. """ def __init__(self): self._background_test_range = None def __get__(self,instance,type=None): - if instance is None: - return self + if instance is None: + return self - if self._background_test_range: - return self._background_test_range - else: + if self._background_test_range: + return self._background_test_range + else: return instance.bkgd_range def __set__(self,instance,value): if value is None: - self._background_test_range = None - return + self._background_test_range = None + return if isinstance(value,str): value = str.split(value,',') if len(value) != 2: @@ -949,52 +949,52 @@ def __set__(self,instance,value): #----------------------------------------------------------------------------------------- class MultirepTOFSpectraList(PropDescriptor): - """ property describes list of spectra numbers, used to identify - TOF range corresponding to the particular energy range + """ property describes list of spectra numbers, used to identify + TOF range corresponding to the particular energy range - Usually it is list of two numbers, specifying monitors which are - closest and furthest from the sample + Usually it is list of two numbers, specifying monitors which are + closest and furthest from the sample """ def __init__(self): self._spectra_list = None def __get__(self,instance,type=None): - if instance is None: - return self + if instance is None: + return self - return self._spectra_list + return self._spectra_list def __set__(self,instance,value): if value is None: - self._spectra_list = None - return + self._spectra_list = None + return if isinstance(value,str): value = str.split(value,',') self.__set__(instance,value) return if isinstance(value, list): - rez =[] - for val in value: - rez.append(int(val)) + rez =[] + for val in value: + rez.append(int(val)) else: rez = [int(value)] self._spectra_list=rez #end MultirepTOFSpectraList class MonoCorrectionFactor(PropDescriptor): - """ property contains correction factor, used to convert - experimental scattering cross-section into absolute - units ( mb/str/mev/fu) + """ property contains correction factor, used to convert + experimental scattering cross-section into absolute + units ( mb/str/mev/fu) - There are independent two sources for this factor: - 1) if user explicitly specifies correction value. - This value then will be applied to all subsequent runs + There are independent two sources for this factor: + 1) if user explicitly specifies correction value. + This value then will be applied to all subsequent runs without any checks if the correction is appropriate - 2) set/get cashed value correspondent to current monovan + 2) set/get cashed value correspondent to current monovan run number, incident energy and integration range. - This value is cashed at first run and reapplied if + This value is cashed at first run and reapplied if no changes to the values it depends on were identified - """ + """ def __init__(self,ei_prop): self._cor_factor = None self._mono_run_number=None @@ -1002,21 +1002,21 @@ def __init__(self,ei_prop): self.cashed_values={} def __get__(self,instance,type=None): - if instance is None: - return self + if instance is None: + return self - return self._cor_factor + return self._cor_factor def __set__(self,instance,value): - self._cor_factor = value - # + self._cor_factor = value + # def set_val_to_cash(self,instance,value): - """ """ + """ """ mono_int_range = instance.monovan_integr_range cash_id = self._build_cash_val_id(mono_int_range) self.cashed_values[cash_id] = value # tell property manager that mono_correction_factor has been modified - # to avoid automatic resetting this property from any workspace + # to avoid automatic resetting this property from any workspace cp = getattr(instance,'_PropertyManager__changed_properties') cp.add('mono_correction_factor') @@ -1024,24 +1024,24 @@ def get_val_from_cash(self,instance): mono_int_range = instance.monovan_integr_range cash_id = self._build_cash_val_id(mono_int_range) if cash_id in self.cashed_values: - return self.cashed_values[cash_id] + return self.cashed_values[cash_id] else: - return None - + return None + def set_cash_mono_run_number(self,new_value): if new_value is None: - self.cashed_values={} - self._mono_run_number = None - return + self.cashed_values={} + self._mono_run_number = None + return if self._mono_run_number != int(new_value): - self.cashed_values={} - self._mono_run_number = int(new_value) + self.cashed_values={} + self._mono_run_number = int(new_value) def _build_cash_val_id(self,mono_int_range): - ei = self._ei_prop.get_current() - cash_id = "Ei={0:0>9.4e}:Int({1:0>9.4e}:{2:0>9.5e}):Run{3}".\ + ei = self._ei_prop.get_current() + cash_id = "Ei={0:0>9.4e}:Int({1:0>9.4e}:{2:0>9.5e}):Run{3}".\ format(ei,mono_int_range[0],mono_int_range[1],self._mono_run_number) - return cash_id + return cash_id #----------------------------------------------------------------------------------------- diff --git a/Code/Mantid/scripts/Inelastic/Direct/PropertyManager.py b/Code/Mantid/scripts/Inelastic/Direct/PropertyManager.py index 987c33499bb5..9e436d64316f 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/PropertyManager.py +++ b/Code/Mantid/scripts/Inelastic/Direct/PropertyManager.py @@ -4,30 +4,30 @@ class PropertyManager(NonIDF_Properties): - """ Class defines the interface for Direct inelastic reduction with properties + """ Class defines the interface for Direct inelastic reduction with properties present in Instrument_Properties.xml file These properties are responsible for fine turning up of the reduction - Supported properties in IDF can be simple (prop[name]=value e.g. - prop['vanadium_mass']=30.5 - - or complex + Supported properties in IDF can be simple (prop[name]=value e.g. + prop['vanadium_mass']=30.5 + + or complex where prop[name_complex_prop] value is equal [prop[name_1],prop[name_2]] e.g. time interval used in normalization on monitor 1: prop[norm_mon_integration_range] = [prop['norm-mon1-min'],prop['norm-mon1-max']] prop['norm-mon1-min']=1000,prop['norm-mon1-max']=2000 - There are properties which provide even more complex functionality. These defined using Descriptors. + There are properties which provide even more complex functionality. These defined using Descriptors. + - - The class is written to provide the following functionality. + The class is written to provide the following functionality. - 1) Properties are initiated from Instrument_Properties.xml file as defaults. - 2) Attempt to access property, not present in this file throws. - 3) Attempt to create property not present in this file throws. - 4) A standard behavior is defined for the most of the properties (get/set appropriate value) when there is number of - overloaded properties, which support more complex behavior using specially written Descriptors + 1) Properties are initiated from Instrument_Properties.xml file as defaults. + 2) Attempt to access property, not present in this file throws. + 3) Attempt to create property not present in this file throws. + 4) A standard behavior is defined for the most of the properties (get/set appropriate value) when there is number of + overloaded properties, which support more complex behavior using specially written Descriptors 5) Changes to the properties are recorded and the list of changed properties is available on request ######## @@ -41,9 +41,9 @@ class PropertyManager(NonIDF_Properties): __getattr__ and __setattr__ are overloaded to understand such calls. The property_name itself is naturally not placed into system dictionary. - 3) Descriptors with the name present in IDF do not store their values and names in __dict__ + 3) Descriptors with the name present in IDF do not store their values and names in __dict__ (the name is removed during IDF parsing) but keep their information in the descriptor. - This is not considered a problem as only one instance of property manager is expected. If this need to be changed, + This is not considered a problem as only one instance of property manager is expected. If this need to be changed, adding property values to the __dict__ as values of _property_name keys should be safe. 4) __getattr__ (and __setattr__ ) method are overloaded to provide call to a descriptor before the search in the system dictionary. @@ -51,10 +51,10 @@ class PropertyManager(NonIDF_Properties): e.g. in case when an descriptor is called through one of its synonym name. A problem will occur if a key with name equal to descriptor name is also present in __dict__. This name would override descriptor. - This is why any new descriptor should never place a key with its name in __dict__. Current design automatically remove IDF name + This is why any new descriptor should never place a key with its name in __dict__. Current design automatically remove IDF name from __dict__ if a descriptor with such name exist, so further development should support this behavior. - 5) In many places (descriptors, RunDescriptor itself), PropertyManager assumed to be a singleton, so most Descriptors are defined on a + 5) In many places (descriptors, RunDescriptor itself), PropertyManager assumed to be a singleton, so most Descriptors are defined on a class level. If this changes, careful refactoring will be necessary @@ -76,10 +76,10 @@ def __init__(self,Instrument,instr_run=None): 'file_properties':[],'abs_norm_file_properties':[]} # place these properties to __dict__ with proper decoration self._init_private_properties(private_properties) - # + # class_dec = '_'+type(self).__name__+'__' # --------------------------------------------------------------------------------------------- - # overloaded descriptors. These properties have their personal descriptors, different from default. + # overloaded descriptors. These properties have their personal descriptors, different from default. all_methods = dir(self) object.__setattr__(self,class_dec+'descriptors',prop_helpers.extract_non_system_names(all_methods)) # --------------------------------------------------------------------------------------------- @@ -99,11 +99,11 @@ def __init__(self,Instrument,instr_run=None): object.__setattr__(self,class_dec+'abs_norm_file_properties',['monovan_mapfile']) # properties with allowed values - + def _convert_params_to_properties(self,param_list,detine_subst_dict=True,descr_list=[]): """ method processes parameters obtained from IDF and modifies the IDF properties - to the form allowing them be assigned as python class properties. - """ + to the form allowing them be assigned as python class properties. + """ subst_name = '_'+type(self).__name__+'__subst_dict' # build and use substitution dictionary @@ -117,12 +117,12 @@ def _convert_params_to_properties(self,param_list,detine_subst_dict=True,descr_l #end - # build properties list and descriptors list with their initial values - param_dict,descr_dict = prop_helpers.build_properties_dict(param_list,self.__dict__[subst_name],descr_list) + # build properties list and descriptors list with their initial values + param_dict,descr_dict = prop_helpers.build_properties_dict(param_list,self.__dict__[subst_name],descr_list) return (param_dict,descr_dict) def _init_private_properties(self,prop_dict): - """ helper method used to define all private dictionaries at once + """ helper method used to define all private dictionaries at once during __init__ procedure """ @@ -133,15 +133,15 @@ def _init_private_properties(self,prop_dict): new_key = class_decor+key object.__setattr__(self,new_key,val) - + def __setattr__(self,name0,val): """ Overloaded generic set method, disallowing non-existing properties being set. - - It also provides common checks for generic properties groups + + It also provides common checks for generic properties groups and records all properties changed - """ + """ - # Let's set private properties directly. Normally, nobody should try + # Let's set private properties directly. Normally, nobody should try # to set them through PropertyManager interface #if name0[:2]=='_P': # self.__dict__[name0] = val @@ -155,47 +155,47 @@ def __setattr__(self,name0,val): # replace common substitutions for string value if type(val) is str : - val1 = val.lower() - if (val1 == 'none' or len(val1) == 0): - val = None - if val1 == 'default': - val = self.getDefaultParameterValue(name0) + val1 = val.lower() + if (val1 == 'none' or len(val1) == 0): + val = None + if val1 == 'default': + val = self.getDefaultParameterValue(name0) # boolean property? - if val1 in ['true','yes']: - val = True - if val1 in ['false','no']: - val = False + if val1 in ['true','yes']: + val = True + if val1 in ['false','no']: + val = False if type(val) is list and len(val) == 0: val = None - + # set property value: if name in self.__descriptors: - super(PropertyManager,self).__setattr__(name,val) + super(PropertyManager,self).__setattr__(name,val) else: - other_prop=prop_helpers.gen_setter(self.__dict__,name,val) + other_prop=prop_helpers.gen_setter(self.__dict__,name,val) # record the fact that the property have changed self.__changed_properties.add(name) # ---------------------------- def __getattr__(self,name): - """ Overloaded get method, disallowing non-existing properties being get but allowing - a property been called with different names specified in substitution dictionary. """ + """ Overloaded get method, disallowing non-existing properties being get but allowing + a property been called with different names specified in substitution dictionary. """ - if name in self.__subst_dict: - name = self.__subst_dict[name] - return getattr(self,name) - #end + if name in self.__subst_dict: + name = self.__subst_dict[name] + return getattr(self,name) + #end - if name in self.__descriptors: - # This can only happen only if descriptor is called through synonims dictionary + if name in self.__descriptors: + # This can only happen only if descriptor is called through synonims dictionary # This to work, all descriptors should define getter to return self on Null instance. - descr=getattr(PropertyManager,name) - return descr.__get__(self,name) - else: - return prop_helpers.gen_getter(self.__dict__,name) + descr=getattr(PropertyManager,name) + return descr.__get__(self,name) + else: + return prop_helpers.gen_getter(self.__dict__,name) ##end #---------------------------------------------------------------------------------- # Overloaded setters/getters @@ -212,7 +212,7 @@ def __getattr__(self,name): monovan_integr_range = MonovanIntegrationRange() # spectra_to_monitors_list = SpectraToMonitorsList() - # + # save_format = SaveFormat() # hardmaskOnly = HardMaskOnly() @@ -226,7 +226,7 @@ def __getattr__(self,name): # Properties with allowed value normalise_method= PropertyFromRange([None,'monitor-1','monitor-2','current'],'current') deltaE_mode = PropertyFromRange(['direct'],'direct') # other modes should not be considered here - # + # multirep_tof_specta_list=MultirepTOFSpectraList() # mono_correction_factor = MonoCorrectionFactor(NonIDF_Properties.incident_energy) @@ -237,7 +237,7 @@ def getChangedProperties(self): decor_prop = '_'+type(self).__name__+'__changed_properties' return self.__dict__[decor_prop] def setChangedProperties(self,value=set([])): - """ Method to clear changed properties list""" + """ Method to clear changed properties list""" if isinstance(value,set): decor_prop = '_'+type(self).__name__+'__changed_properties' self.__dict__[decor_prop] =value @@ -250,17 +250,17 @@ def relocate_dets(self) : return True else: return False - + def set_input_parameters_ignore_nan(self,**kwargs): - """ Like similar method set_input_parameters this one is used to - set changed parameters from dictionary of parameters. + """ Like similar method set_input_parameters this one is used to + set changed parameters from dictionary of parameters. - Unlike set_input_parameters, this method does not set parameter, - with value equal to None. As such, this method is used as interface to + Unlike set_input_parameters, this method does not set parameter, + with value equal to None. As such, this method is used as interface to set data from a function with a list of given parameters (*args vrt **kwargs), with some parameters missing. - """ - # if sum is in parameters one needs to set it first + """ + # if sum is in parameters one needs to set it first if 'sum_runs' in kwargs and not (kwargs['sum_runs'] is None): self.sum_runs = kwargs['sum_runs'] del kwargs['sum_runs'] @@ -280,7 +280,7 @@ def set_input_parameters(self,**kwargs): """ # if sum is in parameters one needs to set it first to interpret - # + # if 'sum_runs' in kwargs : self.sum_runs = kwargs['sum_runs'] del kwargs['sum_runs'] @@ -295,7 +295,7 @@ def set_input_parameters(self,**kwargs): return self.getChangedProperties() def get_used_monitors_list(self): - """ Method returns list of monitors ID used during reduction """ + """ Method returns list of monitors ID used during reduction """ used_mon=set() for case in common.switch(self.normalise_method): @@ -306,7 +306,7 @@ def get_used_monitors_list(self): used_mon.add(self.mon2_norm_spec) break if case(): # default, could also just omit condition or 'if True' - pass + pass used_mon.add(self.ei_mon1_spec) used_mon.add(self.ei_mon2_spec) @@ -316,9 +316,9 @@ def get_used_monitors_list(self): def get_diagnostics_parameters(self): """ Return the dictionary of the properties used in diagnostics with their values defined in IDF - + if some values are not in IDF, default values are used instead - """ + """ diag_param_list ={'tiny':1e-10, 'huge':1e10, 'samp_zero':False, 'samp_lo':0.0, 'samp_hi':2,'samp_sig':3,\ 'van_out_lo':0.01, 'van_out_hi':100., 'van_lo':0.1, 'van_hi':1.5, 'van_sig':0.0, 'variation':1.1,\ @@ -330,26 +330,26 @@ def get_diagnostics_parameters(self): for key,val in diag_param_list.iteritems(): try: result[key] = getattr(self,key) - except KeyError: + except KeyError: self.log('--- Diagnostics property {0} is not found in instrument properties. Default value: {1} is used instead \n'.format(key,value),'warning') - + return result def update_defaults_from_instrument(self,pInstrument,ignore_changes=False): """ Method used to update default parameters from the same instrument (with different parameters). - Used if initial parameters correspond to instrument with one validity dates and - current instrument has different validity dates and different default values for + Used if initial parameters correspond to instrument with one validity dates and + current instrument has different validity dates and different default values for these dates. - List of synonims is not modified and new properties are not added assuming that + List of synonims is not modified and new properties are not added assuming that recent dictionary and properties are most comprehensive one ignore_changes==True when changes, caused by setting properties from instrument are not recorded - ignore_changes==False -- getChangedProperties properties after applied this method would return set + ignore_changes==False -- getChangedProperties properties after applied this method would return set of all properties changed when applying this method - """ + """ if self.instr_name != pInstrument.getName(): self.log("*** WARNING: Setting reduction properties of the instrument {0} from the instrument {1}.\n" "*** This only works if both instruments have the same reduction properties!"\ @@ -362,48 +362,48 @@ def update_defaults_from_instrument(self,pInstrument,ignore_changes=False): for prop_name in old_changes_list: old_changes[prop_name] = getattr(self,prop_name) - + param_list = prop_helpers.get_default_idf_param_list(pInstrument) # remove old changes which are not related to IDF (not to reapply it again) for prop_name in old_changes: if not (prop_name in param_list): - try: - dependencies = getattr(PropertyManager,prop_name).dependencies() - except: - dependencies = [] - modified = False - for name in dependencies: - if name in param_list: - modified = True - break - if not modified: - del old_changes[prop_name] + try: + dependencies = getattr(PropertyManager,prop_name).dependencies() + except: + dependencies = [] + modified = False + for name in dependencies: + if name in param_list: + modified = True + break + if not modified: + del old_changes[prop_name] #end param_list,descr_dict = self._convert_params_to_properties(param_list,False,self.__descriptors) # clear record about previous changes self.setChangedProperties(set()) - #sort parameters to have complex properties (with underscore _) first + #sort parameters to have complex properties (with underscore _) first sorted_param = OrderedDict(sorted(param_list.items(),key=lambda x : ord((x[0][0]).lower()))) - # Walk through descriptors list and set their values + # Walk through descriptors list and set their values # Assignment to descriptors should accept the form, descriptor is written in IDF changed_descriptors = set() for key,val in descr_dict.iteritems(): if not (key in old_changes_list): - try: # this is reliability check, and except ideally should never be hit. May occur if old IDF contains + try: # this is reliability check, and except ideally should never be hit. May occur if old IDF contains # properties, not present in recent IDF. - cur_val = getattr(self,key) - setattr(self,key,val) - new_val = getattr(self,key) + cur_val = getattr(self,key) + setattr(self,key,val) + new_val = getattr(self,key) except: - self.log("property {0} have not been found in existing IDF. Ignoring this property"\ + self.log("property {0} have not been found in existing IDF. Ignoring this property"\ .format(key),'warning') - continue + continue if isinstance(new_val,api.Workspace) and isinstance(cur_val,api.Workspace): - # do simplified workspace comparison which is appropriate here - if new_val.name() == cur_val.name() and \ + # do simplified workspace comparison which is appropriate here + if new_val.name() == cur_val.name() and \ new_val.getNumberHistograms() == cur_val.getNumberHistograms() and \ new_val.getNEvents() == cur_val.getNEvents() and \ new_val.getAxis(0).getUnit().unitID() == cur_val.getAxis(0).getUnit().unitID(): @@ -411,16 +411,16 @@ def update_defaults_from_instrument(self,pInstrument,ignore_changes=False): # #end if new_val != cur_val: - changed_descriptors.add(key) + changed_descriptors.add(key) # dependencies removed either properties are equal or not try: - dependencies = getattr(PropertyManager,key).dependencies() + dependencies = getattr(PropertyManager,key).dependencies() except: - dependencies = [] + dependencies = [] for dep_name in dependencies: if dep_name in sorted_param: - del sorted_param[dep_name] + del sorted_param[dep_name] else: # remove property from old changes list not to reapply it again? pass #end loop @@ -439,21 +439,21 @@ def update_defaults_from_instrument(self,pInstrument,ignore_changes=False): public_name = key prop_new_val = val - try: # this is reliability check, and except ideally should never be hit. May occur if old IDF contains + try: # this is reliability check, and except ideally should never be hit. May occur if old IDF contains # properties, not present in recent IDF. - cur_val = getattr(self,public_name) + cur_val = getattr(self,public_name) except: self.log("property {0} have not been found in existing IDF. Ignoring this property"\ .format(public_name),'warning') continue if prop_new_val !=cur_val : - setattr(self,public_name,prop_new_val) + setattr(self,public_name,prop_new_val) # Dependencies removed either properties are equal or not try: - dependencies = val.dependencies() + dependencies = val.dependencies() except: - dependencies =[] + dependencies =[] for dep_name in dependencies: # delete dependent properties not to deal with them again del sorted_param[dep_name] @@ -462,11 +462,11 @@ def update_defaults_from_instrument(self,pInstrument,ignore_changes=False): new_changes_list = self.getChangedProperties() self.setChangedProperties(set()) - # set back all changes stored earlier and may be overwritten by new IDF + # set back all changes stored earlier and may be overwritten by new IDF # (this is just to be sure -- should not change anything as we do not set properties changed) for key,val in old_changes.iteritems(): setattr(self,key,val) - + # Clear changed properties list (is this wise?, may be we want to know that some defaults changed?) if ignore_changes: self.setChangedProperties(old_changes_list) @@ -505,8 +505,8 @@ def check_files_list(files_list): if not (file is None) and isinstance(file,str): file_path = self._check_file_exist(file) if len(file_path)==0: - self.log(" Can not find file ""{0}"" for property: {1} ".format(file,prop),'error') - file_missing=True + self.log(" Can not find file ""{0}"" for property: {1} ".format(file,prop),'error') + file_missing=True return file_missing @@ -516,7 +516,7 @@ def check_files_list(files_list): abs_file_missing = check_files_list(self.__abs_norm_file_properties) if base_file_missing or abs_file_missing: - raise RuntimeError(" Files needed for the run are missing ") + raise RuntimeError(" Files needed for the run are missing ") # def _check_monovan_par_changed(self): """ method verifies, if properties necessary for monovanadium reduction have indeed been changed from defaults """ @@ -532,62 +532,62 @@ def _check_monovan_par_changed(self): # def log_changed_values(self,log_level='notice',display_header=True,already_changed=set()): - """ inform user about changed parameters and about the parameters that should be changed but have not - + """ inform user about changed parameters and about the parameters that should be changed but have not + This method is abstract method of NonIDF_Properties but is fully defined in PropertyManager - display_header==True prints nice additional information about run. If False, only + display_header==True prints nice additional information about run. If False, only list of changed properties displayed. """ - if display_header: + if display_header: # we may want to run absolute units normalization and this function has been called with monovan run or helper procedure - if self.monovan_run != None : + if self.monovan_run != None : # check if mono-vanadium is provided as multiple files list or just put in brackets occasionally - self.log("****************************************************************",'notice') - self.log('*** Output will be in absolute units of mb/str/mev/fu','notice') - non_changed = self._check_monovan_par_changed() - if len(non_changed) > 0: - for prop in non_changed: - value = getattr(self,prop) - message = "\n***WARNING!: Abs units norm. parameter : {0} not changed from default val: {1}"\ + self.log("****************************************************************",'notice') + self.log('*** Output will be in absolute units of mb/str/mev/fu','notice') + non_changed = self._check_monovan_par_changed() + if len(non_changed) > 0: + for prop in non_changed: + value = getattr(self,prop) + message = "\n***WARNING!: Abs units norm. parameter : {0} not changed from default val: {1}"\ "\n This may need to change for correct absolute units reduction\n" - self.log(message.format(prop,value),'warning') + self.log(message.format(prop,value),'warning') # now let's report on normal run. - if PropertyManager.incident_energy.multirep_mode(): - ei = self.incident_energy - mess = "*** Provisional Incident energies: {0:>8.3f}".format(ei[0]) - for en in ei[1:]: - mess += "; {0:>8.3f}".format(en) - mess+=" mEv" - self.log(mess,log_level) - else: - self.log("*** Provisional Incident energy: {0:>12.3f} mEv".format(self.incident_energy),log_level) + if PropertyManager.incident_energy.multirep_mode(): + ei = self.incident_energy + mess = "*** Provisional Incident energies: {0:>8.3f}".format(ei[0]) + for en in ei[1:]: + mess += "; {0:>8.3f}".format(en) + mess+=" mEv" + self.log(mess,log_level) + else: + self.log("*** Provisional Incident energy: {0:>12.3f} mEv".format(self.incident_energy),log_level) #end display_header - self.log("****************************************************************",log_level) - changed_Keys= self.getChangedProperties() - for key in changed_Keys: - if key in already_changed: - continue - val = getattr(self,key) - self.log(" Value of : {0:<25} is set to : {1:<20} ".format(key,val),log_level) - - if not display_header: - return - - save_dir = config.getString('defaultsave.directory') - self.log("****************************************************************",log_level) - if self.monovan_run != None and not('van_mass' in changed_Keys): # This output is - self.log("*** Monochromatic vanadium mass used : {0} ".format(self.van_mass),log_level) # Adroja request from may 2014 + self.log("****************************************************************",log_level) + changed_Keys= self.getChangedProperties() + for key in changed_Keys: + if key in already_changed: + continue + val = getattr(self,key) + self.log(" Value of : {0:<25} is set to : {1:<20} ".format(key,val),log_level) + + if not display_header: + return + + save_dir = config.getString('defaultsave.directory') + self.log("****************************************************************",log_level) + if self.monovan_run != None and not('van_mass' in changed_Keys): # This output is + self.log("*** Monochromatic vanadium mass used : {0} ".format(self.van_mass),log_level) # Adroja request from may 2014 # - self.log("*** By default results are saved into: {0}".format(save_dir),log_level) - self.log("*** Output will be normalized to {0}".format(self.normalise_method),log_level) - if self.map_file == None: + self.log("*** By default results are saved into: {0}".format(save_dir),log_level) + self.log("*** Output will be normalized to {0}".format(self.normalise_method),log_level) + if self.map_file == None: self.log('*** one2one map selected',log_level) - self.log("****************************************************************",log_level) + self.log("****************************************************************",log_level) #def help(self,keyword=None) : diff --git a/Code/Mantid/scripts/Inelastic/Direct/ReductionHelpers.py b/Code/Mantid/scripts/Inelastic/Direct/ReductionHelpers.py index 3aaa2f271fa9..73c3b8038457 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/ReductionHelpers.py +++ b/Code/Mantid/scripts/Inelastic/Direct/ReductionHelpers.py @@ -2,13 +2,13 @@ import os """ -Set of functions to assist with processing instrument parameters relevant to reduction. +Set of functions to assist with processing instrument parameters relevant to reduction. """ class ComplexProperty(object): - """ Class describes property which depends on other properties and stores/receives values in other properties """ + """ Class describes property which depends on other properties and stores/receives values in other properties """ def __init__(self,other_prop_list): - self._other_prop = other_prop_list; - + self._other_prop = other_prop_list + def __get__(self,spec_dict,owner=None): """ return complex properties list """ if spec_dict is None: @@ -19,24 +19,24 @@ def __get__(self,spec_dict,owner=None): spec_dict = spec_dict.__dict__ rez = list() for key in self._other_prop: - rez.append(spec_dict[key]); - return rez; + rez.append(spec_dict[key]) + return rez def __set__(self,instance,value): try: lv = len(value) except: - raise KeyError("Complex property values can be assigned only by list of other values"); + raise KeyError("Complex property values can be assigned only by list of other values") if lv != len(self._other_prop): - raise KeyError("Complex property values can be set equal to the same length values list"); + raise KeyError("Complex property values can be set equal to the same length values list") if isinstance(instance,dict): spec_dict = instance else: spec_dict = instance.__dict__ - + #changed_prop=[]; for key,val in zip(self._other_prop,value): - spec_dict[key] =val; + spec_dict[key] =val #changed_prop.append(key); #return changed_prop; def dependencies(self): @@ -52,37 +52,37 @@ def len(self): def get_default_parameter(instrument, name): - """ Function gets the value of a default instrument parameter and - assign proper(the one defined in IPF ) type to this parameter - @param instrument -- - """ - - if instrument is None: - raise ValueError("Cannot initiate default parameter, instrument has not been properly defined.") - - type_name = instrument.getParameterType(name) - if type_name == "double": - val = instrument.getNumberParameter(name) - elif type_name == "bool": - val = instrument.getBoolParameter(name) - elif type_name == "string": - val = instrument.getStringParameter(name) - if val[0] == "None" : - return None - elif type_name == "int" : - val = instrument.getIntParameter(name) - else : - raise KeyError(" Instrument: {0} does not have parameter with name: {1}".format(instrument.getName(),name)) - - return val[0] + """ Function gets the value of a default instrument parameter and + assign proper(the one defined in IPF ) type to this parameter + @param instrument -- + """ + + if instrument is None: + raise ValueError("Cannot initiate default parameter, instrument has not been properly defined.") + + type_name = instrument.getParameterType(name) + if type_name == "double": + val = instrument.getNumberParameter(name) + elif type_name == "bool": + val = instrument.getBoolParameter(name) + elif type_name == "string": + val = instrument.getStringParameter(name) + if val[0] == "None" : + return None + elif type_name == "int" : + val = instrument.getIntParameter(name) + else : + raise KeyError(" Instrument: {0} does not have parameter with name: {1}".format(instrument.getName(),name)) + + return val[0] def get_default_idf_param_list(pInstrument,synonims_list=None): """ Obtain default reduction parameters list from the instrument """ - params = pInstrument.getParameterNames(); - par_list = {}; + params = pInstrument.getParameterNames() + par_list = {} for name in params: - par_list[name] = get_default_parameter(pInstrument,name); + par_list[name] = get_default_parameter(pInstrument,name) return par_list @@ -91,25 +91,25 @@ def get_default_idf_param_list(pInstrument,synonims_list=None): def build_properties_dict(param_map,synonims,descr_list=[]) : """ function builds the properties list from the properties strings obtained from Insturment_Parameters.xml file - + The properties, which have simple values are added to dictionary in the form: properties_dict[prop_name]=(False,value); - The properties, expressed trough the values of other properties - e.g. strings in a form key1 = key2:key3 + The properties, expressed trough the values of other properties + e.g. strings in a form key1 = key2:key3 are added to the dictionary in the form: in the form properties_dict[key1]=(True,['key2','key3']) - """ + """ # dictionary used for substituting composite keys. prelim_dict = dict() for name in param_map: - if name in synonims: - final_name = str(synonims[name]) - else: - final_name = str(name) - prelim_dict[final_name]=None + if name in synonims: + final_name = str(synonims[name]) + else: + final_name = str(name) + prelim_dict[final_name]=None param_keys = prelim_dict.keys() properties_dict = dict() @@ -124,46 +124,46 @@ def build_properties_dict(param_map,synonims,descr_list=[]) : if final_name in descr_list: is_descriptor = True - if isinstance(val,str): - val = val.strip() - keys_candidates = val.split(":") - n_keys = len(keys_candidates) + if isinstance(val,str): + val = val.strip() + keys_candidates = val.split(":") + n_keys = len(keys_candidates) # - if n_keys>1 : # this is the property we want to modify - result=list() - for key in keys_candidates : - if key in synonims: - rkey = str(synonims[key]) - else: - rkey = str(key) - if rkey in param_keys: - result.append(rkey) - else: - raise KeyError('Substitution key : {0} is not in the list of allowed keys'.format(rkey)) - if is_descriptor: - descr_dict[final_name] = result - else: - properties_dict['_'+final_name]=ComplexProperty(result) - else: - if is_descriptor: - descr_dict[final_name] = keys_candidates[0] - else: - properties_dict[final_name] =keys_candidates[0] + if n_keys>1 : # this is the property we want to modify + result=list() + for key in keys_candidates : + if key in synonims: + rkey = str(synonims[key]) + else: + rkey = str(key) + if rkey in param_keys: + result.append(rkey) + else: + raise KeyError('Substitution key : {0} is not in the list of allowed keys'.format(rkey)) + if is_descriptor: + descr_dict[final_name] = result + else: + properties_dict['_'+final_name]=ComplexProperty(result) + else: + if is_descriptor: + descr_dict[final_name] = keys_candidates[0] + else: + properties_dict[final_name] =keys_candidates[0] else: - if is_descriptor: + if is_descriptor: descr_dict[final_name] = val - else: + else: properties_dict[final_name]=val return (properties_dict,descr_dict) def extract_non_system_names(names_list,prefix='_'): - """ The function processes the input list and returns - the list with names which do not have the system framing (leading __) + """ The function processes the input list and returns + the list with names which do not have the system framing (leading __) """ - result = list(); - ns = len(prefix); + result = list() + ns = len(prefix) for name in names_list: pend = min(ns,len(name)) if name[:pend] != prefix: @@ -180,11 +180,11 @@ def build_subst_dictionary(synonims_list=None) : norm-mon1-spec=my_detector in the synonyms field of the IDF parameters file. """ if not synonims_list : # nothing to do - return dict(); + return dict() if type(synonims_list) == dict : # all done - return synonims_list + return synonims_list if type(synonims_list) != str : - raise AttributeError("The synonyms field of Reducer object has to be special format string or the dictionary") + raise AttributeError("The synonyms field of Reducer object has to be special format string or the dictionary") # we are in the right place and going to transform string into dictionary subst_lines = synonims_list.split(";") @@ -193,20 +193,20 @@ def build_subst_dictionary(synonims_list=None) : lin=lin.strip() keys = lin.split("=") if len(keys) < 2 : - raise AttributeError("The pairs in the synonyms fields have to have form key1=key2=key3 with at least two values present") + raise AttributeError("The pairs in the synonyms fields have to have form key1=key2=key3 with at least two values present") if len(keys[0]) == 0: - raise AttributeError("The pairs in the synonyms fields have to have form key1=key2=key3 with at least two values present, but the first key is empty") + raise AttributeError("The pairs in the synonyms fields have to have form key1=key2=key3 with at least two values present, but the first key is empty") for i in xrange(1,len(keys)) : - if len(keys[i]) == 0 : - raise AttributeError("The pairs in the synonyms fields have to have form key1=key2=key3 with at least two values present, but the key"+str(i)+" is empty") - kkk = keys[i].strip(); - rez[kkk]=keys[0].strip() + if len(keys[i]) == 0 : + raise AttributeError("The pairs in the synonyms fields have to have form key1=key2=key3 with at least two values present, but the key"+str(i)+" is empty") + kkk = keys[i].strip() + rez[kkk]=keys[0].strip() return rez def gen_getter(keyval_dict,key): - """ function returns value from dictionary with substitution - + """ function returns value from dictionary with substitution + e.g. if keyval_dict[A] = 10, keyval_dict[B] = 20 and key_val[C] = [A,B] gen_getter(keyval_dict,A) == 10; gen_getter(keyval_dict,B) == 20; and gen_getter(keyval_dict,C) == [10,20]; @@ -214,11 +214,11 @@ def gen_getter(keyval_dict,key): if not(key in keyval_dict): name = '_'+key if not(name in keyval_dict): - raise KeyError('Property with name: {0} is not among the class properties '.format(key)); + raise KeyError('Property with name: {0} is not among the class properties '.format(key)) else: name = key - a_val= keyval_dict[name]; + a_val= keyval_dict[name] if isinstance(a_val,ComplexProperty): return a_val.__get__(keyval_dict) else: @@ -229,8 +229,8 @@ def gen_getter(keyval_dict,key): def gen_setter(keyval_dict,key,val): - """ function sets value to dictionary with substitution - + """ function sets value to dictionary with substitution + e.g. if keyval_dict[A] = 10, keyval_dict[B] = 20 and key_val[C] = [A,B] gen_setter(keyval_dict,A,20) causes keyval_dict[A] == 20 @@ -245,16 +245,16 @@ def gen_setter(keyval_dict,key,val): else: name = key - test_val = keyval_dict[name]; + test_val = keyval_dict[name] if isinstance(test_val,ComplexProperty): - if not isinstance(val,list): - raise KeyError(' You can not assign non-list value to complex property {0}'.format(key)) - pass + if not isinstance(val,list): + raise KeyError(' You can not assign non-list value to complex property {0}'.format(key)) + pass # Assigning values for composite function to the function components - test_val.__set__(keyval_dict,val) - return None + test_val.__set__(keyval_dict,val) + return None else: - keyval_dict[key] = val; + keyval_dict[key] = val return None @@ -263,13 +263,13 @@ def check_instrument_name(old_name,new_name): if new_name is None: - if not(old_name is None): + if not(old_name is None): return (None,None,str(config.getFacility())) - else: + else: raise KeyError("No instrument name is defined") if old_name == new_name: - return; + return # Instrument name might be a prefix, query Mantid for the full name short_name='' @@ -283,18 +283,18 @@ def check_instrument_name(old_name,new_name): facilities = config.getFacilities() old_facility = str(config.getFacility()) for facility in facilities: - config.setString('default.facility',facility.name()) - try : - instrument = facility.instrument(new_name) - short_name = instrument.shortName() - full_name = instrument.name() - if len(short_name)>0 : - break - except: - pass + config.setString('default.facility',facility.name()) + try : + instrument = facility.instrument(new_name) + short_name = instrument.shortName() + full_name = instrument.name() + if len(short_name)>0 : + break + except: + pass if len(short_name)==0 : - config.setString('default.facility',old_facility) - raise KeyError(" Can not find/set-up the instrument: "+new_name+' in any supported facility') + config.setString('default.facility',old_facility) + raise KeyError(" Can not find/set-up the instrument: "+new_name+' in any supported facility') new_name = short_name facility = str(config.getFacility()) @@ -306,23 +306,23 @@ def parse_single_name(filename): """ Process single run name into """ filepath,fname = os.path.split(filename) if ':' in fname: - fl,fr=fname.split(':') - path1,ind1,ext1=parse_single_name(fl) - path2,ind2,ext2=parse_single_name(fr) - if ind1>ind2: - raise ValueError('Invalid file number defined using colon : left run number {0} has to be large then right {1}'.format(ind1,ind2)) - number = range(ind1[0],ind2[0]+1) - if len(filepath)>0: - filepath=[filepath]*len(number) - else: - filepath=path1*len(number) - if len(ext2[0])>0: - fext = ext2*len(number) - else: - fext = ext1*len(number) - - return (filepath,number,fext) - + fl,fr=fname.split(':') + path1,ind1,ext1=parse_single_name(fl) + path2,ind2,ext2=parse_single_name(fr) + if ind1>ind2: + raise ValueError('Invalid file number defined using colon : left run number {0} has to be large then right {1}'.format(ind1,ind2)) + number = range(ind1[0],ind2[0]+1) + if len(filepath)>0: + filepath=[filepath]*len(number) + else: + filepath=path1*len(number) + if len(ext2[0])>0: + fext = ext2*len(number) + else: + fext = ext1*len(number) + + return (filepath,number,fext) + fname,fext = os.path.splitext(fname) fnumber = filter(lambda x: x.isdigit(), fname) @@ -331,7 +331,7 @@ def parse_single_name(filename): else: number = int(fnumber) return ([filepath],[number],[fext]) - + def parse_run_file_name(run_string): """ Parses run file name to obtain run number, path if possible, and file extension if any present in the string""" @@ -363,5 +363,5 @@ def parse_run_file_name(run_string): # extensions should be either all the same or all defined return (filepath,filenum,fext) - + diff --git a/Code/Mantid/scripts/Inelastic/Direct/ReductionWrapper.py b/Code/Mantid/scripts/Inelastic/Direct/ReductionWrapper.py index f7e35393991e..fa65b83f4067 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/ReductionWrapper.py +++ b/Code/Mantid/scripts/Inelastic/Direct/ReductionWrapper.py @@ -11,11 +11,11 @@ class ReductionWrapper(object): - """ Abstract class provides interface to direct inelastic reduction - allowing it to be run from Mantid, web services, or system tests - using the same interface and the same run file placed in different + """ Abstract class provides interface to direct inelastic reduction + allowing it to be run from Mantid, web services, or system tests + using the same interface and the same run file placed in different locations. - """ + """ class var_holder(object): """ A simple wrapper class to keep web variables""" def __init__(self): @@ -24,46 +24,46 @@ def __init__(self): pass def __init__(self,instrumentName,web_var=None): - """ sets properties defaults for the instrument with Name + """ sets properties defaults for the instrument with Name and define if wrapper runs from web services or not """ # internal variable, indicating if we should try to wait for input files to appear - self._wait_for_file=False + self._wait_for_file=False - # The variables which are set up from web interface or to be exported to + # The variables which are set up from web interface or to be exported to # web interface - if web_var: - self._run_from_web = True - self._wvs = web_var - else: - self._run_from_web = False - self._wvs = ReductionWrapper.var_holder() + if web_var: + self._run_from_web = True + self._wvs = web_var + else: + self._run_from_web = False + self._wvs = ReductionWrapper.var_holder() # Initialize reduced for given instrument - self.reducer = DirectEnergyConversion(instrumentName) + self.reducer = DirectEnergyConversion(instrumentName) - self._validation_fname=None + self._validation_fname=None # def get_validation_file_name(self,ReferenceFile=None): - """ function provides name of the file with mantid - workspace reduced earlier and which should be validated + """ function provides name of the file with mantid + workspace reduced earlier and which should be validated against results of current reduction Should be overloaded to return real file name for particular reduction - """ - if ReferenceFile: - self._validation_fname = ReferenceFile - return self._validation_fname + """ + if ReferenceFile: + self._validation_fname = ReferenceFile + return self._validation_fname @property def wait_for_file(self): """ If this variable set to positive value, this value - is interpreted as time to wait until check for specified run file - if this file have not been find immediately. + is interpreted as time to wait until check for specified run file + if this file have not been find immediately. if this variable is 0 or false and the the file have not been found, reduction will fail - """ + """ return self._wait_for_file @wait_for_file.setter @@ -74,72 +74,72 @@ def wait_for_file(self,value): self._wait_for_file = False # def save_web_variables(self,FileName=None): - """ Method to write simple and advanced properties and help + """ Method to write simple and advanced properties and help information into dictionary, to use by web reduction interface - If no file is provided, reduce_var.py file will be written - to + If no file is provided, reduce_var.py file will be written + to """ if not FileName: FileName = 'reduce_vars.py' - + f=open(FileName,'w') f.write("standard_vars = {\n") str_wrapper = ' ' for key,val in self._wvs.standard_vars.iteritems(): - if isinstance(val,str): - row = "{0}\'{1}\':\'{2}\'".format(str_wrapper,key,val) - else: - row = "{0}\'{1}\':{2}".format(str_wrapper,key,val) - f.write(row) - str_wrapper=',\n ' + if isinstance(val,str): + row = "{0}\'{1}\':\'{2}\'".format(str_wrapper,key,val) + else: + row = "{0}\'{1}\':{2}".format(str_wrapper,key,val) + f.write(row) + str_wrapper=',\n ' f.write("\n}\nadvanced_vars={\n") str_wrapper=' ' for key,val in self._wvs.advanced_vars.iteritems(): - if isinstance(val,str): - row = "{0}\'{1}\':\'{2}\'".format(str_wrapper,key,val) - else: - row = "{0}\'{1}\':{2}".format(str_wrapper,key,val) - f.write(row) - str_wrapper=',\n ' + if isinstance(val,str): + row = "{0}\'{1}\':\'{2}\'".format(str_wrapper,key,val) + else: + row = "{0}\'{1}\':{2}".format(str_wrapper,key,val) + f.write(row) + str_wrapper=',\n ' f.write("\n}\n") f.close() # -# +# def validate_result(self,build_validation=False,Error=1.e-3,ToleranceRelErr=True): - """ Overload this using build_or_validate_result to have possibility to run or validate result """ + """ Overload this using build_or_validate_result to have possibility to run or validate result """ return True def build_or_validate_result(self,sample_run,validationFile,build_validation=False,Error=1.e-3,ToleranceRelErr=True): """ Method validates results of the reduction against reference file provided - by get_validation_file_name() method - + by get_validation_file_name() method + At the moment, get_validation_file_name method should return the name of a file, - where workspace sample reduced workspace with default properties - is stored. - CheckWorkspaceMatch method is applied to verify if current reduced workspace is - equivalent to the workspace, stored in the reference file. + where workspace sample reduced workspace with default properties + is stored. + CheckWorkspaceMatch method is applied to verify if current reduced workspace is + equivalent to the workspace, stored in the reference file. """ if not build_validation: - if validationFile: - if isinstance(validationFile,api.Workspace): - sample = validationFile - validationFile = sample.name() - else: - sample = Load(validationFile) - else: - build_validation=True + if validationFile: + if isinstance(validationFile,api.Workspace): + sample = validationFile + validationFile = sample.name() + else: + sample = Load(validationFile) + else: + build_validation=True # just in case, to be sure current_web_state = self._run_from_web current_wait_state= self.wait_for_file - # disable wait for input and + # disable wait for input and self._run_from_web = False self.wait_for_file = False # @@ -153,9 +153,9 @@ def build_or_validate_result(self,sample_run,validationFile,build_validation=Fal if build_validation: if validationFile: - result_name = os.path.splitext(validationFile)[0] + result_name = os.path.splitext(validationFile)[0] else: - result_name = self.reducer.prop_man.save_file_name + result_name = self.reducer.prop_man.save_file_name self.reducer.prop_man.log("*** Saving validation file with name: {0}.nxs".format(result_name),'notice') SaveNexus(reduced,Filename=result_name+'.nxs') return True,'Created validation file {0}.nxs'.format(result_name) @@ -167,7 +167,7 @@ def build_or_validate_result(self,sample_run,validationFile,build_validation=Fal CheckInstrument=False,ToleranceRelErr=ToleranceRelErr) self.wait_for_file = current_wait_state - self._run_from_web = current_web_state + self._run_from_web = current_web_state if result == 'Success!': return True,'Reference file and reduced workspace are equivalent' else: @@ -176,35 +176,35 @@ def build_or_validate_result(self,sample_run,validationFile,build_validation=Fal @abstractmethod def def_main_properties(self): """ Define properties which considered to be main properties changeable by user - - Should be overwritten by special reduction and decorated with @MainProperties decorator. - Should return dictionary with key are the properties names and values -- the default + Should be overwritten by special reduction and decorated with @MainProperties decorator. + + Should return dictionary with key are the properties names and values -- the default values these properties should have. - """ + """ raise NotImplementedError('def_main_properties has to be implemented') @abstractmethod def def_advanced_properties(self): """ Define properties which considered to be advanced but still changeable by instrument scientist or advanced user - - Should be overwritten by special reduction and decorated with @AdvancedProperties decorator. - Should return dictionary with key are the properties names and values -- the default + Should be overwritten by special reduction and decorated with @AdvancedProperties decorator. + + Should return dictionary with key are the properties names and values -- the default values these properties should have. - """ + """ raise NotImplementedError('def_advanced_properties has to be implemented') def reduce(self,input_file=None,output_directory=None): - """ The method performs all main reduction operations over + """ The method performs all main reduction operations over single run file - - Wrap it into @iliad wrapper to switch input for + + Wrap it into @iliad wrapper to switch input for reduction properties between script and web variables - """ + """ if input_file: - self.reducer.sample_run = input_file + self.reducer.sample_run = input_file timeToWait = self._wait_for_file if timeToWait: @@ -227,7 +227,7 @@ def reduce(self,input_file=None,output_directory=None): def MainProperties(main_prop_definition): """ Decorator stores properties dedicated as main and sets these properties - as input to reduction parameters.""" + as input to reduction parameters.""" def main_prop_wrapper(*args): # execute decorated function prop_dict = main_prop_definition(*args) @@ -243,7 +243,7 @@ def main_prop_wrapper(*args): def AdvancedProperties(adv_prop_definition): """ Decorator stores properties decided to be advanced and sets these properties as input for reduction parameters - """ + """ def advanced_prop_wrapper(*args): prop_dict = adv_prop_definition(*args) #print "in decorator: ",properties @@ -257,7 +257,7 @@ def advanced_prop_wrapper(*args): def iliad(reduce): - """ This decorator wraps around main procedure and switch input from + """ This decorator wraps around main procedure and switch input from web variables to properties or vise versa depending on web variables presence """ @@ -282,39 +282,39 @@ def iliad_wrapper(*args): output_directory=None # add input file folder to data search directory if file has it if input_file and isinstance(input_file,str): - data_path = os.path.dirname(input_file) - if len(data_path)>0: - try: - config.appendDataSearchDir(str(data_path)) - args[1] = os.path.basename(input_file) - except: # if mantid is not available, this should ignore config - pass + data_path = os.path.dirname(input_file) + if len(data_path)>0: + try: + config.appendDataSearchDir(str(data_path)) + args[1] = os.path.basename(input_file) + except: # if mantid is not available, this should ignore config + pass if output_directory: - config['defaultsave.directory'] = output_directory + config['defaultsave.directory'] = output_directory if host._run_from_web: web_vars = dict(host._wvs.standard_vars.items()+host._wvs.advanced_vars.items()) host.reducer.prop_man.set_input_parameters(**web_vars) else: - pass # we should set already set up variables using + pass # we should set already set up variables using + - rez = reduce(*args) - # prohibit returning workspace to web services. + # prohibit returning workspace to web services. if host._run_from_web and not isinstance(rez,str): rez="" - else: - if isinstance(rez,list): + else: + if isinstance(rez,list): # multirep run, just return as it is - return rez - if out_ws_name and rez.name() != out_ws_name : - rez=RenameWorkspace(InputWorkspace=rez,OutputWorkspace=out_ws_name) - + return rez + if out_ws_name and rez.name() != out_ws_name : + rez=RenameWorkspace(InputWorkspace=rez,OutputWorkspace=out_ws_name) + return rez return iliad_wrapper - + if __name__=="__main__": - pass \ No newline at end of file + pass diff --git a/Code/Mantid/scripts/Inelastic/Direct/RunDescriptor.py b/Code/Mantid/scripts/Inelastic/Direct/RunDescriptor.py index 9edf8e9a1d86..e403133dc79b 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/RunDescriptor.py +++ b/Code/Mantid/scripts/Inelastic/Direct/RunDescriptor.py @@ -1,4 +1,4 @@ -""" File contains Descriptors used describe run for direct inelastic reduction """ +""" File contains Descriptors used describe run for direct inelastic reduction """ from mantid.simpleapi import * @@ -18,7 +18,7 @@ class RunDescriptor(PropDescriptor): # class level reference to the property manager _PropMan = None #-------------------------------------------------------------------------------------------------------------------- - def __init__(self,prop_name,DocString=None): + def __init__(self,prop_name,DocString=None): """ """ # Run number self._run_number = None @@ -40,103 +40,103 @@ def __init__(self,prop_name,DocString=None): self.__doc__ = DocString #-------------------------------------------------------------------------------------------------------------------- def __get__(self,instance,owner): - """ return current run number or workspace if it is loaded""" - if not RunDescriptor._PropMan: - RunDescriptor._PropMan = owner - if instance is None: - return self - - if self._ws_name and self._ws_name in mtd: - return mtd[self._ws_name] - else: - return self._run_number + """ return current run number or workspace if it is loaded""" + if not RunDescriptor._PropMan: + RunDescriptor._PropMan = owner + if instance is None: + return self + + if self._ws_name and self._ws_name in mtd: + return mtd[self._ws_name] + else: + return self._run_number #-------------------------------------------------------------------------------------------------------------------- def __set__(self,instance,value): - """ Set up Run number and define workspace name from any source """ + """ Set up Run number and define workspace name from any source """ # - if not RunDescriptor._PropMan: - from PropertyManager import PropertyManager - RunDescriptor._PropMan = PropertyManager + if not RunDescriptor._PropMan: + from PropertyManager import PropertyManager + RunDescriptor._PropMan = PropertyManager - old_ws_name = self._ws_name - clear_fext = True + old_ws_name = self._ws_name + clear_fext = True #end - if value == None: # clear current run number - self._run_number = None - self._ws_name = None - self._ws_cname = '' - self._ws_suffix = '' - # only one RunDescriptor can be summed under current approach. + if value == None: # clear current run number + self._run_number = None + self._ws_name = None + self._ws_cname = '' + self._ws_suffix = '' + # only one RunDescriptor can be summed under current approach. # To disentangle one run descriptor from another -- set up binding - self._bind_to_sum = False - self._clear_old_ws(old_ws_name,self._ws_name,clear_fext) - RunDescriptor._PropMan.sum_runs.clear_sum() - return - if isinstance(value, api.Workspace): + self._bind_to_sum = False + self._clear_old_ws(old_ws_name,self._ws_name,clear_fext) + RunDescriptor._PropMan.sum_runs.clear_sum() + return + if isinstance(value, api.Workspace): #if 'SumOfRuns:' in value.getRun(): # TODO: not implemented #else: - if self._ws_name != value.name(): + if self._ws_name != value.name(): self._set_ws_as_source(value) self._clear_old_ws(old_ws_name,self._ws_name,clear_fext) self._bind_to_sum = False RunDescriptor._PropMan.sum_runs.clear_sum() return - else: # it is just reassigning the same workspace to itself - return - - if isinstance(value,str): # it may be run number as string or it may be a workspace name - if value in mtd: # workspace name - ws = mtd[value] - self.__set__(instance,ws) - return - else: - file_path,run_num,fext = prop_helpers.parse_run_file_name(value) - - if isinstance(run_num,list): - RunDescriptor._PropMan.sum_runs.set_list2add(run_num,file_path,fext) - self._bind_to_sum = True - if instance.sum_runs: - last_run_ind = RunDescriptor._PropMan.sum_runs.get_last_ind2sum() - main_fext = fext[last_run_ind].lower() - self._run_file_path = file_path[last_run_ind].lower() - else: - self.__set__(instance,run_num) - self._run_file_path = file_path - main_fext = fext.lower() - + else: # it is just reassigning the same workspace to itself + return + + if isinstance(value,str): # it may be run number as string or it may be a workspace name + if value in mtd: # workspace name + ws = mtd[value] + self.__set__(instance,ws) + return + else: + file_path,run_num,fext = prop_helpers.parse_run_file_name(value) + + if isinstance(run_num,list): + RunDescriptor._PropMan.sum_runs.set_list2add(run_num,file_path,fext) + self._bind_to_sum = True + if instance.sum_runs: + last_run_ind = RunDescriptor._PropMan.sum_runs.get_last_ind2sum() + main_fext = fext[last_run_ind].lower() + self._run_file_path = file_path[last_run_ind].lower() + else: + self.__set__(instance,run_num) + self._run_file_path = file_path + main_fext = fext.lower() + # - if len(main_fext) > 0: - self._run_ext = main_fext - else: # will be default file extension - self._run_ext = None - clear_fext = False - elif isinstance(value,list): - if len(value) == 1: - self.__set__(instance,value[0]) - return - self._bind_to_sum = True - RunDescriptor._PropMan.sum_runs.set_list2add(value) - if instance.sum_runs: + if len(main_fext) > 0: + self._run_ext = main_fext + else: # will be default file extension + self._run_ext = None + clear_fext = False + elif isinstance(value,list): + if len(value) == 1: + self.__set__(instance,value[0]) + return + self._bind_to_sum = True + RunDescriptor._PropMan.sum_runs.set_list2add(value) + if instance.sum_runs: last_run_ind = RunDescriptor._PropMan.sum_runs.get_last_ind2sum() self._run_number = value[last_run_ind] - else: - self._run_number = value[0] - clear_fext = True - else: - clear_fext = True - self._run_number = int(value) - if self._bind_to_sum and instance and instance.sum_runs: - num2_sum = RunDescriptor._PropMan.sum_runs.set_last_ind2sum(self._run_number) - if num2_sum == 0: - self._bind_to_sum = False - instance.sum_runs = False + else: + self._run_number = value[0] + clear_fext = True + else: + clear_fext = True + self._run_number = int(value) + if self._bind_to_sum and instance and instance.sum_runs: + num2_sum = RunDescriptor._PropMan.sum_runs.set_last_ind2sum(self._run_number) + if num2_sum == 0: + self._bind_to_sum = False + instance.sum_runs = False - self._ws_cname = '' - self._ws_name = None - self._clear_old_ws(old_ws_name,None,clear_fext) + self._ws_cname = '' + self._ws_name = None + self._clear_old_ws(old_ws_name,None,clear_fext) #-------------------------------------------------------------------------------------------------------------------- def run_number(self): """ Return run number regardless of workspace is loaded or not""" @@ -144,7 +144,7 @@ def run_number(self): ws = mtd[self._ws_name] return ws.getRunNumber() else: - return self._run_number + return self._run_number #-------------------------------------------------------------------------------------------------------------------- def is_monws_separate(self): """ """ @@ -169,16 +169,16 @@ def get_run_list(self): else: return [current_run] else: - return [current_run] + return [current_run] #-------------------------------------------------------------------------------------------------------------------- def set_action_suffix(self,suffix=None): - """ method to set part of the workspace name, which indicate some action performed over this workspace - - e.g.: default suffix of a loaded workspace is 'RAW' but we can set it to SPE to show that conversion to + """ method to set part of the workspace name, which indicate some action performed over this workspace + + e.g.: default suffix of a loaded workspace is 'RAW' but we can set it to SPE to show that conversion to energy will be performed for this workspace. - method returns the name of the workspace is will have with this suffix. Algorithms would later - work on the initial workspace and modify it in-place or to produce workspace with new name (depending if one + method returns the name of the workspace is will have with this suffix. Algorithms would later + work on the initial workspace and modify it in-place or to produce workspace with new name (depending if one wants to keep initial workspace) synchronize_ws(ws_pointer) then should synchronize workspace and its name. @@ -193,32 +193,32 @@ def set_action_suffix(self,suffix=None): return self._build_ws_name() #-------------------------------------------------------------------------------------------------------------------- def synchronize_ws(self,workspace=None): - """ Synchronize workspace name (after workspace may have changed due to algorithm) - with internal run holder name. Accounts for the situation when + """ Synchronize workspace name (after workspace may have changed due to algorithm) + with internal run holder name. Accounts for the situation when TODO: This method should be automatically invoked by an algorithm decorator - Until implemented, one have to ensure that it is correctly used together with + Until implemented, one have to ensure that it is correctly used together with set_action_suffix to ensue one can always get expected workspace from its name - outside of a method visibility - """ + outside of a method visibility + """ if not workspace: workspace = mtd[self._ws_name] new_name = self._build_ws_name() old_name = workspace.name() if new_name != old_name: - RenameWorkspace(InputWorkspace=old_name,OutputWorkspace=new_name) + RenameWorkspace(InputWorkspace=old_name,OutputWorkspace=new_name) - old_mon_name = old_name + '_monitors' - new_mon_name = new_name + '_monitors' - if old_mon_name in mtd: - RenameWorkspace(InputWorkspace=old_mon_name,OutputWorkspace=new_mon_name) + old_mon_name = old_name + '_monitors' + new_mon_name = new_name + '_monitors' + if old_mon_name in mtd: + RenameWorkspace(InputWorkspace=old_mon_name,OutputWorkspace=new_mon_name) self._ws_name = new_name #-------------------------------------------------------------------------------------------------------------------- def get_file_ext(self): - """ Method returns current file extension for file to load workspace from + """ Method returns current file extension for file to load workspace from e.g. .raw or .nxs extension - """ + """ if self._run_ext: return self._run_ext else: # return IDF default @@ -237,23 +237,23 @@ def set_file_ext(self,val): #-------------------------------------------------------------------------------------------------------------------- @staticmethod def _check_claibration_source(): - """ if user have not specified calibration as input to the script, + """ if user have not specified calibration as input to the script, try to retrieve calibration stored in file with run properties""" - changed_prop = RunDescriptor._holder.getChangedProperties() - if 'det_cal_file' in changed_prop: - use_workspace_calibration = False - else: - use_workspace_calibration = True - return use_workspace_calibration + changed_prop = RunDescriptor._holder.getChangedProperties() + if 'det_cal_file' in changed_prop: + use_workspace_calibration = False + else: + use_workspace_calibration = True + return use_workspace_calibration #-------------------------------------------------------------------------------------------------------------------- def get_workspace(self): """ Method returns workspace correspondent to current run number(s) and loads this workspace if it has not been loaded Returns Mantid pointer to the workspace, corresponding to this run number - """ + """ if not self._ws_name: - self._ws_name = self._build_ws_name() + self._ws_name = self._build_ws_name() if self._ws_name in mtd: @@ -261,26 +261,26 @@ def get_workspace(self): if ws.run().hasProperty("calibrated"): return ws # already calibrated else: - prefer_ws_calibration = self._check_claibration_source() - self.apply_calibration(ws,RunDescriptor._holder.det_cal_file,prefer_ws_calibration) - return ws + prefer_ws_calibration = self._check_claibration_source() + self.apply_calibration(ws,RunDescriptor._holder.det_cal_file,prefer_ws_calibration) + return ws else: - if self._run_number: - prefer_ws_calibration = self._check_claibration_source() - inst_name = RunDescriptor._holder.short_inst_name - calibration = RunDescriptor._holder.det_cal_file - if self._bind_to_sum and RunDescriptor._holder.sum_runs : # Sum runs - ws = RunDescriptor._PropMan.sum_runs.load_and_sum_runs(inst_name,RunDescriptor._holder.load_monitors_with_workspace) - else: # load current workspace - ws = self.load_run(inst_name, calibration,False, RunDescriptor._holder.load_monitors_with_workspace,prefer_ws_calibration) - - - self.synchronize_ws(ws) - self.apply_calibration(ws,calibration,prefer_ws_calibration) - - return ws - else: - return None + if self._run_number: + prefer_ws_calibration = self._check_claibration_source() + inst_name = RunDescriptor._holder.short_inst_name + calibration = RunDescriptor._holder.det_cal_file + if self._bind_to_sum and RunDescriptor._holder.sum_runs : # Sum runs + ws = RunDescriptor._PropMan.sum_runs.load_and_sum_runs(inst_name,RunDescriptor._holder.load_monitors_with_workspace) + else: # load current workspace + ws = self.load_run(inst_name, calibration,False, RunDescriptor._holder.load_monitors_with_workspace,prefer_ws_calibration) + + + self.synchronize_ws(ws) + self.apply_calibration(ws,calibration,prefer_ws_calibration) + + return ws + else: + return None #-------------------------------------------------------------------------------------------------------------------- def get_ws_clone(self,clone_name='ws_clone'): """ Get unbounded clone of eisting Run workspace """ @@ -303,33 +303,33 @@ def _set_ws_as_source(self,value): #-------------------------------------------------------------------------------------------------------------------- def chop_ws_part(self,origin,tof_range,rebin,chunk_num,n_chunks): - """ chop part of the original workspace and sets it up as new original. - Return the old one """ + """ chop part of the original workspace and sets it up as new original. + Return the old one """ if not(origin): - origin = self.get_workspace() + origin = self.get_workspace() origin_name = origin.name() try: - mon_ws = mtd[origin_name+'_monitors'] + mon_ws = mtd[origin_name+'_monitors'] except: - mon_ws = None + mon_ws = None target_name = '#{0}/{1}#'.format(chunk_num,n_chunks)+origin_name if chunk_num == n_chunks: - RenameWorkspace(InputWorkspace=origin_name,OutputWorkspace=target_name) - if mon_ws: - RenameWorkspace(InputWorkspace=mon_ws,OutputWorkspace=target_name+'_monitors') - origin_name = target_name - origin_invalidated=True + RenameWorkspace(InputWorkspace=origin_name,OutputWorkspace=target_name) + if mon_ws: + RenameWorkspace(InputWorkspace=mon_ws,OutputWorkspace=target_name+'_monitors') + origin_name = target_name + origin_invalidated=True else: - if mon_ws: - CloneWorkspace(InputWorkspace=mon_ws,OutputWorkspace=target_name+'_monitors') - origin_invalidated=False + if mon_ws: + CloneWorkspace(InputWorkspace=mon_ws,OutputWorkspace=target_name+'_monitors') + origin_invalidated=False if rebin: # debug and compatibility mode with old reduction - Rebin(origin_name,OutputWorkspace=target_name,Params=[tof_range[0],tof_range[1],tof_range[2]],PreserveEvents=False) + Rebin(origin_name,OutputWorkspace=target_name,Params=[tof_range[0],tof_range[1],tof_range[2]],PreserveEvents=False) else: - CropWorkspace(origin_name,OutputWorkspace=target_name,XMin=tof_range[0],XMax=tof_range[2]) + CropWorkspace(origin_name,OutputWorkspace=target_name,XMin=tof_range[0],XMax=tof_range[2]) self._set_ws_as_source(mtd[target_name]) if origin_invalidated: @@ -339,7 +339,7 @@ def chop_ws_part(self,origin,tof_range,rebin,chunk_num,n_chunks): #-------------------------------------------------------------------------------------------------------------------- def get_monitors_ws(self,monitor_ID=None): - """ get pointer to a workspace containing monitors. + """ get pointer to a workspace containing monitors. Explores different ways of finding monitor workspace in Mantid and returns the python pointer to the workspace which contains monitors. @@ -360,39 +360,39 @@ def get_monitors_ws(self,monitor_ID=None): mon_ws = self.copy_spectrum2monitors(data_ws,mon_ws,specID) if monitor_ID: - try: - ws_index = mon_ws.getIndexFromSpectrumNumber(monitor_ID) - except: # - mon_ws = None - else: + try: + ws_index = mon_ws.getIndexFromSpectrumNumber(monitor_ID) + except: # + mon_ws = None + else: mon_list = self._holder.get_used_monitors_list() for monID in mon_list: try: ws_ind = mon_ws.getIndexFromSpectrumNumber(int(monID)) except: - mon_ws = None - break + mon_ws = None + break return mon_ws #-------------------------------------------------------------------------------------------------------------------- def get_ws_name(self): """ return workspace name. If ws name is not defined, build it first and set up as the target ws name - """ + """ if self._ws_name: if self._ws_name in mtd: return self._ws_name else: - raise RuntimeError('Getting workspace name {0} for undefined workspace. Run get_workspace first'.format(self._ws_name)) + raise RuntimeError('Getting workspace name {0} for undefined workspace. Run get_workspace first'.format(self._ws_name)) self._ws_name = self._build_ws_name() return self._ws_name #-------------------------------------------------------------------------------------------------------------------- def file_hint(self,run_num_str=None,filePath=None,fileExt=None,**kwargs): """ procedure to provide run file guess name from run properties - + main purpose -- to support customized order of file extensions - """ + """ if not run_num_str: - run_num_str = str(self.run_number()) + run_num_str = str(self.run_number()) inst_name = RunDescriptor._holder.short_inst_name @@ -403,9 +403,9 @@ def file_hint(self,run_num_str=None,filePath=None,fileExt=None,**kwargs): old_ext = self.get_file_ext() else: if fileExt: - old_ext = fileExt + old_ext = fileExt else: - old_ext = self.get_file_ext() + old_ext = self.get_file_ext() hint = inst_name + run_num_str + old_ext if not filePath: @@ -443,32 +443,32 @@ def find_file(self,inst_name=None,run_num=None,filePath=None,fileExt=None,**kwar self._run_file_path = os.path.dirname(fname) return file except RuntimeError: - message = 'Cannot find file matching hint {0} on current search paths ' \ + message = 'Cannot find file matching hint {0} on current search paths ' \ 'for instrument {1}'.format(file_hint,inst_name) - if not ('be_quet' in kwargs): + if not ('be_quet' in kwargs): RunDescriptor._logger(message,'warning') - return 'ERROR:find_file: ' + message + return 'ERROR:find_file: ' + message #-------------------------------------------------------------------------------------------------------------------- def load_file(self,inst_name,ws_name,run_number=None,load_mon_with_workspace=False,filePath=None,fileExt=None,**kwargs): - """ load run for the instrument name provided. If run_numner is None, look for the current run""" - + """ load run for the instrument name provided. If run_numner is None, look for the current run""" + data_file = self.find_file(None,filePath,fileExt,**kwargs) if data_file.find('ERROR') > -1: - self._ws_name = None - raise IOError(data_file) - + self._ws_name = None + raise IOError(data_file) + if load_mon_with_workspace: - mon_load_option = 'Include' + mon_load_option = 'Include' else: - mon_load_option = 'Separate' + mon_load_option = 'Separate' # try: # Hack: LoadEventNexus does not understand Separate at the moment and throws. # And event loader always loads monitors separately - Load(Filename=data_file, OutputWorkspace=ws_name,LoadMonitors = mon_load_option) + Load(Filename=data_file, OutputWorkspace=ws_name,LoadMonitors = mon_load_option) except ValueError: #mon_load_option =str(int(load_mon_with_workspace)) - Load(Filename=data_file, OutputWorkspace=ws_name,LoadMonitors = '1',MonitorsAsEvents='0') + Load(Filename=data_file, OutputWorkspace=ws_name,LoadMonitors = '1',MonitorsAsEvents='0') RunDescriptor._logger("Loaded {0}".format(data_file),'information') @@ -506,17 +506,17 @@ def load_run(self,inst_name, calibration=None, force=False, mon_load_option=Fals return loaded_ws #-------------------------------------------------------------------------------------------------------------------- def apply_calibration(self,loaded_ws,calibration=None,use_ws_calibration=True): - """ If calibration is present, apply it to the workspace - - use_ws_calibration -- if true, retrieve workspace property, which defines + """ If calibration is present, apply it to the workspace + + use_ws_calibration -- if true, retrieve workspace property, which defines calibration option (e.g. det_cal_file used a while ago) and try to use it """ if not (calibration or use_ws_calibration): - return + return if not isinstance(loaded_ws, api.Workspace): - raise RuntimeError(' Calibration can be applied to a workspace only and got object of type {0}'.format(type(loaded_ws))) - + raise RuntimeError(' Calibration can be applied to a workspace only and got object of type {0}'.format(type(loaded_ws))) + if loaded_ws.run().hasProperty("calibrated"): return # already calibrated @@ -532,7 +532,7 @@ def apply_calibration(self,loaded_ws,calibration=None,use_ws_calibration=True): test_name = ws_calibration ws_calibration = FileFinder.getFullPath(ws_calibration) if len(ws_calibration) == 0: - raise RuntimeError('Can not find defined in run {0} calibration file {1}\n'\ + raise RuntimeError('Can not find defined in run {0} calibration file {1}\n'\ 'Define det_cal_file reduction parameter properly'.format(loaded_ws.name(),test_name)) RunDescriptor._logger('*** load_data: Calibrating data using workspace defined calibration file: {0}'.format(ws_calibration),'notice') except KeyError: # no det_cal_file defined in workspace @@ -553,42 +553,42 @@ def apply_calibration(self,loaded_ws,calibration=None,use_ws_calibration=True): #-------------------------------------------------------------------------------------------------------------------- @staticmethod def copy_spectrum2monitors(data_ws,mon_ws,spectraID): - """ + """ this routine copies a spectrum form workspace to monitor workspace and rebins it according to monitor workspace binning @param data_ws -- the event workspace which detector is considered as monitor or Mantid pointer to this workspace - @param mon_ws -- the histogram workspace with monitors where one needs to place the detector's spectra + @param mon_ws -- the histogram workspace with monitors where one needs to place the detector's spectra @param spectraID-- the ID of the spectra to copy. """ - + # ---------------------------- - try: - ws_index = mon_ws.getIndexFromSpectrumNumber(spectraID) + try: + ws_index = mon_ws.getIndexFromSpectrumNumber(spectraID) # Spectra is already in the monitor workspace - return mon_ws - except: - ws_index = data_ws.getIndexFromSpectrumNumber(spectraID) + return mon_ws + except: + ws_index = data_ws.getIndexFromSpectrumNumber(spectraID) # - x_param = mon_ws.readX(0) - bins = [x_param[0],x_param[1] - x_param[0],x_param[-1]] - ExtractSingleSpectrum(InputWorkspace=data_ws,OutputWorkspace='tmp_mon',WorkspaceIndex=ws_index) - Rebin(InputWorkspace='tmp_mon',OutputWorkspace='tmp_mon',Params=bins,PreserveEvents='0') + x_param = mon_ws.readX(0) + bins = [x_param[0],x_param[1] - x_param[0],x_param[-1]] + ExtractSingleSpectrum(InputWorkspace=data_ws,OutputWorkspace='tmp_mon',WorkspaceIndex=ws_index) + Rebin(InputWorkspace='tmp_mon',OutputWorkspace='tmp_mon',Params=bins,PreserveEvents='0') # should be vice versa but Conjoin invalidate ws pointers and hopefully # nothing could happen with workspace during conjoining #AddSampleLog(Workspace=monWS,LogName=done_log_name,LogText=str(ws_index),LogType='Number') - mon_ws_name = mon_ws.getName() - ConjoinWorkspaces(InputWorkspace1=mon_ws,InputWorkspace2='tmp_mon') - mon_ws = mtd[mon_ws_name] + mon_ws_name = mon_ws.getName() + ConjoinWorkspaces(InputWorkspace1=mon_ws,InputWorkspace2='tmp_mon') + mon_ws = mtd[mon_ws_name] - if 'tmp_mon' in mtd: - DeleteWorkspace(WorkspaceName='tmp_mon') - return mon_ws + if 'tmp_mon' in mtd: + DeleteWorkspace(WorkspaceName='tmp_mon') + return mon_ws #-------------------------------------------------------------------------------------------------------------------- def clear_monitors(self): - """ method removes monitor workspace form analysis data service if it is there - + """ method removes monitor workspace form analysis data service if it is there + (assuming it is not needed any more) """ monWS_name = self._ws_name + '_monitors' @@ -607,7 +607,7 @@ def _build_ws_name(self): else: ws_name = '{0}{1}{2}{3}'.format(self._prop_name,self._ws_cname,sum_ext,self._ws_suffix) - return ws_name + return ws_name #-------------------------------------------------------------------------------------------------------------------- @staticmethod def rremove(thestr, trailing): @@ -616,7 +616,7 @@ def rremove(thestr, trailing): return thestr[:-thelen] return thestr def _split_ws_name(self,ws_name): - """ Method to split existing workspace name + """ Method to split existing workspace name into parts, in such a way that _build_name would restore the same name """ # Remove suffix @@ -628,10 +628,10 @@ def _split_ws_name(self,ws_name): name = name.replace(self._prop_name,'',1) try: - part_ind = re.search('#(.+?)#', name).group(0) - name =name.replace(part_ind,'',1) + part_ind = re.search('#(.+?)#', name).group(0) + name =name.replace(part_ind,'',1) except AttributeError: - part_ind='' + part_ind='' if self._run_number: instr_name = self._instr_name() @@ -642,24 +642,24 @@ def _split_ws_name(self,ws_name): self._ws_cname = part_ind+name # def _instr_name(self): - if RunDescriptor._holder: + if RunDescriptor._holder: instr_name = RunDescriptor._holder.short_inst_name - else: + else: instr_name = '_test_instrument' - return instr_name + return instr_name def _clear_old_ws(self,old_ws_name,new_name,clear_fext=False): """ helper method used in __set__. When new data (run or wod) """ if old_ws_name: - if new_name != old_ws_name: + if new_name != old_ws_name: if old_ws_name in mtd: - DeleteWorkspace(old_ws_name) + DeleteWorkspace(old_ws_name) old_mon_ws = old_ws_name + '_monitors' if old_mon_ws in mtd: DeleteWorkspace(old_mon_ws) if clear_fext: - self._run_ext = None - self._run_file_path = '' + self._run_ext = None + self._run_file_path = '' #------------------------------------------------------------------------------------------------------------------------------- @@ -668,7 +668,7 @@ def _clear_old_ws(self,old_ws_name,new_name,clear_fext=False): class RunDescriptorDependent(RunDescriptor): """ Simple RunDescriptor class dependent on another RunDescriptor, providing the host descriptor if current descriptor value is not defined - or usual descriptor functionality if somebody sets current descriptor up + or usual descriptor functionality if somebody sets current descriptor up """ def __init__(self,host_run,ws_preffix,DocString=None): @@ -677,14 +677,14 @@ def __init__(self,host_run,ws_preffix,DocString=None): self._this_run_defined = False def __get__(self,instance,owner=None): - """ return dependent run number which is host run number if this one has not been set or this run number if it was""" - if self._this_run_defined: - if instance is None: - return self - else: + """ return dependent run number which is host run number if this one has not been set or this run number if it was""" + if self._this_run_defined: + if instance is None: + return self + else: return super(RunDescriptorDependent,self).__get__(instance,owner) - else: - return self._host.__get__(instance,owner) + else: + return self._host.__get__(instance,owner) def __set__(self,instance,value): if value is None: @@ -694,7 +694,7 @@ def __set__(self,instance,value): super(RunDescriptorDependent,self).__set__(instance,value) #def __del__(self): - # # destructor removes bounded workspace + # # destructor removes bounded workspace # # Probably better not to at current approach # if self._ws_name in mtd: # DeleteWorkspace(self._ws_name) diff --git a/Code/Mantid/scripts/Inelastic/Direct/__init__.py b/Code/Mantid/scripts/Inelastic/Direct/__init__.py index e798813ca1ff..26487e011f10 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/__init__.py +++ b/Code/Mantid/scripts/Inelastic/Direct/__init__.py @@ -4,8 +4,8 @@ DirectEnergyConversion -- main reduction class PropertyManager -- helper class providing access and functionality for IDF properties ReductionWrapper -- parent class for reduction, After overloading for particular insrument provides common interface for Mantid and web services -RunDescriptor -- Class descripbing a run and instantiated as property of Property manager to specify a +RunDescriptor -- Class descripbing a run and instantiated as property of Property manager to specify a particular kind of run (e.g. sample run, monovan run etc...) """ -__all__=['dgreduce','DirectEnergyConversion','PropertyManager','ReductionWrapper','RunDescriptor'] \ No newline at end of file +__all__=['dgreduce','DirectEnergyConversion','PropertyManager','ReductionWrapper','RunDescriptor'] diff --git a/Code/Mantid/scripts/Inelastic/Direct/dgreduce.py b/Code/Mantid/scripts/Inelastic/Direct/dgreduce.py index 80b41f20c374..67ebb7df6fb5 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/dgreduce.py +++ b/Code/Mantid/scripts/Inelastic/Direct/dgreduce.py @@ -36,7 +36,7 @@ def setup(instname=None,reload=False): old_name=Reducer.prop_man.instr_name if old_name.upper()[0:3] == instname.upper()[0:3] : if not reload : - return # has been already defined + return # has been already defined Reducer = DRC.setup_reducer(instname,reload) @@ -137,10 +137,10 @@ def arb_units(wb_run,sample_run,ei_guess,rebin,map_file='default',monovan_run=No if sample_run: Reducer.sample_run = sample_run try: - n,r=funcreturns.lhs_info('both') - wksp_out=r[0] + n,r=funcreturns.lhs_info('both') + wksp_out=r[0] except: - wksp_out = Reducer.prop_man.get_sample_ws_name() + wksp_out = Reducer.prop_man.get_sample_ws_name() # res = Reducer.convert_to_energy(wb_run,sample_run,ei_guess,rebin,map_file,monovan_run,second_wb,**kwargs) # diff --git a/Code/Mantid/scripts/Inelastic/Direct/diagnostics.py b/Code/Mantid/scripts/Inelastic/Direct/diagnostics.py index 10898f95070d..a48b55901abc 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/diagnostics.py +++ b/Code/Mantid/scripts/Inelastic/Direct/diagnostics.py @@ -135,18 +135,18 @@ def diagnose(white_int,**kwargs): end_index_name=" to: end" default = True if hasattr(parser, 'print_diag_results') and parser.print_diag_results: - default=True + default=True if 'start_index' in kwargs: - default = False - start_index_name = "from: "+str(kwargs['start_index']) + default = False + start_index_name = "from: "+str(kwargs['start_index']) if 'end_index' in kwargs : - default = False - end_index_name = " to: "+str(kwargs['end_index']) + default = False + end_index_name = " to: "+str(kwargs['end_index']) testName=start_index_name+end_index_name if not default : - testName = " For bank: "+start_index_name+end_index_name + testName = " For bank: "+start_index_name+end_index_name if hasattr(parser, 'print_diag_results') and parser.print_diag_results: print_test_summary(test_results,testName) @@ -271,11 +271,11 @@ def normalise_background(background_int, white_int, second_white_int=None): """ if second_white_int is None: # quetly divide background integral by white beam integral not reporting about possible 0 in wb integral (they will be removed by diag anyway) - background_int = Divide(LHSWorkspace=background_int,RHSWorkspace=white_int,WarnOnZeroDivide='0'); + background_int = Divide(LHSWorkspace=background_int,RHSWorkspace=white_int,WarnOnZeroDivide='0') else: hmean = 2.0*white_int*second_white_int/(white_int+second_white_int) #background_int /= hmean - background_int = Divide(LHSWorkspace=background_int,RHSWorkspace=hmean,WarnOnZeroDivide='0'); + background_int = Divide(LHSWorkspace=background_int,RHSWorkspace=hmean,WarnOnZeroDivide='0') DeleteWorkspace(hmean) #------------------------------------------------------------------------------ @@ -324,11 +324,11 @@ def do_bleed_test(sample_run, max_framerate, ignored_pixels): # Load the sample run if __Reducer__: # Try to use generic loader which would work with files or workspaces alike sample_run = __Reducer__.get_run_descriptor(sample_run) - data_ws = sample_run.get_workspace() # this will load data if necessary + data_ws = sample_run.get_workspace() # this will load data if necessary ws_name = sample_run.get_ws_name()+'_bleed' - else: + else: # may be sample run is already a run descriptor despite __Reducer__ have not been exposed - data_ws = sample_run.get_workspace() # this will load data if necessary + data_ws = sample_run.get_workspace() # this will load data if necessary ws_name = sample_run.get_ws_name()+'_bleed' if max_framerate is None: diff --git a/Code/Mantid/scripts/Inelastic/IndirectBayes.py b/Code/Mantid/scripts/Inelastic/IndirectBayes.py index 90123e79487c..a4fb2aacdacf 100644 --- a/Code/Mantid/scripts/Inelastic/IndirectBayes.py +++ b/Code/Mantid/scripts/Inelastic/IndirectBayes.py @@ -141,8 +141,8 @@ def ReadWidthFile(readWidth,widthFile,numSampleGroups): raise ValueError('Width groups (' +str(numLines) + ') not = Sample (' +str(numSampleGroups) +')') else: # no file: just use constant values - widthY = np.zeros(numSampleGroups) - widthE = np.zeros(numSampleGroups) + widthY = np.zeros(numSampleGroups) + widthE = np.zeros(numSampleGroups) # pad for Fortran call widthY = PadArray(widthY,51) @@ -513,12 +513,12 @@ def C2Fw(prog,sname): axis_names.append('f'+str(nl)+'.f0.'+'Height') x.append(x_data) for j in range(1,nl+1): - axis_names.append('f'+str(nl)+'.f'+str(j)+'.Amplitude') - x.append(x_data) - axis_names.append('f'+str(nl)+'.f'+str(j)+'.FWHM') - x.append(x_data) - axis_names.append('f'+str(nl)+'.f'+str(j)+'.EISF') - x.append(x_data) + axis_names.append('f'+str(nl)+'.f'+str(j)+'.Amplitude') + x.append(x_data) + axis_names.append('f'+str(nl)+'.f'+str(j)+'.FWHM') + x.append(x_data) + axis_names.append('f'+str(nl)+'.f'+str(j)+'.EISF') + x.append(x_data) x = np.asarray(x).flatten() y = np.asarray(y).flatten() diff --git a/Code/Mantid/scripts/Inelastic/IndirectCommon.py b/Code/Mantid/scripts/Inelastic/IndirectCommon.py index 043c2717866c..fc7993f9e4b3 100644 --- a/Code/Mantid/scripts/Inelastic/IndirectCommon.py +++ b/Code/Mantid/scripts/Inelastic/IndirectCommon.py @@ -388,32 +388,32 @@ def plotParameters(ws, *param_names): plotSpectra(ws, name, indicies) def convertToElasticQ(input_ws, output_ws=None): - """ + """ Helper function to convert the spectrum axis of a sample to ElasticQ. @param input_ws - the name of the workspace to convert from @param output_ws - the name to call the converted workspace """ - if output_ws is None: - output_ws = input_ws + if output_ws is None: + output_ws = input_ws - axis = mtd[input_ws].getAxis(1) - if axis.isSpectra(): - e_fixed = getEfixed(input_ws) - ConvertSpectrumAxis(input_ws,Target='ElasticQ',EMode='Indirect',EFixed=e_fixed,OutputWorkspace=output_ws) + axis = mtd[input_ws].getAxis(1) + if axis.isSpectra(): + e_fixed = getEfixed(input_ws) + ConvertSpectrumAxis(input_ws,Target='ElasticQ',EMode='Indirect',EFixed=e_fixed,OutputWorkspace=output_ws) - elif axis.isNumeric(): + elif axis.isNumeric(): #check that units are Momentum Transfer - if axis.getUnit().unitID() != 'MomentumTransfer': - raise RuntimeError('Input must have axis values of Q') + if axis.getUnit().unitID() != 'MomentumTransfer': + raise RuntimeError('Input must have axis values of Q') - CloneWorkspace(input_ws, OutputWorkspace=output_ws) - else: - raise RuntimeError('Input workspace must have either spectra or numeric axis.') + CloneWorkspace(input_ws, OutputWorkspace=output_ws) + else: + raise RuntimeError('Input workspace must have either spectra or numeric axis.') def transposeFitParametersTable(params_table, output_table=None): - """ + """ Transpose the parameter table created from a multi domain Fit. This function will make the output consistent with PlotPeakByLogValue. @@ -421,44 +421,44 @@ def transposeFitParametersTable(params_table, output_table=None): @param output_table - name to call the transposed table. If omitted, the output_table will be the same as the params_table """ - params_table = mtd[params_table] + params_table = mtd[params_table] - table_ws = '__tmp_table_ws' - table_ws = CreateEmptyTableWorkspace(OutputWorkspace=table_ws) + table_ws = '__tmp_table_ws' + table_ws = CreateEmptyTableWorkspace(OutputWorkspace=table_ws) - param_names = params_table.column(0)[:-1] #-1 to remove cost function - param_values = params_table.column(1)[:-1] - param_errors = params_table.column(2)[:-1] + param_names = params_table.column(0)[:-1] #-1 to remove cost function + param_values = params_table.column(1)[:-1] + param_errors = params_table.column(2)[:-1] #find the number of parameters per function - func_index = param_names[0].split('.')[0] - num_params = 0 - for i, name in enumerate(param_names): - if name.split('.')[0] != func_index: - num_params = i - break + func_index = param_names[0].split('.')[0] + num_params = 0 + for i, name in enumerate(param_names): + if name.split('.')[0] != func_index: + num_params = i + break #create columns with parameter names for headers - column_names = ['.'.join(name.split('.')[1:]) for name in param_names[:num_params]] - column_error_names = [name + '_Err' for name in column_names] - column_names = zip(column_names, column_error_names) - table_ws.addColumn('double', 'axis-1') - for name, error_name in column_names: - table_ws.addColumn('double', name) - table_ws.addColumn('double', error_name) + column_names = ['.'.join(name.split('.')[1:]) for name in param_names[:num_params]] + column_error_names = [name + '_Err' for name in column_names] + column_names = zip(column_names, column_error_names) + table_ws.addColumn('double', 'axis-1') + for name, error_name in column_names: + table_ws.addColumn('double', name) + table_ws.addColumn('double', error_name) #output parameter values to table row - for i in xrange(0, params_table.rowCount()-1, num_params): - row_values = param_values[i:i+num_params] - row_errors = param_errors[i:i+num_params] - row = [value for pair in zip(row_values, row_errors) for value in pair] - row = [i/num_params] + row - table_ws.addRow(row) + for i in xrange(0, params_table.rowCount()-1, num_params): + row_values = param_values[i:i+num_params] + row_errors = param_errors[i:i+num_params] + row = [value for pair in zip(row_values, row_errors) for value in pair] + row = [i/num_params] + row + table_ws.addRow(row) - if output_table is None: - output_table = params_table.name() + if output_table is None: + output_table = params_table.name() - RenameWorkspace(table_ws.name(), OutputWorkspace=output_table) + RenameWorkspace(table_ws.name(), OutputWorkspace=output_table) def search_for_fit_params(suffix, table_ws): @@ -472,7 +472,7 @@ def search_for_fit_params(suffix, table_ws): def convertParametersToWorkspace(params_table, x_column, param_names, output_name): - """ + """ Convert a parameter table output by PlotPeakByLogValue to a MatrixWorkspace. This will make a spectrum for each parameter name using the x_column vairable as the @@ -485,57 +485,57 @@ def convertParametersToWorkspace(params_table, x_column, param_names, output_nam """ #search for any parameters in the table with the given parameter names, #ignoring their function index and output them to a workspace - workspace_names = [] - for param_name in param_names: - column_names = search_for_fit_params(param_name, params_table) - column_error_names = search_for_fit_params(param_name+'_Err', params_table) - param_workspaces = [] - for name, error_name in zip(column_names, column_error_names): - ConvertTableToMatrixWorkspace(params_table, x_column, name, error_name, OutputWorkspace=name) - param_workspaces.append(name) - workspace_names.append(param_workspaces) + workspace_names = [] + for param_name in param_names: + column_names = search_for_fit_params(param_name, params_table) + column_error_names = search_for_fit_params(param_name+'_Err', params_table) + param_workspaces = [] + for name, error_name in zip(column_names, column_error_names): + ConvertTableToMatrixWorkspace(params_table, x_column, name, error_name, OutputWorkspace=name) + param_workspaces.append(name) + workspace_names.append(param_workspaces) #transpose list of workspaces, ignoring unequal length of lists #this handles the case where a parameter occurs only once in the whole workspace - workspace_names = map(list, itertools.izip_longest(*workspace_names)) - workspace_names = [filter(None, sublist) for sublist in workspace_names] + workspace_names = map(list, itertools.izip_longest(*workspace_names)) + workspace_names = [filter(None, sublist) for sublist in workspace_names] #join all the parameters for each peak into a single workspace per peak - temp_workspaces = [] - for peak_params in workspace_names: - temp_peak_ws = peak_params[0] - for param_ws in peak_params[1:]: - ConjoinWorkspaces(temp_peak_ws, param_ws, False) - temp_workspaces.append(temp_peak_ws) + temp_workspaces = [] + for peak_params in workspace_names: + temp_peak_ws = peak_params[0] + for param_ws in peak_params[1:]: + ConjoinWorkspaces(temp_peak_ws, param_ws, False) + temp_workspaces.append(temp_peak_ws) #join all peaks into a single workspace - temp_workspace = temp_workspaces[0] - for temp_ws in temp_workspaces[1:]: - ConjoinWorkspaces(temp_workspace, temp_peak_ws, False) + temp_workspace = temp_workspaces[0] + for temp_ws in temp_workspaces[1:]: + ConjoinWorkspaces(temp_workspace, temp_peak_ws, False) - RenameWorkspace(temp_workspace, OutputWorkspace=output_name) + RenameWorkspace(temp_workspace, OutputWorkspace=output_name) #replace axis on workspaces with text axis - axis = TextAxis.create(mtd[output_name].getNumberHistograms()) - workspace_names = [name for sublist in workspace_names for name in sublist] - for i, name in enumerate(workspace_names): - axis.setLabel(i, name) - mtd[output_name].replaceAxis(1, axis) + axis = TextAxis.create(mtd[output_name].getNumberHistograms()) + workspace_names = [name for sublist in workspace_names for name in sublist] + for i, name in enumerate(workspace_names): + axis.setLabel(i, name) + mtd[output_name].replaceAxis(1, axis) def addSampleLogs(ws, sample_logs): - """ + """ Add a dictionary of logs to a workspace. The type of the log is inferred by the type of the value passed to the log. @param ws - workspace to add logs too. @param sample_logs - dictionary of logs to append to the workspace. """ - for key, value in sample_logs.iteritems(): - if isinstance(value, bool): - log_type = 'String' - elif isinstance(value, (int, long, float)): - log_type = 'Number' - else: - log_type = 'String' + for key, value in sample_logs.iteritems(): + if isinstance(value, bool): + log_type = 'String' + elif isinstance(value, (int, long, float)): + log_type = 'Number' + else: + log_type = 'String' - AddSampleLog(Workspace=ws, LogName=key, LogType=log_type, LogText=str(value)) + AddSampleLog(Workspace=ws, LogName=key, LogType=log_type, LogText=str(value)) diff --git a/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py b/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py index ca7a18289489..35fab8fc8043 100644 --- a/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py +++ b/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py @@ -160,177 +160,177 @@ def confitSeq(inputWS, func, startX, endX, ftype, bgd, temperature=None, specMin def furyfitSeq(inputWS, func, ftype, startx, endx, spec_min=0, spec_max=None, intensities_constrained=False, Save=False, Plot='None'): - StartTime('FuryFit') + StartTime('FuryFit') - fit_type = ftype[:-2] - logger.information('Option: ' + fit_type) - logger.information(func) + fit_type = ftype[:-2] + logger.information('Option: ' + fit_type) + logger.information(func) - tmp_fit_workspace = "__furyfit_fit_ws" - CropWorkspace(InputWorkspace=inputWS, OutputWorkspace=tmp_fit_workspace, XMin=startx, XMax=endx) + tmp_fit_workspace = "__furyfit_fit_ws" + CropWorkspace(InputWorkspace=inputWS, OutputWorkspace=tmp_fit_workspace, XMin=startx, XMax=endx) - num_hist = mtd[inputWS].getNumberHistograms() - if spec_max is None: - spec_max = num_hist - 1 + num_hist = mtd[inputWS].getNumberHistograms() + if spec_max is None: + spec_max = num_hist - 1 # name stem for generated workspace - output_workspace = getWSprefix(inputWS) + 'fury_' + ftype + str(spec_min) + "_to_" + str(spec_max) + output_workspace = getWSprefix(inputWS) + 'fury_' + ftype + str(spec_min) + "_to_" + str(spec_max) - ConvertToHistogram(tmp_fit_workspace, OutputWorkspace=tmp_fit_workspace) - convertToElasticQ(tmp_fit_workspace) + ConvertToHistogram(tmp_fit_workspace, OutputWorkspace=tmp_fit_workspace) + convertToElasticQ(tmp_fit_workspace) #build input string for PlotPeakByLogValue - input_str = [tmp_fit_workspace + ',i%d' % i for i in range(spec_min, spec_max + 1)] - input_str = ';'.join(input_str) + input_str = [tmp_fit_workspace + ',i%d' % i for i in range(spec_min, spec_max + 1)] + input_str = ';'.join(input_str) - PlotPeakByLogValue(Input=input_str, OutputWorkspace=output_workspace, Function=func, + PlotPeakByLogValue(Input=input_str, OutputWorkspace=output_workspace, Function=func, StartX=startx, EndX=endx, FitType='Sequential', CreateOutput=True) #remove unsused workspaces - DeleteWorkspace(output_workspace + '_NormalisedCovarianceMatrices') - DeleteWorkspace(output_workspace + '_Parameters') + DeleteWorkspace(output_workspace + '_NormalisedCovarianceMatrices') + DeleteWorkspace(output_workspace + '_Parameters') - fit_group = output_workspace + '_Workspaces' - params_table = output_workspace + '_Parameters' - RenameWorkspace(output_workspace, OutputWorkspace=params_table) + fit_group = output_workspace + '_Workspaces' + params_table = output_workspace + '_Parameters' + RenameWorkspace(output_workspace, OutputWorkspace=params_table) #create *_Result workspace - result_workspace = output_workspace + "_Result" - parameter_names = ['A0', 'Intensity', 'Tau', 'Beta'] - convertParametersToWorkspace(params_table, "axis-1", parameter_names, result_workspace) + result_workspace = output_workspace + "_Result" + parameter_names = ['A0', 'Intensity', 'Tau', 'Beta'] + convertParametersToWorkspace(params_table, "axis-1", parameter_names, result_workspace) #set x units to be momentum transfer - axis = mtd[result_workspace].getAxis(0) - axis.setUnit("MomentumTransfer") + axis = mtd[result_workspace].getAxis(0) + axis.setUnit("MomentumTransfer") #process generated workspaces - wsnames = mtd[fit_group].getNames() - params = [startx, endx, fit_type] - for i, ws in enumerate(wsnames): - output_ws = output_workspace + '_%d_Workspace' % i - RenameWorkspace(ws, OutputWorkspace=output_ws) + wsnames = mtd[fit_group].getNames() + params = [startx, endx, fit_type] + for i, ws in enumerate(wsnames): + output_ws = output_workspace + '_%d_Workspace' % i + RenameWorkspace(ws, OutputWorkspace=output_ws) - sample_logs = {'start_x': startx, 'end_x': endx, 'fit_type': fit_type, + sample_logs = {'start_x': startx, 'end_x': endx, 'fit_type': fit_type, 'intensities_constrained': intensities_constrained, 'beta_constrained': False} - CopyLogs(InputWorkspace=inputWS, OutputWorkspace=fit_group) - CopyLogs(InputWorkspace=inputWS, OutputWorkspace=result_workspace) + CopyLogs(InputWorkspace=inputWS, OutputWorkspace=fit_group) + CopyLogs(InputWorkspace=inputWS, OutputWorkspace=result_workspace) - addSampleLogs(fit_group, sample_logs) - addSampleLogs(result_workspace, sample_logs) + addSampleLogs(fit_group, sample_logs) + addSampleLogs(result_workspace, sample_logs) - if Save: - save_workspaces = [result_workspace, fit_group] - furyFitSaveWorkspaces(save_workspaces) + if Save: + save_workspaces = [result_workspace, fit_group] + furyFitSaveWorkspaces(save_workspaces) - if Plot != 'None' : - furyfitPlotSeq(result_workspace, Plot) + if Plot != 'None' : + furyfitPlotSeq(result_workspace, Plot) - EndTime('FuryFit') - return result_workspace + EndTime('FuryFit') + return result_workspace def furyfitMult(inputWS, function, ftype, startx, endx, spec_min=0, spec_max=None, intensities_constrained=False, Save=False, Plot='None'): - StartTime('FuryFit Multi') + StartTime('FuryFit Multi') - nHist = mtd[inputWS].getNumberHistograms() - output_workspace = getWSprefix(inputWS) + 'fury_1Smult_s0_to_' + str(nHist-1) + nHist = mtd[inputWS].getNumberHistograms() + output_workspace = getWSprefix(inputWS) + 'fury_1Smult_s0_to_' + str(nHist-1) - option = ftype[:-2] - logger.information('Option: '+option) - logger.information('Function: '+function) + option = ftype[:-2] + logger.information('Option: '+option) + logger.information('Function: '+function) #prepare input workspace for fitting - tmp_fit_workspace = "__furyfit_fit_ws" - if spec_max is None: - CropWorkspace(InputWorkspace=inputWS, OutputWorkspace=tmp_fit_workspace, XMin=startx, XMax=endx, + tmp_fit_workspace = "__furyfit_fit_ws" + if spec_max is None: + CropWorkspace(InputWorkspace=inputWS, OutputWorkspace=tmp_fit_workspace, XMin=startx, XMax=endx, StartWorkspaceIndex=spec_min) - else: - CropWorkspace(InputWorkspace=inputWS, OutputWorkspace=tmp_fit_workspace, XMin=startx, XMax=endx, + else: + CropWorkspace(InputWorkspace=inputWS, OutputWorkspace=tmp_fit_workspace, XMin=startx, XMax=endx, StartWorkspaceIndex=spec_min, EndWorkspaceIndex=spec_max) - ConvertToHistogram(tmp_fit_workspace, OutputWorkspace=tmp_fit_workspace) - convertToElasticQ(tmp_fit_workspace) + ConvertToHistogram(tmp_fit_workspace, OutputWorkspace=tmp_fit_workspace) + convertToElasticQ(tmp_fit_workspace) #fit multi-domian functino to workspace - multi_domain_func, kwargs = createFuryMultiDomainFunction(function, tmp_fit_workspace) - Fit(Function=multi_domain_func, InputWorkspace=tmp_fit_workspace, WorkspaceIndex=0, + multi_domain_func, kwargs = createFuryMultiDomainFunction(function, tmp_fit_workspace) + Fit(Function=multi_domain_func, InputWorkspace=tmp_fit_workspace, WorkspaceIndex=0, Output=output_workspace, CreateOutput=True, **kwargs) - params_table = output_workspace + '_Parameters' - transposeFitParametersTable(params_table) + params_table = output_workspace + '_Parameters' + transposeFitParametersTable(params_table) #set first column of parameter table to be axis values - ax = mtd[tmp_fit_workspace].getAxis(1) - axis_values = ax.extractValues() - for i, value in enumerate(axis_values): - mtd[params_table].setCell('axis-1', i, value) + ax = mtd[tmp_fit_workspace].getAxis(1) + axis_values = ax.extractValues() + for i, value in enumerate(axis_values): + mtd[params_table].setCell('axis-1', i, value) #convert parameters to matrix workspace - result_workspace = output_workspace + "_Result" - parameter_names = ['A0', 'Intensity', 'Tau', 'Beta'] - convertParametersToWorkspace(params_table, "axis-1", parameter_names, result_workspace) + result_workspace = output_workspace + "_Result" + parameter_names = ['A0', 'Intensity', 'Tau', 'Beta'] + convertParametersToWorkspace(params_table, "axis-1", parameter_names, result_workspace) #set x units to be momentum transfer - axis = mtd[result_workspace].getAxis(0) - axis.setUnit("MomentumTransfer") + axis = mtd[result_workspace].getAxis(0) + axis.setUnit("MomentumTransfer") - result_workspace = output_workspace + '_Result' - fit_group = output_workspace + '_Workspaces' + result_workspace = output_workspace + '_Result' + fit_group = output_workspace + '_Workspaces' - sample_logs = {'start_x': startx, 'end_x': endx, 'fit_type': ftype, + sample_logs = {'start_x': startx, 'end_x': endx, 'fit_type': ftype, 'intensities_constrained': intensities_constrained, 'beta_constrained': True} - CopyLogs(InputWorkspace=inputWS, OutputWorkspace=result_workspace) - CopyLogs(InputWorkspace=inputWS, OutputWorkspace=fit_group) + CopyLogs(InputWorkspace=inputWS, OutputWorkspace=result_workspace) + CopyLogs(InputWorkspace=inputWS, OutputWorkspace=fit_group) - addSampleLogs(result_workspace, sample_logs) - addSampleLogs(fit_group, sample_logs) + addSampleLogs(result_workspace, sample_logs) + addSampleLogs(fit_group, sample_logs) - DeleteWorkspace(tmp_fit_workspace) + DeleteWorkspace(tmp_fit_workspace) - if Save: - save_workspaces = [result_workspace] - furyFitSaveWorkspaces(save_workspaces) + if Save: + save_workspaces = [result_workspace] + furyFitSaveWorkspaces(save_workspaces) - if Plot != 'None': - furyfitPlotSeq(result_workspace, Plot) + if Plot != 'None': + furyfitPlotSeq(result_workspace, Plot) - EndTime('FuryFit Multi') - return result_workspace + EndTime('FuryFit Multi') + return result_workspace def createFuryMultiDomainFunction(function, input_ws): - multi= 'composite=MultiDomainFunction,NumDeriv=1;' - comp = '(composite=CompositeFunction,$domains=i;' + function + ');' + multi= 'composite=MultiDomainFunction,NumDeriv=1;' + comp = '(composite=CompositeFunction,$domains=i;' + function + ');' - ties = [] - kwargs = {} - num_spectra = mtd[input_ws].getNumberHistograms() - for i in range(0, num_spectra): - multi += comp - kwargs['WorkspaceIndex_' + str(i)] = i + ties = [] + kwargs = {} + num_spectra = mtd[input_ws].getNumberHistograms() + for i in range(0, num_spectra): + multi += comp + kwargs['WorkspaceIndex_' + str(i)] = i - if i > 0: - kwargs['InputWorkspace_' + str(i)] = input_ws + if i > 0: + kwargs['InputWorkspace_' + str(i)] = input_ws #tie beta for every spectrum - tie = 'f%d.f1.Beta=f0.f1.Beta' % i - ties.append(tie) + tie = 'f%d.f1.Beta=f0.f1.Beta' % i + ties.append(tie) - ties = ','.join(ties) - multi += 'ties=(' + ties + ')' + ties = ','.join(ties) + multi += 'ties=(' + ties + ')' - return multi, kwargs + return multi, kwargs def furyFitSaveWorkspaces(save_workspaces): - workdir = getDefaultWorkingDirectory() - for ws in save_workspaces: + workdir = getDefaultWorkingDirectory() + for ws in save_workspaces: #save workspace to default directory - fpath = os.path.join(workdir, ws+'.nxs') - SaveNexusProcessed(InputWorkspace=ws, Filename=fpath) - logger.information(ws + ' output to file : '+fpath) + fpath = os.path.join(workdir, ws+'.nxs') + SaveNexusProcessed(InputWorkspace=ws, Filename=fpath) + logger.information(ws + ' output to file : '+fpath) def furyfitPlotSeq(ws, plot): diff --git a/Code/Mantid/scripts/Inelastic/IndirectMuscat.py b/Code/Mantid/scripts/Inelastic/IndirectMuscat.py index e20601e39e48..379505207530 100644 --- a/Code/Mantid/scripts/Inelastic/IndirectMuscat.py +++ b/Code/Mantid/scripts/Inelastic/IndirectMuscat.py @@ -18,19 +18,19 @@ def CalcW0(nq,dq,disp,coeff): w0 = [] e0 = [] for n in range(0,nq): - q0 = (n+1)*dq - Q.append(q0) - q02 = q0*q0 - Q2.append(q02) - if (disp == 'Poly'): - w = coeff[0]+coeff[1]*q0+coeff[2]*q02+coeff[3]*q0*q02+coeff[4]*q02*q02 - if (disp == 'CE'): - qk = coeff[1]*q0 - w = coeff[0]*(1.0-math.sin(qk)/qk) - if (disp == 'SS'): - w0 = coeff[0]*(1.0-math.exp(coeff[1]*q02)) - w0.append(w*0.001) #convert from mmeV to meV - e0.append(0.0) + q0 = (n+1)*dq + Q.append(q0) + q02 = q0*q0 + Q2.append(q02) + if (disp == 'Poly'): + w = coeff[0]+coeff[1]*q0+coeff[2]*q02+coeff[3]*q0*q02+coeff[4]*q02*q02 + if (disp == 'CE'): + qk = coeff[1]*q0 + w = coeff[0]*(1.0-math.sin(qk)/qk) + if (disp == 'SS'): + w0 = coeff[0]*(1.0-math.exp(coeff[1]*q02)) + w0.append(w*0.001) #convert from mmeV to meV + e0.append(0.0) return Q,w0,e0 def CalcSqw(q0,nw2,nel,dw,w0): @@ -41,66 +41,66 @@ def CalcSqw(q0,nw2,nel,dw,w0): nq = len(q0) Qaxis = '' for i in range(0,nq): - ww0 = w0[i] - for j in range(0,nw2): + ww0 = w0[i] + for j in range(0,nw2): # S(I,J)=S(I,J)+PKHT*W0(I)/(W0(I)**2+W**2) !Lorentzian S(Q,w) - ww = (j-nel)*dw - xSqw.append(ww) #convert to microeV - ss = PKHT*ww0/(ww0**2+ww**2) - ySqw.append(ss) - eSqw.append(0.0) - if i == 0: - Qaxis += str(q0[i]) - else: - Qaxis += ','+str(q0[i]) + ww = (j-nel)*dw + xSqw.append(ww) #convert to microeV + ss = PKHT*ww0/(ww0**2+ww**2) + ySqw.append(ss) + eSqw.append(0.0) + if i == 0: + Qaxis += str(q0[i]) + else: + Qaxis += ','+str(q0[i]) CreateWorkspace(OutputWorkspace='S(Q,w)', DataX=xSqw, DataY=ySqw, DataE=eSqw, Nspec=nq, UnitX='DeltaE', VerticalAxisUnit='MomentumTransfer', VerticalAxisValues=Qaxis) def CheckCoeff(disp,coeff): if (disp == 'CE') or (disp == 'SS'): - if coeff[0] < 1e-8: - error = disp + ' coeff 1 is zero' - logger.notice('ERROR *** '+error) - sys.exit(error) - if coeff[1] < 1e-8: - error = disp + ' coeff 2 is zero' - logger.notice('ERROR *** '+error) - sys.exit(error) + if coeff[0] < 1e-8: + error = disp + ' coeff 1 is zero' + logger.notice('ERROR *** '+error) + sys.exit(error) + if coeff[1] < 1e-8: + error = disp + ' coeff 2 is zero' + logger.notice('ERROR *** '+error) + sys.exit(error) if (disp == 'Poly'): - cc = coeff[0]+coeff[1]+coeff[2]+coeff[3]+coeff[4] - if cc < 1e-8: - error = 'Poly coeffs all zero' - logger.notice('ERROR *** '+error) - sys.exit(error) + cc = coeff[0]+coeff[1]+coeff[2]+coeff[3]+coeff[4] + if cc < 1e-8: + error = 'Poly coeffs all zero' + logger.notice('ERROR *** '+error) + sys.exit(error) def CheckQw(grid): nq = grid[0] if nq == 0: - error = 'Grid : Number of Q values is zero' - logger.notice('ERROR *** '+error) - sys.exit(error) + error = 'Grid : Number of Q values is zero' + logger.notice('ERROR *** '+error) + sys.exit(error) nw = grid[2] if nw == 0: - error = 'Grid : Number of w values is zero' - logger.notice('ERROR *** '+error) - sys.exit(error) + error = 'Grid : Number of w values is zero' + logger.notice('ERROR *** '+error) + sys.exit(error) dq = grid[1] if dq < 1e-5: - error = 'Grid : Q increment is zero' - logger.notice('ERROR *** '+error) - sys.exit(error) + error = 'Grid : Q increment is zero' + logger.notice('ERROR *** '+error) + sys.exit(error) dw = grid[3]*0.001 if dw < 1e-8: - error = 'Grid : w increment is zero' - logger.notice('ERROR *** '+error) - sys.exit(error) + error = 'Grid : w increment is zero' + logger.notice('ERROR *** '+error) + sys.exit(error) return nq,dq,nw,dw def CreateSqw(disp,coeff,grid,Verbose): CheckCoeff(disp,coeff) if Verbose: - logger.notice('Dispersion is '+disp) - logger.notice('Coefficients : '+str(coeff)) + logger.notice('Dispersion is '+disp) + logger.notice('Coefficients : '+str(coeff)) nq,dq,nw,dw = CheckQw(grid) q0,w0,e0 = CalcW0(nq,dq,disp,coeff) CreateWorkspace(OutputWorkspace=disp, DataX=q0, DataY=w0, DataE=e0, @@ -115,77 +115,77 @@ def ReadSqw(sqw,Verbose): axis = mtd[sqw].getAxis(1) Q = [] for i in range(0,nq): - Q.append(float(axis.label(i))) + Q.append(float(axis.label(i))) Q_in = PadArray(Q,500) Sqw_in = [] for n in range(0,nq): - Xw = mtd[sqw].readX(n) # energy array - Ys = mtd[sqw].readY(n) # S(q,w) values - Ys = PadArray(Ys,1000) # pad to Fortran energy size 1000 - Sqw_in.append(Ys) + Xw = mtd[sqw].readX(n) # energy array + Ys = mtd[sqw].readY(n) # S(q,w) values + Ys = PadArray(Ys,1000) # pad to Fortran energy size 1000 + Sqw_in.append(Ys) dw = Xw[2]-Xw[1] if dw < 1e-8: - error = 'Sqw : w increment is zero' - logger.notice('ERROR *** '+error) - sys.exit(error) + error = 'Sqw : w increment is zero' + logger.notice('ERROR *** '+error) + sys.exit(error) nel= nw+1 for n in range(0,nw): - if (Xw[n] < dw): - nel = n + if (Xw[n] < dw): + nel = n dq = Q[1]-Q[0] if dq < 1e-5: - error = 'Sqw : Q increment is zero' - logger.notice('ERROR *** '+error) - sys.exit(error) + error = 'Sqw : Q increment is zero' + logger.notice('ERROR *** '+error) + sys.exit(error) if Verbose: - logger.notice('Q : '+str(nq)+' points from '+str(Q[0])+' to '+str(Q[nq-1])+' at '+str(dq)) - logger.notice('w : '+str(nw)+' points from '+str(Xw[0])+' to '+str(Xw[nw])+' at '+str(dw) + logger.notice('Q : '+str(nq)+' points from '+str(Q[0])+' to '+str(Q[nq-1])+' at '+str(dq)) + logger.notice('w : '+str(nw)+' points from '+str(Xw[0])+' to '+str(Xw[nw])+' at '+str(dw) +' ; Elastic energy at : '+str(nel)) X0 = [] X0 = PadArray(X0,1000) # zeroes for n in range(nq,500): # pad to Fortran Q size 500 - Sqw_in.append(X0) + Sqw_in.append(X0) return nq,dq,Q_in,nw,dw,nel,Xw,Sqw_in def CheckNeut(neut): # neut = [NRUN1, NRUN2, JRAND, MRAND, NMST] if neut[0] == 0: - error = 'NRUN1 is Zero' - logger.notice('ERROR *** ' + error) - sys.exit(error) + error = 'NRUN1 is Zero' + logger.notice('ERROR *** ' + error) + sys.exit(error) if neut[1] == 0: - error = 'NRUN2 is Zero' - logger.notice('ERROR *** ' + error) - sys.exit(error) + error = 'NRUN2 is Zero' + logger.notice('ERROR *** ' + error) + sys.exit(error) if neut[4] == 0: - error = 'Number scatterings is Zero' - logger.notice('ERROR *** ' + error) - sys.exit(error) + error = 'Number scatterings is Zero' + logger.notice('ERROR *** ' + error) + sys.exit(error) def CheckBeam(beam): # beam = [THICK, WIDTH, HEIGHT, alfa] if beam[0] <1e-5: - error = 'Beam thickness is Zero' - logger.notice('ERROR *** ' + error) - sys.exit(error) + error = 'Beam thickness is Zero' + logger.notice('ERROR *** ' + error) + sys.exit(error) if beam[1] <1e-5: - error = 'Beam width is Zero' - logger.notice('ERROR *** ' + error) - sys.exit(error) + error = 'Beam width is Zero' + logger.notice('ERROR *** ' + error) + sys.exit(error) if beam[2] <1e-5: - error = 'Beam height is Zero' - logger.notice('ERROR *** ' + error) - sys.exit(error) + error = 'Beam height is Zero' + logger.notice('ERROR *** ' + error) + sys.exit(error) def CheckSam(sam): if sam[1] <1e-8: - error = 'Sample density is Zero' - logger.notice('ERROR *** ' + error) - sys.exit(error) + error = 'Sample density is Zero' + logger.notice('ERROR *** ' + error) + sys.exit(error) if (sam[2]+sam[3]) <1e-8: - error = 'Sample total scattering cross-section (scat+abs) is Zero' - logger.notice('ERROR *** ' + error) - sys.exit(error) + error = 'Sample total scattering cross-section (scat+abs) is Zero' + logger.notice('ERROR *** ' + error) + sys.exit(error) def MuscatRun(sname,geom,neut,beam,sam,sqw,kr1,Verbose,Plot,Save): # neut = [NRUN1, NRUN2, JRAND, MRAND, NMST] @@ -203,23 +203,23 @@ def MuscatRun(sname,geom,neut,beam,sam,sqw,kr1,Verbose,Plot,Save): # ijeom = [jeom, Jann] Jann = 1 if geom == 'Flat': - ijeom = [2, Jann] + ijeom = [2, Jann] if geom == 'Cyl': - ijeom = [3, Jann] + ijeom = [3, Jann] # rgeom = [thick, width, height] rgeom = [beam[0], beam[1], beam[2]] nran = [neut[0], neut[1], neut[2], neut[3]] lpt = os.path.join(workdir, sname[:-3]+geom+'_ms.lpt') # path name for lpt file if Verbose: - logger.notice('Detectors/angles : '+str(mang)) - logger.notice('Sample geometry : '+geom) - logger.notice('Sample parameters') - logger.notice(' sigs = '+str(sam[3])+' ; siga = '+str(sam[1])+' ; rho = '+str(sam[0])) - if geom == 'Cyl': - logger.notice(' inner radius = '+str(beam[0])+' ; outer radius = '+str(beam[1])) - if geom == 'Flat': - logger.notice(' thickness = '+str(beam[0])) - logger.notice('Output lptfile : ' + lpt) + logger.notice('Detectors/angles : '+str(mang)) + logger.notice('Sample geometry : '+geom) + logger.notice('Sample parameters') + logger.notice(' sigs = '+str(sam[3])+' ; siga = '+str(sam[1])+' ; rho = '+str(sam[0])) + if geom == 'Cyl': + logger.notice(' inner radius = '+str(beam[0])+' ; outer radius = '+str(beam[1])) + if geom == 'Flat': + logger.notice(' thickness = '+str(beam[0])) + logger.notice('Output lptfile : ' + lpt) llpt = len(lpt) lpt.ljust(140,' ') lsqw = len(sqw) @@ -235,49 +235,49 @@ def MuscatRun(sname,geom,neut,beam,sam,sqw,kr1,Verbose,Plot,Save): Qaxis = '' for m in range(0,mang): # rinstr = [efixed, theta, alfa] - rinstr = [efixed, angle[m], beam[3]] - logger.notice('Detector ' +str(m+1)+ ' at angle ' +str(angle[m])+ ' and Q = ' +str(QQ[m])) + rinstr = [efixed, angle[m], beam[3]] + logger.notice('Detector ' +str(m+1)+ ' at angle ' +str(angle[m])+ ' and Q = ' +str(QQ[m])) # SUBROUTINE MUSCAT_data(IDET,sfile,l_sf,rfile,l_rf,rinstr,nran, # 1 ijeom,rgeom,sam,ims,dqw,Q_in,S_in, # 2 totals,iw,energy,scat1,scatm,RR,S_out) - idet = m+1 - kill,totals,iw,energy,scat1,scatm,RR,Sqw=muscat.muscat_data(idet,lpt,llpt,sqw,lsqw,rinstr,nran, + idet = m+1 + kill,totals,iw,energy,scat1,scatm,RR,Sqw=muscat.muscat_data(idet,lpt,llpt,sqw,lsqw,rinstr,nran, ijeom,rgeom,sam,ims,dqw,Q_in,Sqw_in) - if (kill != 0): - error = 'Muscat error code : '+str(kill) - logger.notice(error) - sys.exit(error) - else: - xEn = energy[:iw] - xEn = np.append(xEn,2*energy[iw-1]-energy[iw-2]) - ySc1 = scat1[:iw] # single scattering energy distribution - yScM = scatm[:iw] # total scattering energy distribution - yRr = RR[:iw] # R-factor energy distribution - if m == 0: - tot1 = np.array(totals[1]) # total single scattering - tot2 = np.array(totals[2]) # total second scattering - tot3 = np.array(totals[3]) # total third scattering - total = np.array(totals[4]) # total all scattering - xMs = xEn - yMsc1 = ySc1 - yMscM = yScM - yMr = yRr - else: - tot1 = np.append(tot1,totals[1]) - tot2 = np.append(tot2,totals[2]) - tot3 = np.append(tot3,totals[3]) - total = np.append(total,totals[4]) - xMs = np.append(xMs,xEn) - yMsc1 = np.append(yMsc1,ySc1) - yMscM = np.append(yMscM,yScM) - yMr = np.append(yMr,yRr) - Qaxis += ',' - Qaxis += str(QQ[m]) + if (kill != 0): + error = 'Muscat error code : '+str(kill) + logger.notice(error) + sys.exit(error) + else: + xEn = energy[:iw] + xEn = np.append(xEn,2*energy[iw-1]-energy[iw-2]) + ySc1 = scat1[:iw] # single scattering energy distribution + yScM = scatm[:iw] # total scattering energy distribution + yRr = RR[:iw] # R-factor energy distribution + if m == 0: + tot1 = np.array(totals[1]) # total single scattering + tot2 = np.array(totals[2]) # total second scattering + tot3 = np.array(totals[3]) # total third scattering + total = np.array(totals[4]) # total all scattering + xMs = xEn + yMsc1 = ySc1 + yMscM = yScM + yMr = yRr + else: + tot1 = np.append(tot1,totals[1]) + tot2 = np.append(tot2,totals[2]) + tot3 = np.append(tot3,totals[3]) + total = np.append(total,totals[4]) + xMs = np.append(xMs,xEn) + yMsc1 = np.append(yMsc1,ySc1) + yMscM = np.append(yMscM,yScM) + yMr = np.append(yMr,yRr) + Qaxis += ',' + Qaxis += str(QQ[m]) # start output of Totals totx = [angle[0]] tote = np.zeros(mang) for m in range(1,mang): - totx = np.append(totx,angle[m]) + totx = np.append(totx,angle[m]) nt = 1 Taxis = 'Scat1' xTot = totx @@ -285,19 +285,19 @@ def MuscatRun(sname,geom,neut,beam,sam,sqw,kr1,Verbose,Plot,Save): eTot = tote spec_list = [nt-1] if nmst > 1: - nt += 1 - spec_list.append(nt-1) - Taxis += ',Scat2' - xTot = np.append(xTot,totx) - yTot = np.append(yTot,tot2) - eTot = np.append(eTot,tote) - if nmst > 2: - nt += 1 - spec_list.append(nt-1) - Taxis += ',Scat3' - xTot = np.append(xTot,totx) - yTot = np.append(yTot,tot3) - eTot = np.append(eTot,tote) + nt += 1 + spec_list.append(nt-1) + Taxis += ',Scat2' + xTot = np.append(xTot,totx) + yTot = np.append(yTot,tot2) + eTot = np.append(eTot,tote) + if nmst > 2: + nt += 1 + spec_list.append(nt-1) + Taxis += ',Scat3' + xTot = np.append(xTot,totx) + yTot = np.append(yTot,tot3) + eTot = np.append(eTot,tote) xTot = np.append(xTot,totx) yTot = np.append(yTot,total) eTot = np.append(eTot,tote) @@ -325,15 +325,15 @@ def MuscatRun(sname,geom,neut,beam,sam,sqw,kr1,Verbose,Plot,Save): GroupWorkspaces(InputWorkspaces=group,OutputWorkspace=msname+'_Scat') # start output if Save: - tot_path = os.path.join(workdir,msname+'_Totals.nxs') - SaveNexusProcessed(InputWorkspace=msname+'_Totals', Filename=tot_path) - scat_path = os.path.join(workdir,msname+'_Scat.nxs') - SaveNexusProcessed(InputWorkspace=msname+'_Scat', Filename=scat_path) - if Verbose: - logger.notice('Output total scattering file : ' + tot_path) - logger.notice('Output MS scattering file : ' + scat_path) + tot_path = os.path.join(workdir,msname+'_Totals.nxs') + SaveNexusProcessed(InputWorkspace=msname+'_Totals', Filename=tot_path) + scat_path = os.path.join(workdir,msname+'_Scat.nxs') + SaveNexusProcessed(InputWorkspace=msname+'_Scat', Filename=scat_path) + if Verbose: + logger.notice('Output total scattering file : ' + tot_path) + logger.notice('Output MS scattering file : ' + scat_path) if Plot: - plotMuscat(msname,spec_list,Plot) + plotMuscat(msname,spec_list,Plot) def MuscatFuncStart(sname,geom,neut,beam,sam,grid,disp,coeff,kr1,Verbose,Plot,Save): StartTime('Muscat Function') @@ -344,8 +344,8 @@ def MuscatFuncStart(sname,geom,neut,beam,sam,grid,disp,coeff,kr1,Verbose,Plot,Sa sqw = 'S(Q,w)' CreateSqw(disp,coeff,grid,Verbose) if Verbose: - logger.notice('Sample run : '+spath) - logger.notice('S(Q,w) from : '+disp) + logger.notice('Sample run : '+spath) + logger.notice('S(Q,w) from : '+disp) MuscatRun(sname,geom,neut,beam,sam,sqw,kr1,Verbose,Plot,Save) EndTime('Muscat Function') @@ -359,13 +359,13 @@ def MuscatDataStart(sname,geom,neut,beam,sam,sqw,kr1,Verbose,Plot,Save): qpath = os.path.join(workdir, sqw+'.nxs') # path name for S(Q,w) nxs file LoadNexusProcessed(FileName=qpath, OutputWorkspace=sqw) if Verbose: - logger.notice('Sample run : '+spath) - logger.notice('S(Q,w) file : '+qpath) + logger.notice('Sample run : '+spath) + logger.notice('S(Q,w) file : '+qpath) MuscatRun(sname,geom,neut,beam,sam,sqw,kr1,Verbose,Plot,Save) EndTime('Muscat Data') def plotMuscat(inWS,spec_list,Plot): if (Plot == 'Totals' or Plot == 'All'): - tot_plot=mp.plotSpectrum(inWS+'_Totals',spec_list) + tot_plot=mp.plotSpectrum(inWS+'_Totals',spec_list) if (Plot == 'Scat1' or Plot == 'All'): - mp.importMatrixWorkspace(inWS+'_1').plotGraph2D() + mp.importMatrixWorkspace(inWS+'_1').plotGraph2D() diff --git a/Code/Mantid/scripts/Inelastic/inelastic_indirect_reduction_steps.py b/Code/Mantid/scripts/Inelastic/inelastic_indirect_reduction_steps.py index 40e79d977176..761a14e289ee 100644 --- a/Code/Mantid/scripts/Inelastic/inelastic_indirect_reduction_steps.py +++ b/Code/Mantid/scripts/Inelastic/inelastic_indirect_reduction_steps.py @@ -119,11 +119,11 @@ def _load_single_file(self, filename, output_ws): basis_mask_filename = os.path.join(config.getString('maskFiles.directory') , basis_mask) if os.path.isfile(basis_mask_filename): - LoadMask(Instrument="BASIS", OutputWorkspace="__basis_mask", + LoadMask(Instrument="BASIS", OutputWorkspace="__basis_mask", InputFile=basis_mask_filename) - MaskDetectors(Workspace=output_ws, MaskedWorkspace="__basis_mask") + MaskDetectors(Workspace=output_ws, MaskedWorkspace="__basis_mask") else: - logger.notice("Couldn't find specified mask file : " + str(basis_mask_filename)) + logger.notice("Couldn't find specified mask file : " + str(basis_mask_filename)) if self._parameter_file != None: LoadParameterFile(Workspace=output_ws,Filename= self._parameter_file) @@ -824,7 +824,7 @@ def _group_data(self, workspace): for i in range(0, nhist): if i not in self._masking_detectors: wslist.append(i) - GroupDetectors(InputWorkspace=workspace, OutputWorkspace=workspace, + GroupDetectors(InputWorkspace=workspace, OutputWorkspace=workspace, WorkspaceIndexList=wslist, Behaviour='Average') else: # We may have either a workspace name or a mapping file name here @@ -852,10 +852,10 @@ def _group_data(self, workspace): # Run GroupDetectors with a workspace if we have one # Otherwise try to run it with a mapping file if grouping_workspace is not None: - GroupDetectors(InputWorkspace=workspace, OutputWorkspace=workspace, CopyGroupingFromWorkspace=grouping_workspace, + GroupDetectors(InputWorkspace=workspace, OutputWorkspace=workspace, CopyGroupingFromWorkspace=grouping_workspace, Behaviour='Average') elif os.path.isfile(grouping_filename): - GroupDetectors(InputWorkspace=workspace, OutputWorkspace=workspace, MapFile=grouping_filename, + GroupDetectors(InputWorkspace=workspace, OutputWorkspace=workspace, MapFile=grouping_filename, Behaviour='Average') return workspace diff --git a/Code/Mantid/scripts/Inelastic/msg_reducer.py b/Code/Mantid/scripts/Inelastic/msg_reducer.py index 2f06d44cee44..e240f2929907 100644 --- a/Code/Mantid/scripts/Inelastic/msg_reducer.py +++ b/Code/Mantid/scripts/Inelastic/msg_reducer.py @@ -42,7 +42,7 @@ def pre_process(self): loadData.set_parameter_file(self._parameter_file) loadData.set_extra_load_opts(self._extra_load_opts) loadData.execute(self, None) - + if loadData.contains_event_data and (self._rebin_string is None or self._rebin_string is ''): logger.warning('Reductins of event data without rebinning may give bad data!') @@ -111,7 +111,7 @@ def set_parameter_file(self, file_name): for directory in config.getInstrumentDirectories(): if os.path.isfile(os.path.join(directory, file_name)): self._parameter_file = os.path.join(directory, file_name) - return + return def set_rebin_string(self, rebin): """Sets the rebin string to be used with the Rebin algorithm. diff --git a/Code/Mantid/scripts/Interface/compile_refm_ui.py b/Code/Mantid/scripts/Interface/compile_refm_ui.py index f73ec768ea6f..6d730cffcce1 100755 --- a/Code/Mantid/scripts/Interface/compile_refm_ui.py +++ b/Code/Mantid/scripts/Interface/compile_refm_ui.py @@ -15,4 +15,4 @@ compile_ui("ui/reflectometer/refl_stitching.ui") except: - print "Could not compile resource file" \ No newline at end of file + print "Could not compile resource file" diff --git a/Code/Mantid/scripts/Interface/compile_sans_ui.py b/Code/Mantid/scripts/Interface/compile_sans_ui.py index 1a7b3f1b7367..d7a8e65a946f 100644 --- a/Code/Mantid/scripts/Interface/compile_sans_ui.py +++ b/Code/Mantid/scripts/Interface/compile_sans_ui.py @@ -29,4 +29,4 @@ os.system("pyuic4 -o ui/ui_data_catalog.py ui/data_catalog.ui") os.system("pyuic4 -o ui/ui_stitcher.py ui/stitcher.ui") except: - print "Could not compile resource file" \ No newline at end of file + print "Could not compile resource file" diff --git a/Code/Mantid/scripts/Interface/reduction_application.py b/Code/Mantid/scripts/Interface/reduction_application.py index 79bb187d52a0..817cbe20fbc0 100644 --- a/Code/Mantid/scripts/Interface/reduction_application.py +++ b/Code/Mantid/scripts/Interface/reduction_application.py @@ -91,7 +91,7 @@ def __init__(self, instrument=None, instrument_list=None): self._compute_resources = ['Fermi'] if IS_IN_MANTIDPLOT \ and hasattr(ConfigService.Instance().getFacility(), "computeResources"): - self._compute_resources = ConfigService.Instance().getFacility().computeResources() + self._compute_resources = ConfigService.Instance().getFacility().computeResources() # Internal flag for clearing all settings and restarting the application self._clear_and_restart = False diff --git a/Code/Mantid/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_reduction_script.py b/Code/Mantid/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_reduction_script.py index cd18ffcf104d..6c7ed3e36314 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_reduction_script.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_reduction_script.py @@ -27,7 +27,7 @@ def __init__(self, name="VULCAN", facility="SNS"): """ Initialization """ super(DiffractionReductionScripter, self).__init__(name=name, facility=facility) - + print "[diffraction_reduction_script] Facility = %s, Instrument = %s" % (self.facility_name, self.instrument_name) return diff --git a/Code/Mantid/scripts/Interface/reduction_gui/reduction/inelastic/dgs_utils.py b/Code/Mantid/scripts/Interface/reduction_gui/reduction/inelastic/dgs_utils.py index 360c9ad69c72..c74a606fe121 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/reduction/inelastic/dgs_utils.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/reduction/inelastic/dgs_utils.py @@ -53,7 +53,7 @@ def get_parameter(self, name): if val[0] == "None" : return None elif type_name == "int" : - val = self._instrument.getIntParameter(name) + val = self._instrument.getIntParameter(name) else : return default try: diff --git a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/data_cat.py b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/data_cat.py index 387831efd38d..efe57b2e28cb 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/data_cat.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/data_cat.py @@ -175,7 +175,7 @@ def __init__(self, replace_db=True): self.db = None try: - self._create_db(db_path, replace_db) + self._create_db(db_path, replace_db) except: print "DataCatalog: Could not access local data catalog\n%s" % sys.exc_value diff --git a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/eqsans_catalog.py b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/eqsans_catalog.py index 9311c309a351..69bf588ea991 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/eqsans_catalog.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/eqsans_catalog.py @@ -113,4 +113,4 @@ class DataCatalog(BaseCatalog): data_set_cls = EQSANSDataSet def __init__(self, replace_db=False): - super(DataCatalog, self).__init__(replace_db) \ No newline at end of file + super(DataCatalog, self).__init__(replace_db) diff --git a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/eqsans_data_script.py b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/eqsans_data_script.py index 1371b7028761..0354545a3284 100755 --- a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/eqsans_data_script.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/eqsans_data_script.py @@ -55,4 +55,4 @@ def from_setup_info(self, xml_str): """ self.reset() super(DataSets, self).from_setup_info(xml_str) - self.background.from_setup_info(xml_str) \ No newline at end of file + self.background.from_setup_info(xml_str) diff --git a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/eqsans_options_script.py b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/eqsans_options_script.py index 2eaf8c2d5191..77425493d07e 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/eqsans_options_script.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/eqsans_options_script.py @@ -31,10 +31,10 @@ class ReductionOptions(BaseOptions): # Perform EQSANS TOF correction perform_TOF_correction = True - + # Turn off the wedges n_wedges = 0 - + # Turn off log binning alignment with decades align_log_with_decades = False diff --git a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/hfir_catalog.py b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/hfir_catalog.py index 216e9ec3c250..dbb7fd0a4d7e 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/hfir_catalog.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/hfir_catalog.py @@ -94,4 +94,4 @@ class DataCatalog(BaseCatalog): data_set_cls = HFIRDataSet def __init__(self, replace_db=False): - super(DataCatalog, self).__init__(replace_db) \ No newline at end of file + super(DataCatalog, self).__init__(replace_db) diff --git a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/hfir_options_script.py b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/hfir_options_script.py index 76ef9527bc49..41d57b666ce3 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/hfir_options_script.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/hfir_options_script.py @@ -40,12 +40,12 @@ class ReductionOptions(BaseScriptElement): log_binning = False align_log_with_decades = True error_weighting = False - + # Wedges n_wedges = 2 wedge_angle = 30.0 wedge_offset = 0.0 - + # Mask side masked_side = None @@ -126,13 +126,13 @@ def to_script(self): if self.align_log_with_decades: script += ", align_log_with_decades=%s" % str(self.align_log_with_decades) if self.error_weighting: script += ", error_weighting=%s" % str(self.error_weighting) script += ")\n" - + # If we align we decades, use more points for I(qx,qy) n_xy_bins = self.n_q_bins if self.log_binning and self.align_log_with_decades: n_xy_bins = int(3*self.n_q_bins) script += "IQxQy(nbins=%g)\n" % n_xy_bins - + if self.n_wedges>0: script += "SetWedges(number_of_wedges=%g, wedge_angle=%g, wedge_offset=%g)\n" % (self.n_wedges, self.wedge_angle, self.wedge_offset) @@ -198,7 +198,7 @@ def to_xml(self): xml += " %g\n" % self.n_wedges xml += " %g\n" % self.wedge_angle xml += " %g\n" % self.wedge_offset - + xml += " %d\n" % self.normalization # Output directory @@ -212,7 +212,7 @@ def to_xml(self): xml += " %g\n" % self.bottom xml += " %g\n" % self.left xml += " %g\n" % self.right - + xml += " %s\n" % str(self.masked_side) xml += " \n" @@ -452,7 +452,7 @@ def reset(self): self.log_binning = ReductionOptions.log_binning self.align_log_with_decades = ReductionOptions.align_log_with_decades self.error_weighting = ReductionOptions.error_weighting - + self.n_wedges = ReductionOptions.n_wedges self.wedge_angle = ReductionOptions.wedge_angle self.wedge_offset = ReductionOptions.wedge_offset diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/base_ref_reduction.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/base_ref_reduction.py index f8105395e8d8..ea4b764e7f2a 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/base_ref_reduction.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/base_ref_reduction.py @@ -383,14 +383,14 @@ def weightedMean(self, data_array, error_array): sz = len(data_array) # calculate the numerator of mean - dataNum = 0; + dataNum = 0 for i in range(sz): if not (data_array[i] == 0): tmpFactor = float(data_array[i]) / float((pow(error_array[i],2))) dataNum += tmpFactor # calculate denominator - dataDen = 0; + dataDen = 0 for i in range(sz): if not (error_array[i] == 0): tmpFactor = 1./float((pow(error_array[i],2))) @@ -444,7 +444,7 @@ def _average_y_of_same_x_(self): for j in range(len(data_y_i)): if data_y[j]>0 and data_y_i[j]>0: - [data_y[j], data_e[j]] = self.weightedMean([data_y[j], data_y_i[j]], [data_e[j], data_e_i[j]]); + [data_y[j], data_e[j]] = self.weightedMean([data_y[j], data_y_i[j]], [data_e[j], data_e_i[j]]) elif (data_y[j] == 0) and (data_y_i[j]>0): data_y[j] = data_y_i[j] data_e[j] = data_e_i[j] @@ -973,7 +973,7 @@ def _plot_count_vs_y(self, is_peak=True): For REFM, this is X For REFL, this is Y """ - + # run_number = self._summary.data_run_number_edit.text() # f = FileFinder.findRuns("%s%s" % (self.instrument_name, str(run_number)))[0] # @@ -1122,12 +1122,12 @@ def _plot_data_count_vs_tof_2d(self): #mantidplot.app.connect(mantidplot.app.mantidUI, QtCore.SIGNAL("python_peak_back_tof_range_update(double,double,double,double,double,double)"), call_back) #mantidplot.app.connect(mantidplot.app.RefDetectorViewer, QtCore.SIGNAL("python_peak_back_tof_range_update(double,double,double,double,double,double)"), call_back) - peak_min = int(self._summary.data_peak_from_pixel.text()); - peak_max = int(self._summary.data_peak_to_pixel.text()); - back_min = int(self._summary.data_background_from_pixel1.text()); - back_max = int(self._summary.data_background_to_pixel1.text()); - tof_min = int(self._summary.data_from_tof.text()); - tof_max = int(self._summary.data_to_tof.text()); + peak_min = int(self._summary.data_peak_from_pixel.text()) + peak_max = int(self._summary.data_peak_to_pixel.text()) + back_min = int(self._summary.data_background_from_pixel1.text()) + back_max = int(self._summary.data_background_to_pixel1.text()) + tof_min = int(self._summary.data_from_tof.text()) + tof_max = int(self._summary.data_to_tof.text()) import mantidqtpython self.ref_det_view = mantidqtpython.MantidQt.RefDetectorViewer.RefMatrixWSImageView(ws_output_base, peak_min, peak_max, back_min, back_max, tof_min, tof_max) @@ -1136,12 +1136,12 @@ def _plot_data_count_vs_tof_2d(self): def call_back(self, peakmin, peakmax, backmin, backmax, tofmin, tofmax): - self._summary.data_peak_from_pixel.setText("%-d" % int(peakmin)) - self._summary.data_peak_to_pixel.setText("%-d" % int(peakmax)) - self._summary.data_background_from_pixel1.setText("%-d" % int(backmin)) - self._summary.data_background_to_pixel1.setText("%-d" % int(backmax)) - self._summary.data_from_tof.setText("%-d" % int(tofmin)) - self._summary.data_to_tof.setText("%-d" % int(tofmax)) + self._summary.data_peak_from_pixel.setText("%-d" % int(peakmin)) + self._summary.data_peak_to_pixel.setText("%-d" % int(peakmax)) + self._summary.data_background_from_pixel1.setText("%-d" % int(backmin)) + self._summary.data_background_to_pixel1.setText("%-d" % int(backmax)) + self._summary.data_from_tof.setText("%-d" % int(tofmin)) + self._summary.data_to_tof.setText("%-d" % int(tofmax)) def _norm_count_vs_y(self): diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/refm_reduction.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/refm_reduction.py index 062c0497128a..182eafe93435 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/refm_reduction.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/refm_reduction.py @@ -964,12 +964,12 @@ def _plot_data_count_vs_tof_2d(self): #mantidplot.app.connect(mantidplot.app.mantidUI, QtCore.SIGNAL("python_peak_back_tof_range_update(double,double,double,double,double,double)"), call_back) #mantidplot.app.connect(mantidplot.app.RefDetectorViewer, QtCore.SIGNAL("python_peak_back_tof_range_update(double,double,double,double,double,double)"), call_back) - peak_min = int(self._summary.data_peak_from_pixel.text()); - peak_max = int(self._summary.data_peak_to_pixel.text()); - back_min = int(self._summary.data_background_from_pixel1.text()); - back_max = int(self._summary.data_background_to_pixel1.text()); - tof_min = int(self._summary.data_from_tof.text()); - tof_max = int(self._summary.data_to_tof.text()); + peak_min = int(self._summary.data_peak_from_pixel.text()) + peak_max = int(self._summary.data_peak_to_pixel.text()) + back_min = int(self._summary.data_background_from_pixel1.text()) + back_max = int(self._summary.data_background_to_pixel1.text()) + tof_min = int(self._summary.data_from_tof.text()) + tof_max = int(self._summary.data_to_tof.text()) import mantidqtpython self.ref_det_view = mantidqtpython.MantidQt.RefDetectorViewer.RefMatrixWSImageView(ws_output_base_ff+'_2D', peak_min, peak_max, back_min, back_max, tof_min, tof_max) diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_instrument.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_instrument.py index 1a8ef047e21c..a60f556c2c2f 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_instrument.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_instrument.py @@ -120,7 +120,7 @@ def initialize_content(self): self.connect(self._summary.log_binning_radio, QtCore.SIGNAL("clicked(bool)"), self._summary.align_check.setEnabled) self._summary.scale_edit.setText("1") - + self._summary.n_wedges_edit.setText("2") self._summary.wedge_angle_edit.setText("30") self._summary.wedge_offset_edit.setText("0") @@ -150,7 +150,7 @@ def initialize_content(self): self._summary.mask_side_none_radio.hide() self._summary.mask_side_front_radio.hide() self._summary.mask_side_back_radio.hide() - + if not self._in_mantidplot: self._summary.dark_plot_button.hide() self._summary.scale_data_plot_button.hide() @@ -349,18 +349,18 @@ def set_state(self, state): self._summary.align_check.setEnabled(state.log_binning) self._summary.align_check.setChecked(state.align_log_with_decades) self._summary.error_weighting_check.setChecked(state.error_weighting) - + self._summary.n_wedges_edit.setText(str(state.n_wedges)) self._summary.wedge_angle_edit.setText(str(state.wedge_angle)) self._summary.wedge_offset_edit.setText(str(state.wedge_offset)) - + # Mask self._summary.mask_edit.setText(str(state.mask_file)) self._summary.mask_check.setChecked(state.use_mask_file) self._mask_checked(state.use_mask_file) self._masked_detectors = state.detector_ids self.mask_reload = True - + if state.masked_side == 'Front': self._summary.mask_side_front_radio.setChecked(True) elif state.masked_side == 'Back': @@ -440,7 +440,7 @@ def get_state(self): m.masked_side = 'Back' else: m.masked_side = None - + # Mask detector IDs m.use_mask_file = self._summary.mask_check.isChecked() m.mask_file = unicode(self._summary.mask_edit.text()) diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_sample_data.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_sample_data.py index ff890705a4e9..9370179713b7 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_sample_data.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_sample_data.py @@ -172,7 +172,7 @@ def get_state(self): return m def _sample_scatt_plot(self): - self.show_instrument(unicode(self._content.sample_scatt_edit.text())) + self.show_instrument(unicode(self._content.sample_scatt_edit.text())) def _sample_scatt_browse(self): fname = self.data_browse_dialog() diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/sans_catalog.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/sans_catalog.py index 9ec8166fc03d..0bfeaae8a135 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/sans_catalog.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/sans_catalog.py @@ -162,13 +162,13 @@ def _get_catalog(self): self._content.data_set_table.resizeColumnsToContents() def _browse_directory(self): - dir = QtGui.QFileDialog.getExistingDirectory(self, "Open Directory", + dir = QtGui.QFileDialog.getExistingDirectory(self, "Open Directory", self._settings.data_path) - if dir: + if dir: # Store the location of the loaded file - self._settings.data_path = str(dir) - self._content.directory_edit.setText(dir) - self._update_content() + self._settings.data_path = str(dir) + self._content.directory_edit.setText(dir) + self._update_content() def set_state(self, state): """ @@ -180,4 +180,4 @@ def set_state(self, state): self._update_content(False) def get_state(self): - return Catalog() \ No newline at end of file + return Catalog() diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/stitcher.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/stitcher.py index ff8927473391..2b3e26f44914 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/stitcher.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/stitcher.py @@ -512,4 +512,4 @@ def get_state(self): """ Return dummy state """ - return StitcherState() \ No newline at end of file + return StitcherState() diff --git a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_choose_col.py b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_choose_col.py index 7a027ee6777e..73a0a4aa64bd 100644 --- a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_choose_col.py +++ b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_choose_col.py @@ -37,4 +37,4 @@ def on_listColumns_itemChanged(self, item): def on_buttonsColumns_Clicked(self, button): if self.buttonsColumns.button(QtGui.QDialogButtonBox.RestoreDefaults) == button: for i in range(self.listColumns.count()): - self.listColumns.item(i).setCheckState(2) \ No newline at end of file + self.listColumns.item(i).setCheckState(2) diff --git a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui.py b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui.py index 99b3c7da943e..5e8aabb610e7 100644 --- a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui.py +++ b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui.py @@ -93,17 +93,17 @@ def __init__(self): settings.endGroup() settings.beginGroup(self.__generic_settings) - + self.__alg_migrate = settings.value(self.__alg_migration_key, True, type=bool) if self.__alg_migrate: self.__alg_use = True # We will use the algorithms by default rather than the quick scripts self.__alg_migrate = False # Never do this again. We only want to reset once. else: self.__alg_use = settings.value(self.__ads_use_key, True, type=bool) - + self.__icat_download = settings.value(self.__icat_download_key, False, type=bool) self.__group_tof_workspaces = settings.value(self.__group_tof_workspaces_key, True, type=bool) - + settings.setValue(self.__ads_use_key, self.__alg_use) settings.setValue(self.__icat_download_key, self.__icat_download) settings.setValue(self.__group_tof_workspaces_key, self.__group_tof_workspaces) @@ -127,15 +127,15 @@ def _save_check(self): """ msgBox = QtGui.QMessageBox() msgBox.setText("The table has been modified. Do you want to save your changes?") - + accept_btn = QtGui.QPushButton('Accept') cancel_btn = QtGui.QPushButton('Cancel') discard_btn = QtGui.QPushButton('Discard') - + msgBox.addButton(accept_btn, QtGui.QMessageBox.AcceptRole) msgBox.addButton(cancel_btn, QtGui.QMessageBox.RejectRole) msgBox.addButton(discard_btn, QtGui.QMessageBox.NoRole) - + msgBox.setIcon(QtGui.QMessageBox.Question) msgBox.setDefaultButton(accept_btn) msgBox.setEscapeButton(cancel_btn) @@ -149,7 +149,7 @@ def _save_check(self): ret = QtGui.QMessageBox.RejectRole else: ret = QtGui.QMessageBox.NoRole - + return ret, saved def closeEvent(self, event): @@ -166,7 +166,7 @@ def closeEvent(self, event): elif ret == QtGui.QMessageBox.NoRole: self.mod_flag = False event.accept() - + def _instrument_selected(self, instrument): """ Change the default instrument to the selected one @@ -717,7 +717,7 @@ def _process(self): #If we're given a group workspace, we can just run it on the first member of the group instead thetaRun = loadedRun if isinstance(thetaRun, WorkspaceGroup): - thetaRun = thetaRun[0] + thetaRun = thetaRun[0] dqq, two_theta = CalculateResolution(Workspace = thetaRun, TwoTheta = two_theta) #Put the calculated resolution into the table @@ -783,7 +783,7 @@ def _process(self): #Scale each run if self.tableMain.item(row, self.scale_col).text(): Scale(InputWorkspace=wksp[i], OutputWorkspace=wksp[i], Factor=1 / float(self.tableMain.item(row, self.scale_col).text())) - + if self.__checked_row_stiched(row): if (len(runno) == 1): logger.notice("Nothing to combine for processing row : " + str(row)) @@ -803,8 +803,8 @@ def _process(self): Qmax = max(w2.readX(0)) wcomb = combineDataMulti(wksp, outputwksp, overlapLow, overlapHigh, Qmin, Qmax, -dqq, 1, keep=True) - - + + # Enable the plot button plotbutton = self.tableMain.cellWidget(row, self.plot_col).children()[1] plotbutton.setProperty('runno',runno) @@ -896,7 +896,7 @@ def _plot(self, plotbutton): if not getWorkspace(outputwksp, report_error=False): # Stitching has not been done as part of processing, so we need to do it here. wcomb = combineDataMulti(wkspBinned, outputwksp, overlapLow, overlapHigh, Qmin, Qmax, -dqq, 1, keep=True) - + Qmin = min(getWorkspace(outputwksp).readX(0)) Qmax = max(getWorkspace(outputwksp).readX(0)) if canMantidPlot: @@ -1198,8 +1198,8 @@ def _options_dialog(self): Shows the dialog for setting options regarding live data """ try: - - dialog_controller = refl_options.ReflOptions(def_method = self.live_method, def_freq = self.live_freq, + + dialog_controller = refl_options.ReflOptions(def_method = self.live_method, def_freq = self.live_freq, def_alg_use = self.__alg_use, def_icat_download=self.__icat_download, def_group_tof_workspaces = self.__group_tof_workspaces) if dialog_controller.exec_(): diff --git a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui_run.py b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui_run.py index 484e52c3dfab..acb98704976e 100644 --- a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui_run.py +++ b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui_run.py @@ -8,4 +8,4 @@ ui = refl_gui.ReflGui() ui.setupUi(MainWindow) MainWindow.show() - sys.exit(app.exec_()) \ No newline at end of file + sys.exit(app.exec_()) diff --git a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_options.py b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_options.py index da837f4513dd..d5b9d9732923 100644 --- a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_options.py +++ b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_options.py @@ -76,7 +76,7 @@ def groupTOFWorkspaces(self): def frequency(self): return self.__frequency - + def useAlg(self): return self.__alg_use diff --git a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_save.py b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_save.py index f7d4a857e09f..86d774ee8f90 100644 --- a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_save.py +++ b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_save.py @@ -17,7 +17,7 @@ class Ui_SaveWindow(object): def __init__(self): - self.__has_mount_point = True; + self.__has_mount_point = True self.__instrument = config['default.instrument'].strip().upper() @@ -26,7 +26,7 @@ def __init__(self): self.__mountpoint = usersettings.get_named_setting("DataMountPoint") except KeyError: print "DataMountPoint is missing from the config.xml file." - self.__has_mount_point = False; + self.__has_mount_point = False def setupUi(self, SaveWindow): self.SavePath="" diff --git a/Code/Mantid/scripts/LargeScaleStructures/EQSANS_geometry.py b/Code/Mantid/scripts/LargeScaleStructures/EQSANS_geometry.py index ad61eeed9c47..11c91894edc1 100644 --- a/Code/Mantid/scripts/LargeScaleStructures/EQSANS_geometry.py +++ b/Code/Mantid/scripts/LargeScaleStructures/EQSANS_geometry.py @@ -94,4 +94,4 @@ def create_geometry(file_name=None, tube_width=TUBE_WIDTH, tube_length=TUBE_SIZE det.writeGeom(xml_outfile) if __name__ == "__main__": - create_geometry() \ No newline at end of file + create_geometry() diff --git a/Code/Mantid/scripts/LargeScaleStructures/REF_L_geometry.py b/Code/Mantid/scripts/LargeScaleStructures/REF_L_geometry.py index 45b8018c8691..f60a886bf4ca 100644 --- a/Code/Mantid/scripts/LargeScaleStructures/REF_L_geometry.py +++ b/Code/Mantid/scripts/LargeScaleStructures/REF_L_geometry.py @@ -100,4 +100,4 @@ def create_geometry(file_name=None, pixel_width=None, pixel_height=None): if __name__ == "__main__": create_geometry() - #create_grouping() \ No newline at end of file + #create_grouping() diff --git a/Code/Mantid/scripts/LargeScaleStructures/ReflectometerCors.py b/Code/Mantid/scripts/LargeScaleStructures/ReflectometerCors.py index f81bdb8f1c58..8de9fd47cf73 100644 --- a/Code/Mantid/scripts/LargeScaleStructures/ReflectometerCors.py +++ b/Code/Mantid/scripts/LargeScaleStructures/ReflectometerCors.py @@ -1,65 +1,65 @@ from mantid.simpleapi import * def heliumDetectorEff(workspace): - ''' Calculate the corrected Helium detector values. ''' + ''' Calculate the corrected Helium detector values. ''' - ac= 6.022169e23 # Avogadro's constant mol-1 - vm= 2.24136e4 # Molar volume of gas cm3 mol-1 - gp= 10.0 # Gas pressure (atms) - gsig0= 5333.0e-24 # Gas cross section at LAM0 cm2 - gt= 2.5 # Gas path length cm - lam0= 1.8 # Characteristic wavelength + ac= 6.022169e23 # Avogadro's constant mol-1 + vm= 2.24136e4 # Molar volume of gas cm3 mol-1 + gp= 10.0 # Gas pressure (atms) + gsig0= 5333.0e-24 # Gas cross section at LAM0 cm2 + gt= 2.5 # Gas path length cm + lam0= 1.8 # Characteristic wavelength - gn= ac*gp/vm # Number density of gas - sgn= gn*gsig0*gt/lam0 # Exponential term for gas + gn= ac*gp/vm # Number density of gas + sgn= gn*gsig0*gt/lam0 # Exponential term for gas - OneMinusExponentialCor(InputWorkspace=workspace,OutputWorkspace=workspace,C=str(sgn),Operation="Divide") + OneMinusExponentialCor(InputWorkspace=workspace,OutputWorkspace=workspace,C=str(sgn),Operation="Divide") - wt= 60.014 # Molecular weight Ni-Cu g mol-1 - rho= 8.00 # Density Ni-Cu g cm-3 - ct= 0.05 # Monel (Ni-Cu) wall thickness cm - wsig0= 4.522e-24 # Wall cross section at LAM0 cm2 + wt= 60.014 # Molecular weight Ni-Cu g mol-1 + rho= 8.00 # Density Ni-Cu g cm-3 + ct= 0.05 # Monel (Ni-Cu) wall thickness cm + wsig0= 4.522e-24 # Wall cross section at LAM0 cm2 - wn= ac*rho/wt # Number density of wall - swn= wn*wsig0*ct/lam0 # Exponential term for wall + wn= ac*rho/wt # Number density of wall + swn= wn*wsig0*ct/lam0 # Exponential term for wall - ExponentialCorrection(InputWorkspace=workspace,OutputWorkspace=workspace,C1=str(swn),Operation="Divide") + ExponentialCorrection(InputWorkspace=workspace,OutputWorkspace=workspace,C1=str(swn),Operation="Divide") # simple polynomial correction based on a D2O spectrum taken at 1.5 deg - PolynomialCorrection(InputWorkspace=workspace,OutputWorkspace=workspace,Coefficients="-1.3697,0.8602,-0.7839,0.2866,-0.0447,0.0025") - return + PolynomialCorrection(InputWorkspace=workspace,OutputWorkspace=workspace,Coefficients="-1.3697,0.8602,-0.7839,0.2866,-0.0447,0.0025") + return def monitor2Eff(workspace): - ''' Calculate the corrected monitor2 values. ''' + ''' Calculate the corrected monitor2 values. ''' # expon= unt*(1-exp(-8.3047 * zz * x_mean )) # yout[i]= yin[i]*(1.0-expon) / expon # eout[i]= ein[i]*(1.0-expon) / expon # The above correction is equivalent to: (1/unt - 1) + e^(-8.3047*zz*x) # ------------------------------ # ( 1 - e^(-8.3047*zz*x) ) - unt=0.24 # 0.05 # ratio of scintillator to total area - zz = 0.6 #0.03 # thickness(cm) of scintillator - c1 = 0.7112*zz #8.3047*zz + unt=0.24 # 0.05 # ratio of scintillator to total area + zz = 0.6 #0.03 # thickness(cm) of scintillator + c1 = 0.7112*zz #8.3047*zz - ExponentialCorrection(InputWorkspace=workspace,OutputWorkspace=workspace,C1=str(c1),Operation="Multiply") - shift = (1.0/unt)-1.0 - CreateSingleValuedWorkspace(OutputWorkspace="shift",DataValue=str(shift),ErrorValue="0.0") - Plus(LHSWorkspace=workspace,RHSWorkspace="shift",OutputWorkspace=workspace) - mtd.remove("shift") - OneMinusExponentialCor(InputWorkspace=workspace,OutputWorkspace=workspace,C=str(c1)) + ExponentialCorrection(InputWorkspace=workspace,OutputWorkspace=workspace,C1=str(c1),Operation="Multiply") + shift = (1.0/unt)-1.0 + CreateSingleValuedWorkspace(OutputWorkspace="shift",DataValue=str(shift),ErrorValue="0.0") + Plus(LHSWorkspace=workspace,RHSWorkspace="shift",OutputWorkspace=workspace) + mtd.remove("shift") + OneMinusExponentialCor(InputWorkspace=workspace,OutputWorkspace=workspace,C=str(c1)) - return + return def main(): - '''This main routine. It is executed on if the script is run directly, not if it is imported.''' - LoadRawDialog(OutputWorkspace="ws",SpectrumMin="1",SpectrumMax="1") - ConvertUnits(InputWorkspace="ws",OutputWorkspace="ws",Target="Wavelength",AlignBins="1") - heliumDetectorEff("ws") - monitor2Eff("ws") - print "Done!" + '''This main routine. It is executed on if the script is run directly, not if it is imported.''' + LoadRawDialog(OutputWorkspace="ws",SpectrumMin="1",SpectrumMax="1") + ConvertUnits(InputWorkspace="ws",OutputWorkspace="ws",Target="Wavelength",AlignBins="1") + heliumDetectorEff("ws") + monitor2Eff("ws") + print "Done!" if __name__ == '__main__': - main() + main() diff --git a/Code/Mantid/scripts/LargeScaleStructures/geometry_writer.py b/Code/Mantid/scripts/LargeScaleStructures/geometry_writer.py index df87ed791fa8..1d68dcbc7ad6 100644 --- a/Code/Mantid/scripts/LargeScaleStructures/geometry_writer.py +++ b/Code/Mantid/scripts/LargeScaleStructures/geometry_writer.py @@ -76,10 +76,10 @@ def addModerator(self, distance): """ source = self._append_child("component", self._root, type="moderator") try: - distance = float(distance) - if distance > 0: - distance *= -1.0 - self._append_child("location", source, z=distance) + distance = float(distance) + if distance > 0: + distance *= -1.0 + self._append_child("location", source, z=distance) except: print "PROBLEM with addModerator" @@ -198,7 +198,7 @@ def addDetector(self, x, y, z, rot_x, rot_y, rot_z, name, comp_type, usepolar=No if usepolar is not None: self.addLocationPolar(comp_element, x, y, z) else: - self.addLocation(comp_element, x, y, z, rot_x, rot_y, rot_z) + self.addLocation(comp_element, x, y, z, rot_x, rot_y, rot_z) def addSingleDetector(self, root, x, y, z, rot_x, rot_y, rot_z, name=None, id=None, usepolar=None): diff --git a/Code/Mantid/scripts/ORNL_SANS.py b/Code/Mantid/scripts/ORNL_SANS.py index 885aadc6e708..b26c507a6d61 100644 --- a/Code/Mantid/scripts/ORNL_SANS.py +++ b/Code/Mantid/scripts/ORNL_SANS.py @@ -6,4 +6,4 @@ reducer = ReductionGUI(instrument_list=["BIOSANS", "GPSANS", "EQSANS"]) if reducer.setup_layout(load_last=True): - reducer.show() \ No newline at end of file + reducer.show() diff --git a/Code/Mantid/scripts/PyChop.py b/Code/Mantid/scripts/PyChop.py index d98e547ebd8c..e349285143ae 100644 --- a/Code/Mantid/scripts/PyChop.py +++ b/Code/Mantid/scripts/PyChop.py @@ -7,9 +7,9 @@ def qapp(): if QtGui.QApplication.instance(): - app = QtGui.QApplication.instance() + app = QtGui.QApplication.instance() else: - app = QtGui.QApplication(sys.argv) + app = QtGui.QApplication(sys.argv) return app app = qapp() @@ -19,4 +19,4 @@ def qapp(): else: Resolution = PyChopGUI.MainWindow() Resolution.show() -app.exec_() \ No newline at end of file +app.exec_() diff --git a/Code/Mantid/scripts/PyChop/PyChop.py b/Code/Mantid/scripts/PyChop/PyChop.py index f01b80fe0f8f..9c9874475f83 100644 --- a/Code/Mantid/scripts/PyChop/PyChop.py +++ b/Code/Mantid/scripts/PyChop/PyChop.py @@ -3,9 +3,9 @@ import numpy from mantid.simpleapi import * try: - from mantidplot import * + from mantidplot import * except ImportError: - pass + pass ''' chop(inst,ei,chop_type,frequency): python implementation of CHOP ver 1.0 @@ -193,39 +193,39 @@ def calculate(ei,frequency,**kwargs): if instname=='maps' or instname=='map' or instname=='MAP'or instname=='MAPS': #For MAPS - x0 = 10.1000 - xa = 8.1100 - x1 = 1.9000 - x2 = 6.0000 - wa_mm = 70.130 - ha_mm = 70.130 - wa = ha_mm / 1000.00 - ha = ha_mm / 1000.00 + x0 = 10.1000 + xa = 8.1100 + x1 = 1.9000 + x2 = 6.0000 + wa_mm = 70.130 + ha_mm = 70.130 + wa = ha_mm / 1000.00 + ha = ha_mm / 1000.00 # chopper details # now some moderator details # for 300K H2O - s=numpy.zeros(6) - s[1] = 38.60 - s[2] = 0.52260 - s[3] = 0.00 - s[4] = 0.00 - s[5] = 0.00 - th_deg = 32.00 - imod = 2 - mod_type = 'AP' + s=numpy.zeros(6) + s[1] = 38.60 + s[2] = 0.52260 + s[3] = 0.00 + s[4] = 0.00 + s[5] = 0.00 + th_deg = 32.00 + imod = 2 + mod_type = 'AP' # sample details - sx_mm = 2.00 - sy_mm = 50.00 - sz_mm = 50.00 - isam = 0 - gam_deg = 0.00 - ia = 0 - ix = 0 + sx_mm = 2.00 + sy_mm = 50.00 + sz_mm = 50.00 + isam = 0 + gam_deg = 0.00 + ia = 0 + ix = 0 # detector details - idet = 1 - dd_mm = 250 - tbin_us = 0.00 + idet = 1 + dd_mm = 250 + tbin_us = 0.00 #chop_par,titledata=setchoptype(instname,chop_type) # end of maps parameters @@ -788,7 +788,7 @@ def achop(ei,omega): return area def frange(limit1, limit2 = None, increment = 1.): - """ + """ Range function that accepts floats (and integers). Usage: @@ -799,10 +799,10 @@ def frange(limit1, limit2 = None, increment = 1.): The returned value is an iterator. Use list(frange) for a list. """ - if limit2 is None: - limit2, limit1 = limit1, 0. - else: - limit1 = float(limit1) + if limit2 is None: + limit2, limit1 = limit1, 0. + else: + limit1 = float(limit1) - count = int(math.ceil(limit2 - limit1)/increment) - return (limit1 + n*increment for n in range(count)) + count = int(math.ceil(limit2 - limit1)/increment) + return (limit1 + n*increment for n in range(count)) diff --git a/Code/Mantid/scripts/PyChop/PyChopGUI.py b/Code/Mantid/scripts/PyChop/PyChopGUI.py index 463e066e20b3..67c4801132ef 100644 --- a/Code/Mantid/scripts/PyChop/PyChopGUI.py +++ b/Code/Mantid/scripts/PyChop/PyChopGUI.py @@ -40,9 +40,9 @@ def set_inst(self,name): self.inst=name config['default.instrument']=name if len(self.chop)>0: - message,err = PyChop.setchoptype(self.inst,self.chop) - if err>0: - self.chop='' + message,err = PyChop.setchoptype(self.inst,self.chop) + if err>0: + self.chop='' def set_chop(self,chop_type): message,err = PyChop.setchoptype(self.inst,chop_type) diff --git a/Code/Mantid/scripts/PyChop/fluxGUI.py b/Code/Mantid/scripts/PyChop/fluxGUI.py index c2e6dc39c391..989aff9fd9bd 100644 --- a/Code/Mantid/scripts/PyChop/fluxGUI.py +++ b/Code/Mantid/scripts/PyChop/fluxGUI.py @@ -29,7 +29,7 @@ def __init__(self, parent=None): QtCore.QObject.connect(self.ui.actionMAPS,QtCore.SIGNAL("triggered()"), lambda : self.otherInstrumentSelected('MAP')) - self.graph=None; + self.graph=None self.loadData() @@ -56,7 +56,7 @@ def loadData(self): self.res_energies = array.array( 'f', [0.2, 0.4, 0.6, 0.8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40] ) self.frequencies = np.arange(30,310,10) - self.ei=""; + self.ei="" self.ei_min = 0.2 # max(min(self.flux_energies),min(self.res_energies)) self.ei_max = 40. #min(max(self.flux_energies),max(self.res_energies)) @@ -108,8 +108,8 @@ def interpolate_data(self,data_matrix,energies): return result def letSelected(self): - QtGui.QMessageBox.warning(self, "Currently You have to switch gui to select another instrument") - self.ui.actionLET.setChecked(True) + QtGui.QMessageBox.warning(self, "Currently You have to switch gui to select another instrument") + self.ui.actionLET.setChecked(True) def otherInstrumentSelected(self,INAME): reply = QtGui.QMessageBox.question(self, 'Selecting : '+INAME, "Do you want to switch GUI?", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) @@ -133,7 +133,7 @@ def calculate(self): self.ei = float (self.ei) if self.ei< self.ei_min or self.ei > self.ei_max: - self.ei=""; + self.ei="" QtGui.QMessageBox.warning(self, "LETFlux", "Energy out of range.\n Please, Provide value between "+str(self.ei_min)+" and "+str(self.ei_max)+" meV \n") else: self.setUpTable() @@ -142,7 +142,7 @@ def calculate(self): self.ui.list.insertItem(0,string) string_title = 'Frequency(Hz) Flux(n/s/cm^2) Resolution[ueV]' self.ui.list.insertItem(1,string_title) - t=self.t; + t=self.t for i in xrange(0, len(self.frequencies)): string1 = str(self.frequencies[i])+' '+ "%e" % t.cell(2,i+1)+' '+ "%e"% t.cell(3,i+1) self.ui.list.insertItem(2+i,string1) @@ -171,7 +171,7 @@ def plotData(self): self.graph = newGraph("Flux and Resolution",2,1,2) - l1 = self.graph.layer(1); + l1 = self.graph.layer(1) l1.setAntialiasing() l1.setTitle("Flux") l1.setAxisTitle(Layer.Bottom, "Frequency [Hz]") @@ -179,7 +179,7 @@ def plotData(self): l1.showGrid() # self.graphFlux.insertCurve(self.t, "Flux/Frequency_2", Layer.Scatter) # legend = self.graphFlux.newLegend(str(self.ei)) - l2 = self.graph.layer(2); + l2 = self.graph.layer(2) l2.setAntialiasing() l2.setTitle("Resolution") l2.setAxisTitle(Layer.Bottom, "Frequency [Hz]") @@ -188,9 +188,9 @@ def plotData(self): # self.graphRes.insertCurve(self.t, "Resolution/Frequency_2", Layer.Scatter) l2.showGrid() - self.addPlot(); + self.addPlot() - self.raise_(); + self.raise_() self.show() return self @@ -199,7 +199,7 @@ def addPlot(self): """ Adds plot to an existing graph """ if self.graph==None: - self.plotData(); + self.plotData() else: self.calculate() if self.ei == "": diff --git a/Code/Mantid/scripts/REFL_Reduction.py b/Code/Mantid/scripts/REFL_Reduction.py index b811a3f8f53e..ef1b36bd3c63 100644 --- a/Code/Mantid/scripts/REFL_Reduction.py +++ b/Code/Mantid/scripts/REFL_Reduction.py @@ -6,4 +6,4 @@ reducer = ReductionGUI(instrument="REFL", instrument_list=["REFL"]) if reducer.setup_layout(load_last=True): - reducer.show() \ No newline at end of file + reducer.show() diff --git a/Code/Mantid/scripts/REFL_SF_Calculator.py b/Code/Mantid/scripts/REFL_SF_Calculator.py index 839f8d3b21b9..eb094088327c 100644 --- a/Code/Mantid/scripts/REFL_SF_Calculator.py +++ b/Code/Mantid/scripts/REFL_SF_Calculator.py @@ -6,4 +6,4 @@ reducer = ReductionGUI(instrument="REFLSF", instrument_list=["REFLSF"]) if reducer.setup_layout(load_last=True): - reducer.show() \ No newline at end of file + reducer.show() diff --git a/Code/Mantid/scripts/REFM_Reduction.py b/Code/Mantid/scripts/REFM_Reduction.py index 42aa147ac080..f56996b14c9b 100644 --- a/Code/Mantid/scripts/REFM_Reduction.py +++ b/Code/Mantid/scripts/REFM_Reduction.py @@ -6,4 +6,4 @@ reducer = ReductionGUI(instrument="REFM", instrument_list=["REFM"]) if reducer.setup_layout(load_last=True): - reducer.show() \ No newline at end of file + reducer.show() diff --git a/Code/Mantid/scripts/Reflectometry/isis_reflectometry/combineMulti.py b/Code/Mantid/scripts/Reflectometry/isis_reflectometry/combineMulti.py index 037f88995b45..81467796e337 100644 --- a/Code/Mantid/scripts/Reflectometry/isis_reflectometry/combineMulti.py +++ b/Code/Mantid/scripts/Reflectometry/isis_reflectometry/combineMulti.py @@ -20,37 +20,37 @@ def combineDataMulti(wksp_list,output_wksp,beg_overlap,end_overlap,Qmin,Qmax,bin # check if overlaps have correct number of entries defaultoverlaps = False if type(beg_overlap) != list: - beg_overlap = [beg_overlap] + beg_overlap = [beg_overlap] if type(end_overlap) != list: - end_overlap = [end_overlap] + end_overlap = [end_overlap] if len(wksp_list) != len(beg_overlap): - print "Using default values!" - defaultoverlaps = True + print "Using default values!" + defaultoverlaps = True #copy first workspace into temporary wksp 'currentSum' currentSum = CloneWorkspace(InputWorkspace=wksp_list[0]) print "Length: ",len(wksp_list), wksp_list for i in range(0,len(wksp_list)-1): - w1=currentSum - w2=getWorkspace(wksp_list[i+1]) # TODO: distinguishing between a group and a individual workspace is unnecessary for an algorithm. But custom group behavior WILL be required. - if defaultoverlaps: - overlapLow = w2.readX(0)[0] - overlapHigh = 0.5*max(w1.readX(0)) - else: - overlapLow = beg_overlap[i+1] - overlapHigh = end_overlap[i] - print "Iteration",i - currentSum, scale_factor = stitch2(currentSum, mtd[wksp_list[i+1]], currentSum.name(), overlapLow, overlapHigh, Qmin, Qmax, binning, scale_high) + w1=currentSum + w2=getWorkspace(wksp_list[i+1]) # TODO: distinguishing between a group and a individual workspace is unnecessary for an algorithm. But custom group behavior WILL be required. + if defaultoverlaps: + overlapLow = w2.readX(0)[0] + overlapHigh = 0.5*max(w1.readX(0)) + else: + overlapLow = beg_overlap[i+1] + overlapHigh = end_overlap[i] + print "Iteration",i + currentSum, scale_factor = stitch2(currentSum, mtd[wksp_list[i+1]], currentSum.name(), overlapLow, overlapHigh, Qmin, Qmax, binning, scale_high) RenameWorkspace(InputWorkspace=currentSum.name(),OutputWorkspace=output_wksp) # Remove any existing workspaces from the workspace list. if not keep: - names = mtd.getObjectNames() - for ws in wksp_list: - candidate = ws - if candidate in names: - DeleteWorkspace(candidate) + names = mtd.getObjectNames() + for ws in wksp_list: + candidate = ws + if candidate in names: + DeleteWorkspace(candidate) return mtd[output_wksp] @@ -70,10 +70,10 @@ def stitch2(ws1, ws2, output_ws_name, begoverlap,endoverlap,Qmin,Qmax,binning,sc scalefactor: Use the manual scaling factor provided if > 0 """ if scalefactor > 0.0: - manual_scalefactor = True + manual_scalefactor = True else: - manual_scalefactor = False - scalefactor = 1.0 + manual_scalefactor = False + scalefactor = 1.0 # Interally use the Stitch1D algorithm. outputs = Stitch1D(LHSWorkspace=ws1, RHSWorkspace=ws2, OutputWorkspace=output_ws_name, StartOverlap=begoverlap, EndOverlap=endoverlap, @@ -99,10 +99,10 @@ def combine2(wksp1,wksp2,outputwksp,begoverlap,endoverlap,Qmin,Qmax,binning,scal scalefactor: Use the manual scaling factor provided if > 0 """ if scalefactor > 0.0: - manual_scalefactor = True + manual_scalefactor = True else: - manual_scalefactor = False - scalefactor = 1.0 + manual_scalefactor = False + scalefactor = 1.0 # Interally use the Stitch1D algorithm. outputs = Stitch1D(LHSWorkspace=mtd[wksp1], RHSWorkspace=mtd[wksp2], OutputWorkspace=outputwksp, StartOverlap=begoverlap, EndOverlap=endoverlap, @@ -118,9 +118,9 @@ def getWorkspace(wksp): Get the workspace if it is not a group workspace. If it is a group workspace, get the first period. """ if isinstance(mtd[wksp], WorkspaceGroup): - wout = mtd[wksp][0] + wout = mtd[wksp][0] else: - wout = mtd[wksp] + wout = mtd[wksp] return wout diff --git a/Code/Mantid/scripts/Reflectometry/isis_reflectometry/convert_to_wavelength.py b/Code/Mantid/scripts/Reflectometry/isis_reflectometry/convert_to_wavelength.py index 2f724574dee3..5507b75bff15 100644 --- a/Code/Mantid/scripts/Reflectometry/isis_reflectometry/convert_to_wavelength.py +++ b/Code/Mantid/scripts/Reflectometry/isis_reflectometry/convert_to_wavelength.py @@ -51,7 +51,7 @@ def to_workspace(cls, candidate, ws_prefix="_"): msi.Load(Filename=candidate, OutputWorkspace=ws_name) _workspace = mantid.api.AnalysisDataService.retrieve(ws_name) else: - raise ValueError("Unknown source item %s" % candidate) + raise ValueError("Unknown source item %s" % candidate) return _workspace def get_workspace_from_list(self, index): diff --git a/Code/Mantid/scripts/Reflectometry/isis_reflectometry/procedures.py b/Code/Mantid/scripts/Reflectometry/isis_reflectometry/procedures.py index c3b43430dd0d..f2fac19542b9 100644 --- a/Code/Mantid/scripts/Reflectometry/isis_reflectometry/procedures.py +++ b/Code/Mantid/scripts/Reflectometry/isis_reflectometry/procedures.py @@ -1,16 +1,16 @@ from math import * try: - from mantid.simpleapi import * # New API + from mantid.simpleapi import * # New API except ImportError: - pass + pass #import qti as qti import numpy as n def addRuns(runlist,wname): - mtd.deleteWorkspace(str(wname)) - output=str(wname) - if runlist[0] != "0": + mtd.deleteWorkspace(str(wname)) + output=str(wname) + if runlist[0] != "0": #nzeros=8-len(str(runlist[0])) #fpad="" #for i in range(nzeros): @@ -24,20 +24,20 @@ def addRuns(runlist,wname): #fname=fname.lower() ##fname=str.replace(fname,'.nxs','.raw') #Load(fname,output) - Load(str(runlist[0]),output) - else: - #dae="ndx"+mtd.settings['default.instrument'].lower() - dae="ndxoffspec" - LoadDAE(DAEname=dae,OutputWorkspace=output,SpectrumMin="1") - if(mtd[output].isGroup()): - for k in mtd[output].getNames(): - mtd[k].setYUnit('Counts') + Load(str(runlist[0]),output) else: - mtd[output].setYUnit('Counts') + #dae="ndx"+mtd.settings['default.instrument'].lower() + dae="ndxoffspec" + LoadDAE(DAEname=dae,OutputWorkspace=output,SpectrumMin="1") + if(mtd[output].isGroup()): + for k in mtd[output].getNames(): + mtd[k].setYUnit('Counts') + else: + mtd[output].setYUnit('Counts') - if len(runlist) > 1: - for i in range(1,len(runlist)): - if runlist[i] != "0": + if len(runlist) > 1: + for i in range(1,len(runlist)): + if runlist[i] != "0": #nzeros=8-len(str(runlist[i])) #fpad="" #for j in range(nzeros): @@ -51,20 +51,20 @@ def addRuns(runlist,wname): #fname=fname.lower() ##fname=str.replace(fname,'.nxs','.raw') #Load(fname,"wtemp") - Load(str(runlist[i]),"wtemp") - else: + Load(str(runlist[i]),"wtemp") + else: #dae="ndx"+mtd.settings['default.instrument'].lower() - dae="ndxoffspec" - LoadDAE(DAEname=dae,OutputWorkspace="wtemp",SpectrumMin="1") - if(mtd['wtemp'].isGroup()): - for k in mtd['wtemp'].getNames(): - mtd[k].setYUnit('Counts') - else: - mtd[output].setYUnit('Counts') - Plus(output,"wtemp",output) - mtd.deleteWorkspace("wtemp") + dae="ndxoffspec" + LoadDAE(DAEname=dae,OutputWorkspace="wtemp",SpectrumMin="1") + if(mtd['wtemp'].isGroup()): + for k in mtd['wtemp'].getNames(): + mtd[k].setYUnit('Counts') + else: + mtd[output].setYUnit('Counts') + Plus(output,"wtemp",output) + mtd.deleteWorkspace("wtemp") - mtd.sendLogMessage("addRuns Completed") + mtd.sendLogMessage("addRuns Completed") ''' parse a text string of the format "1-6:2+8+9,10+11+12+13-19:3,20-24" @@ -132,15 +132,15 @@ def floodnorm(wkspName,floodfile): # # pixel by pixel efficiency correction for the linear detector # - floodloaded=0 - a1=mtd.getWorkspaceNames() - for i in range(len(a1)): - if a1[i] == "ld240flood": - floodloaded=1 - if floodloaded == 0: - LoadNexusProcessed(Filename=floodfile,OutputWorkspace="ld240flood") - - Divide(wkspName,"ld240flood",wkspName) + floodloaded=0 + a1=mtd.getWorkspaceNames() + for i in range(len(a1)): + if a1[i] == "ld240flood": + floodloaded=1 + if floodloaded == 0: + LoadNexusProcessed(Filename=floodfile,OutputWorkspace="ld240flood") + + Divide(wkspName,"ld240flood",wkspName) # # Plot a bunch of workspaces as 2D maps # using the supplied limits and log scale settings @@ -264,8 +264,8 @@ def removeoutlayer(wksp): for j in range(len(x)-1): y=a1.readY(i)[j] if (y<2): - a1.dataY(i)[j]=0.0; - a1.dataE(i)[j]=0.0; + a1.dataY(i)[j]=0.0 + a1.dataE(i)[j]=0.0 def nrSESANSFn(runList,nameList,P0runList,P0nameList,minSpec,maxSpec,upPeriod,downPeriod,existingP0,SEConstants,gparams,convertToSEL,lnPOverLam,diagnostics="0",removeoutlayer="0",floodfile="none",): nlist=parseNameList(nameList) diff --git a/Code/Mantid/scripts/SANS/ISISCommandInterface.py b/Code/Mantid/scripts/SANS/ISISCommandInterface.py index f3cd45cac67a..d7c2bbee8be0 100644 --- a/Code/Mantid/scripts/SANS/ISISCommandInterface.py +++ b/Code/Mantid/scripts/SANS/ISISCommandInterface.py @@ -452,9 +452,9 @@ def WavRangeReduction(wav_start=None, wav_end=None, full_trans_wav=None, name_su if merge_flag: retWSname_merged = retWSname_rear if retWSname_merged.count('rear') == 1: - retWSname_merged = retWSname_merged.replace('rear', 'merged') + retWSname_merged = retWSname_merged.replace('rear', 'merged') else: - retWSname_merged = retWSname_merged + "_merged" + retWSname_merged = retWSname_merged + "_merged" Nf = mtd[retWSname_front+"_sumOfNormFactors"] Nr = mtd[retWSname_rear+"_sumOfNormFactors"] @@ -574,26 +574,26 @@ def _fitRescaleAndShift(rAnds, frontData, rearData): if rAnds.qRangeUserSelected: Fit(InputWorkspace=rearData, Function='name=TabulatedFunction, Workspace="'+str(frontData)+'"' - +";name=FlatBackground", + +";name=FlatBackground", Ties='f0.Scaling='+str(rAnds.scale)+',f0.Shift=0.0', Output="__fitRescaleAndShift", StartX=rAnds.qMin, EndX=rAnds.qMax) else: Fit(InputWorkspace=rearData, Function='name=TabulatedFunction, Workspace="'+str(frontData)+'"' - +";name=FlatBackground", + +";name=FlatBackground", Ties='f0.Scaling='+str(rAnds.scale)+',f0.Shift=0.0', Output="__fitRescaleAndShift") elif rAnds.fitShift==False: if rAnds.qRangeUserSelected: Fit(InputWorkspace=rearData, Function='name=TabulatedFunction, Workspace="'+str(frontData)+'"' - +";name=FlatBackground", + +";name=FlatBackground", Ties='f1.A0='+str(rAnds.shift*rAnds.scale)+',f0.Shift=0.0', Output="__fitRescaleAndShift", StartX=rAnds.qMin, EndX=rAnds.qMax) else: Fit(InputWorkspace=rearData, Function='name=TabulatedFunction, Workspace="'+str(frontData)+'"' - +";name=FlatBackground", + +";name=FlatBackground", Ties='f1.A0='+str(rAnds.shift*rAnds.scale)+',f0.Shift=0.0', Output="__fitRescaleAndShift") else: diff --git a/Code/Mantid/scripts/SANS/SANSUtility.py b/Code/Mantid/scripts/SANS/SANSUtility.py index e66369da9fdc..48fb6cef0dd2 100644 --- a/Code/Mantid/scripts/SANS/SANSUtility.py +++ b/Code/Mantid/scripts/SANS/SANSUtility.py @@ -143,9 +143,9 @@ def spectrumBlock(base, ylow, xlow, ydim, xdim, det_dimension, orientation): max_row = base + (y+1)*det_dimension - 1 min_row = base + (y)*det_dimension for x in range(0,xdim): - std_i = start_spec + x + (y*det_dimension) - diff_s = std_i - min_row - output += str(max_row - diff_s) + ',' + std_i = start_spec + x + (y*det_dimension) + diff_s = std_i - min_row + output += str(max_row - diff_s) + ',' return output.rstrip(",") @@ -618,28 +618,28 @@ def ScaleByVolume(inputWS, scalefactor, geomid, width, height, thickness): @deprecated def StripEndZeroes(workspace, flag_value = 0.0): - result_ws = mtd[workspace] - y_vals = result_ws.readY(0) - length = len(y_vals) + result_ws = mtd[workspace] + y_vals = result_ws.readY(0) + length = len(y_vals) # Find the first non-zero value - start = 0 - for i in range(0, length): - if ( y_vals[i] != flag_value ): - start = i - break + start = 0 + for i in range(0, length): + if ( y_vals[i] != flag_value ): + start = i + break # Now find the last non-zero value - stop = 0 - length -= 1 - for j in range(length, 0,-1): - if ( y_vals[j] != flag_value ): - stop = j - break + stop = 0 + length -= 1 + for j in range(length, 0,-1): + if ( y_vals[j] != flag_value ): + stop = j + break # Find the appropriate X values and call CropWorkspace - x_vals = result_ws.readX(0) - startX = x_vals[start] + x_vals = result_ws.readX(0) + startX = x_vals[start] # Make sure we're inside the bin that we want to crop - endX = 1.001*x_vals[stop + 1] - CropWorkspace(InputWorkspace=workspace,OutputWorkspace=workspace,XMin=startX,XMax=endX) + endX = 1.001*x_vals[stop + 1] + CropWorkspace(InputWorkspace=workspace,OutputWorkspace=workspace,XMin=startX,XMax=endX) @deprecated class Orientation(object): diff --git a/Code/Mantid/scripts/SANS/SANSadd2.py b/Code/Mantid/scripts/SANS/SANSadd2.py index 910687eb533e..6f9fbb481586 100644 --- a/Code/Mantid/scripts/SANS/SANSadd2.py +++ b/Code/Mantid/scripts/SANS/SANSadd2.py @@ -7,54 +7,76 @@ _NO_INDIVIDUAL_PERIODS = -1 def add_runs(runs, inst='sans2d', defType='.nxs', rawTypes=('.raw', '.s*', 'add','.RAW'), lowMem=False, binning='Monitors'): - if inst.upper() == "SANS2DTUBES": - inst = "SANS2D" + if inst.upper() == "SANS2DTUBES": + inst = "SANS2D" #check if there is at least one file in the list - if len(runs) < 1 : return + if len(runs) < 1 : return - if not defType.startswith('.') : defType = '.'+defType + if not defType.startswith('.') : defType = '.'+defType #these input arguments need to be arrays of strings, enforce this - if type(runs) == str : runs = (runs, ) - if type(rawTypes) == str : rawTypes = (rawTypes, ) + if type(runs) == str : runs = (runs, ) + if type(rawTypes) == str : rawTypes = (rawTypes, ) - if lowMem: - lowMem = _can_load_periods(runs, defType, rawTypes) - if lowMem: - period = 1 - else: - period = _NO_INDIVIDUAL_PERIODS + if lowMem: + lowMem = _can_load_periods(runs, defType, rawTypes) + if lowMem: + period = 1 + else: + period = _NO_INDIVIDUAL_PERIODS - userEntry = runs[0] + userEntry = runs[0] - while(True): + while(True): - isFirstDataSetEvent = False + isFirstDataSetEvent = False #we need to catch all exceptions to ensure that a dialog box is raised with the error - try : - lastPath, lastFile, logFile, num_periods, isFirstDataSetEvent = _loadWS( + try : + lastPath, lastFile, logFile, num_periods, isFirstDataSetEvent = _loadWS( userEntry, defType, inst, 'AddFilesSumTempory', rawTypes, period) # if event data prevent loop over periods makes no sense - if isFirstDataSetEvent: - period = _NO_INDIVIDUAL_PERIODS - - if inst.upper() != 'SANS2D' and isFirstDataSetEvent: - error = 'Adding event data not supported for ' + inst + ' for now' - print error - logger.notice(error) - for workspaceName in ('AddFilesSumTempory','AddFilesSumTempory_monitors'): - if workspaceName in mtd: - DeleteWorkspace(workspaceName) - return "" - - for i in range(len(runs)-1): - userEntry = runs[i+1] - lastPath, lastFile, logFile, dummy, isDataSetEvent = _loadWS( + if isFirstDataSetEvent: + period = _NO_INDIVIDUAL_PERIODS + + if inst.upper() != 'SANS2D' and isFirstDataSetEvent: + error = 'Adding event data not supported for ' + inst + ' for now' + print error + logger.notice(error) + for workspaceName in ('AddFilesSumTempory','AddFilesSumTempory_monitors'): + if workspaceName in mtd: + DeleteWorkspace(workspaceName) + return "" + + for i in range(len(runs)-1): + userEntry = runs[i+1] + lastPath, lastFile, logFile, dummy, isDataSetEvent = _loadWS( userEntry, defType, inst,'AddFilesNewTempory', rawTypes, period) - if isDataSetEvent != isFirstDataSetEvent: - error = 'Datasets added must be either ALL histogram data or ALL event data' + if isDataSetEvent != isFirstDataSetEvent: + error = 'Datasets added must be either ALL histogram data or ALL event data' + print error + logger.notice(error) + for workspaceName in ('AddFilesSumTempory','AddFilesNewTempory'): + if workspaceName in mtd: + DeleteWorkspace(workspaceName) + return "" + + Plus(LHSWorkspace='AddFilesSumTempory',RHSWorkspace= 'AddFilesNewTempory',OutputWorkspace= 'AddFilesSumTempory') + if isFirstDataSetEvent: + Plus(LHSWorkspace='AddFilesSumTempory_monitors',RHSWorkspace= 'AddFilesNewTempory_monitors',OutputWorkspace= 'AddFilesSumTempory_monitors') + DeleteWorkspace("AddFilesNewTempory") + if isFirstDataSetEvent: + DeleteWorkspace("AddFilesNewTempory_monitors") + + except ValueError as e: + error = 'Error opening file ' + userEntry+': ' + str(e) + print error + logger.notice(error) + if 'AddFilesSumTempory' in mtd : DeleteWorkspace('AddFilesSumTempory') + return "" + except Exception as e: + error = 'Error finding files: ' + str(e) print error logger.notice(error) for workspaceName in ('AddFilesSumTempory','AddFilesNewTempory'): @@ -62,221 +84,199 @@ def add_runs(runs, inst='sans2d', defType='.nxs', rawTypes=('.raw', '.s*', 'add' DeleteWorkspace(workspaceName) return "" - Plus(LHSWorkspace='AddFilesSumTempory',RHSWorkspace= 'AddFilesNewTempory',OutputWorkspace= 'AddFilesSumTempory') - if isFirstDataSetEvent: - Plus(LHSWorkspace='AddFilesSumTempory_monitors',RHSWorkspace= 'AddFilesNewTempory_monitors',OutputWorkspace= 'AddFilesSumTempory_monitors') - DeleteWorkspace("AddFilesNewTempory") - if isFirstDataSetEvent: - DeleteWorkspace("AddFilesNewTempory_monitors") - - except ValueError as e: - error = 'Error opening file ' + userEntry+': ' + str(e) - print error - logger.notice(error) - if 'AddFilesSumTempory' in mtd : DeleteWorkspace('AddFilesSumTempory') - return "" - except Exception as e: - error = 'Error finding files: ' + str(e) - print error - logger.notice(error) - for workspaceName in ('AddFilesSumTempory','AddFilesNewTempory'): - if workspaceName in mtd: - DeleteWorkspace(workspaceName) - return "" - # in case of event file force it into a histogram workspace - if isFirstDataSetEvent: - wsInMonitor = mtd['AddFilesSumTempory_monitors'] - if binning == 'Monitors': - monX = wsInMonitor.dataX(0) - binning = str(monX[0]) - binGap = monX[1] - monX[0] - binning = binning + "," + str(binGap) - for j in range(2,len(monX)): - nextBinGap = monX[j] - monX[j-1] - if nextBinGap != binGap: - binGap = nextBinGap - binning = binning + "," + str(monX[j-1]) + "," + str(binGap) - binning = binning + "," + str(monX[len(monX)-1]) - - logger.notice(binning) - Rebin(InputWorkspace='AddFilesSumTempory',OutputWorkspace='AddFilesSumTempory_Rebin',Params= binning, PreserveEvents=False) + if isFirstDataSetEvent: + wsInMonitor = mtd['AddFilesSumTempory_monitors'] + if binning == 'Monitors': + monX = wsInMonitor.dataX(0) + binning = str(monX[0]) + binGap = monX[1] - monX[0] + binning = binning + "," + str(binGap) + for j in range(2,len(monX)): + nextBinGap = monX[j] - monX[j-1] + if nextBinGap != binGap: + binGap = nextBinGap + binning = binning + "," + str(monX[j-1]) + "," + str(binGap) + binning = binning + "," + str(monX[len(monX)-1]) + + logger.notice(binning) + Rebin(InputWorkspace='AddFilesSumTempory',OutputWorkspace='AddFilesSumTempory_Rebin',Params= binning, PreserveEvents=False) # loading the nexus file using LoadNexus is necessary because it has some metadata # that is not in LoadEventNexus. This must be fixed. - filename, ext = _makeFilename(runs[0], defType, inst) - LoadNexus(Filename=filename, OutputWorkspace='AddFilesSumTempory', SpectrumMax=wsInMonitor.getNumberHistograms()) + filename, ext = _makeFilename(runs[0], defType, inst) + LoadNexus(Filename=filename, OutputWorkspace='AddFilesSumTempory', SpectrumMax=wsInMonitor.getNumberHistograms()) # User may have selected a binning which is different from the default - Rebin(InputWorkspace='AddFilesSumTempory',OutputWorkspace='AddFilesSumTempory',Params= binning) + Rebin(InputWorkspace='AddFilesSumTempory',OutputWorkspace='AddFilesSumTempory',Params= binning) # For now the monitor binning must be the same as the detector binning # since otherwise both cannot exist in the same output histogram file - Rebin(InputWorkspace='AddFilesSumTempory_monitors',OutputWorkspace='AddFilesSumTempory_monitors',Params= binning) + Rebin(InputWorkspace='AddFilesSumTempory_monitors',OutputWorkspace='AddFilesSumTempory_monitors',Params= binning) - wsInMonitor = mtd['AddFilesSumTempory_monitors'] - wsOut = mtd['AddFilesSumTempory'] - wsInDetector = mtd['AddFilesSumTempory_Rebin'] + wsInMonitor = mtd['AddFilesSumTempory_monitors'] + wsOut = mtd['AddFilesSumTempory'] + wsInDetector = mtd['AddFilesSumTempory_Rebin'] - mon_n = wsInMonitor.getNumberHistograms() - for i in range(mon_n): - wsOut.setY(i,wsInMonitor.dataY(i)) - wsOut.setE(i,wsInMonitor.dataE(i)) - ConjoinWorkspaces(wsOut, wsInDetector, CheckOverlapping=True) + mon_n = wsInMonitor.getNumberHistograms() + for i in range(mon_n): + wsOut.setY(i,wsInMonitor.dataY(i)) + wsOut.setE(i,wsInMonitor.dataE(i)) + ConjoinWorkspaces(wsOut, wsInDetector, CheckOverlapping=True) - if 'AddFilesSumTempory_Rebin' in mtd : DeleteWorkspace('AddFilesSumTempory_Rebin') + if 'AddFilesSumTempory_Rebin' in mtd : DeleteWorkspace('AddFilesSumTempory_Rebin') - lastFile = os.path.splitext(lastFile)[0] + lastFile = os.path.splitext(lastFile)[0] # now save the added file - outFile = lastFile+'-add.'+'nxs' - logger.notice('writing file: '+outFile) - if period == 1 or period == _NO_INDIVIDUAL_PERIODS: + outFile = lastFile+'-add.'+'nxs' + logger.notice('writing file: '+outFile) + if period == 1 or period == _NO_INDIVIDUAL_PERIODS: #replace the file the first time around - SaveNexusProcessed(InputWorkspace="AddFilesSumTempory", + SaveNexusProcessed(InputWorkspace="AddFilesSumTempory", Filename=outFile, Append=False) - else: + else: #then append - SaveNexusProcessed("AddFilesSumTempory", outFile, Append=True) + SaveNexusProcessed("AddFilesSumTempory", outFile, Append=True) - DeleteWorkspace("AddFilesSumTempory") - if isFirstDataSetEvent: + DeleteWorkspace("AddFilesSumTempory") + if isFirstDataSetEvent: DeleteWorkspace("AddFilesSumTempory_monitors") - if period == num_periods: - break + if period == num_periods: + break - if period == _NO_INDIVIDUAL_PERIODS: - break - else: - period += 1 + if period == _NO_INDIVIDUAL_PERIODS: + break + else: + period += 1 #this adds the path to the filename - path,base = os.path.split(outFile) - if path == '' or base not in os.listdir(path): - path = config['defaultsave.directory'] + path - assert(base in os.listdir(path)) - pathout = path - if logFile: - _copyLog(lastPath, logFile, pathout) + path,base = os.path.split(outFile) + if path == '' or base not in os.listdir(path): + path = config['defaultsave.directory'] + path + assert(base in os.listdir(path)) + pathout = path + if logFile: + _copyLog(lastPath, logFile, pathout) - return 'The following file has been created:\n'+outFile + return 'The following file has been created:\n'+outFile def _can_load_periods(runs, defType, rawTypes): - """ + """ Searches through the supplied list of run file names and returns False if some appear to be raw files else True """ - for i in runs: - dummy, ext = os.path.splitext(i) - if ext == '': ext = defType - if _isType(ext, rawTypes): - return False + for i in runs: + dummy, ext = os.path.splitext(i) + if ext == '': ext = defType + if _isType(ext, rawTypes): + return False #no raw files were found, assume we can specify the period number for each - return True + return True def _makeFilename(entry, ext, inst) : - """ + """ If entry not already a valid filename make it into one """ - try : - runNum = int(entry) #the user entered something that translates to a run number, convert it to a file - filename=inst+_padZero(runNum, inst)+ext - except ValueError : #we don't have a run number, assume it's a valid filename - filename = entry - dummy, ext = os.path.splitext(filename) + try : + runNum = int(entry) #the user entered something that translates to a run number, convert it to a file + filename=inst+_padZero(runNum, inst)+ext + except ValueError : #we don't have a run number, assume it's a valid filename + filename = entry + dummy, ext = os.path.splitext(filename) - return filename, ext + return filename, ext def _loadWS(entry, ext, inst, wsName, rawTypes, period=_NO_INDIVIDUAL_PERIODS) : - filename, ext = _makeFilename(entry, ext, inst) + filename, ext = _makeFilename(entry, ext, inst) - logger.notice('reading file: '+filename) + logger.notice('reading file: '+filename) - if period != _NO_INDIVIDUAL_PERIODS: + if period != _NO_INDIVIDUAL_PERIODS: #load just a single period - outWs = Load(Filename=filename, OutputWorkspace=wsName, EntryNumber=period) - else: - outWs = Load(Filename=filename,OutputWorkspace=wsName) + outWs = Load(Filename=filename, OutputWorkspace=wsName, EntryNumber=period) + else: + outWs = Load(Filename=filename,OutputWorkspace=wsName) - props = outWs.getHistory().lastAlgorithm() + props = outWs.getHistory().lastAlgorithm() - isDataSetEvent = False - wsDataSet = mtd[wsName] - if hasattr(wsDataSet, 'getNumberEvents'): - isDataSetEvent = True + isDataSetEvent = False + wsDataSet = mtd[wsName] + if hasattr(wsDataSet, 'getNumberEvents'): + isDataSetEvent = True - if isDataSetEvent: - LoadEventNexus(Filename=filename,OutputWorkspace=wsName, LoadMonitors=True) - runDetails = mtd[wsName].getRun() - timeArray = runDetails.getLogData("proton_charge").times + if isDataSetEvent: + LoadEventNexus(Filename=filename,OutputWorkspace=wsName, LoadMonitors=True) + runDetails = mtd[wsName].getRun() + timeArray = runDetails.getLogData("proton_charge").times # There should never be a time increment in the proton charge larger than say "two weeks" # SANS2D currently is run at 10 frames per second. This may be increated to 5Hz # (step of 0.2 sec). Although time between frames may be larger due to having the SMP veto switched on, # but hopefully not longer than two weeks! - for i in range(len(timeArray)-1): + for i in range(len(timeArray)-1): # cal time dif in seconds - timeDif = (timeArray[i+1].total_nanoseconds()-timeArray[i].total_nanoseconds())*1e-9 - if timeDif > 172800: - sanslog.warning('Time increments in the proton charge log of ' + filename + ' are suspicious large.' + + timeDif = (timeArray[i+1].total_nanoseconds()-timeArray[i].total_nanoseconds())*1e-9 + if timeDif > 172800: + sanslog.warning('Time increments in the proton charge log of ' + filename + ' are suspicious large.' + ' For example a time difference of ' + str(timeDif) + " seconds has been observed.") - break + break - path = props.getPropertyValue('FileName') - path, fName = os.path.split(path) - if path.find('/') == -1: + path = props.getPropertyValue('FileName') + path, fName = os.path.split(path) + if path.find('/') == -1: #looks like we're on a windows system, convert the directory separators - path = path.replace('\\', '/') + path = path.replace('\\', '/') - if _isType(ext, rawTypes): - LoadSampleDetailsFromRaw(InputWorkspace=wsName,Filename= path+'/'+fName) + if _isType(ext, rawTypes): + LoadSampleDetailsFromRaw(InputWorkspace=wsName,Filename= path+'/'+fName) - logFile = None + logFile = None #change below when logs in Nexus files work file types of .raw need their log files to be copied too - if True:#_isType(ext, rawTypes): - logFile = os.path.splitext(fName)[0]+'.log' + if True:#_isType(ext, rawTypes): + logFile = os.path.splitext(fName)[0]+'.log' - try: - samp = mtd[wsName].getRun() - numPeriods = samp.getLogData('nperiods').value - except: + try: + samp = mtd[wsName].getRun() + numPeriods = samp.getLogData('nperiods').value + except: #assume the run file didn't support multi-period data and so there is only one period - numPeriods = 1 + numPeriods = 1 - return path, fName, logFile, numPeriods, isDataSetEvent + return path, fName, logFile, numPeriods, isDataSetEvent def _padZero(runNum, inst): - numDigits = config.getInstrument(inst).zeroPadding(0) - run = str(runNum).zfill(numDigits) - return run + numDigits = config.getInstrument(inst).zeroPadding(0) + run = str(runNum).zfill(numDigits) + return run ########################################## # returns true if ext is in the tuple allTypes, ext # is intended to be a file extension and allTypes a # list of allowed extensions. '*' at the end is supported def _isType(ext, allTypes): - for oneType in allTypes: - oneType = str(oneType) - if oneType.endswith('*') : - oneType = oneType[0:len(oneType)-1] - if ext.startswith(oneType) : - return True - else : - if ext == oneType : - return True - return False + for oneType in allTypes: + oneType = str(oneType) + if oneType.endswith('*') : + oneType = oneType[0:len(oneType)-1] + if ext.startswith(oneType) : + return True + else : + if ext == oneType : + return True + return False def _copyLog(lastPath, logFile, pathout): - try : - logFile = os.path.join(lastPath, logFile) - if os.path.exists(logFile): - copyfile(logFile, os.path.join(pathout, os.path.basename(logFile))) - else: - logger.notice("Could not find log file %s" % logFile) - except Exception, reason: - error = 'Error copying log file ' + logFile + ' to directory ' + pathout+'\n' - print error - logger.notice(error) + try : + logFile = os.path.join(lastPath, logFile) + if os.path.exists(logFile): + copyfile(logFile, os.path.join(pathout, os.path.basename(logFile))) + else: + logger.notice("Could not find log file %s" % logFile) + except Exception, reason: + error = 'Error copying log file ' + logFile + ' to directory ' + pathout+'\n' + print error + logger.notice(error) if __name__ == '__main__': diff --git a/Code/Mantid/scripts/SANS/isis_reducer.py b/Code/Mantid/scripts/SANS/isis_reducer.py index a5c5389ab84f..b81d902301fe 100644 --- a/Code/Mantid/scripts/SANS/isis_reducer.py +++ b/Code/Mantid/scripts/SANS/isis_reducer.py @@ -313,7 +313,7 @@ def get_out_ws_name(self, show_period=True): name += '_' + self.to_Q.output_type name += '_' + self.to_wavelen.get_range() if self.to_Q.get_output_type() == "1D": - name += self.mask.get_phi_limits_tag() + name += self.mask.get_phi_limits_tag() if self.getNumSlices() > 0: limits = self.getCurrSliceLimit() @@ -421,7 +421,7 @@ def run_from_raw(self): return self._reduce(init=False, post=True) def set_Q_output_type(self, out_type): - self.to_Q.set_output_type(out_type) + self.to_Q.set_output_type(out_type) def pre_process(self): """ @@ -566,9 +566,9 @@ def set_beam_finder(self, finder, det_bank='rear'): """ if issubclass(finder.__class__, isis_reduction_steps.BaseBeamFinder) or finder is None: if det_bank == 'front': - self._front_beam_finder = finder + self._front_beam_finder = finder else: - self._beam_finder = finder + self._beam_finder = finder else: raise RuntimeError, "Reducer.set_beam_finder expects an object of class ReductionStep" diff --git a/Code/Mantid/scripts/SANS/isis_reduction_steps.py b/Code/Mantid/scripts/SANS/isis_reduction_steps.py index 13ec11a10297..c56ae0991fe4 100644 --- a/Code/Mantid/scripts/SANS/isis_reduction_steps.py +++ b/Code/Mantid/scripts/SANS/isis_reduction_steps.py @@ -717,7 +717,7 @@ def parse_instruction(self, instName, details): else: _issueWarning('Unrecognized masking line "' + details + '"') else: - _issueWarning('Unrecognized masking line "' + details + '"') + _issueWarning('Unrecognized masking line "' + details + '"') def add_mask_string(self, mask_string, detect): if detect.upper() == 'FRONT' or detect.upper() == 'HAB': @@ -858,9 +858,9 @@ def get_phi_limits_tag(self): @return 'Phi'low'_'high if it has been set """ if self.mask_phi and self._lim_phi_xml != '' and (abs(self.phi_max - self.phi_min) != 180.0): - return 'Phi'+str(self.phi_min)+'_'+str(self.phi_max) + return 'Phi'+str(self.phi_min)+'_'+str(self.phi_max) else: - return '' + return '' def set_phi_limit(self, phimin, phimax, phimirror, override=True): ''' @@ -1695,7 +1695,7 @@ def set_gravity(self, flag, override=True): self._grav_set = True if (not self._grav_set) or override: - self._use_gravity = bool(flag) + self._use_gravity = bool(flag) else: msg = "User file can't override previous gravity setting, do gravity correction remains " + str(self._use_gravity) print msg @@ -1992,26 +1992,26 @@ def read_line(self, line, reducer): # SET CENTRE/HAB X Y main_str_pos = upper_line.find('MAIN') hab_str_pos = upper_line.find('HAB') - x_pos = 0.0; - y_pos = 0.0; + x_pos = 0.0 + y_pos = 0.0 if (main_str_pos > 0): - values = upper_line[main_str_pos+5:].split() #remov the SET CENTRE/MAIN - x_pos = float(values[0])/1000.0 - y_pos = float(values[1])/1000.0 + values = upper_line[main_str_pos+5:].split() #remov the SET CENTRE/MAIN + x_pos = float(values[0])/1000.0 + y_pos = float(values[1])/1000.0 elif (hab_str_pos > 0): - values = upper_line[hab_str_pos+4:].split() # remove the SET CENTRE/HAB - print ' convert values ',values - x_pos = float(values[0])/1000.0 - y_pos = float(values[1])/1000.0 + values = upper_line[hab_str_pos+4:].split() # remove the SET CENTRE/HAB + print ' convert values ',values + x_pos = float(values[0])/1000.0 + y_pos = float(values[1])/1000.0 else: - values = upper_line.split() - x_pos = float(values[2])/1000.0 - y_pos = float(values[3])/1000.0 + values = upper_line.split() + x_pos = float(values[2])/1000.0 + y_pos = float(values[3])/1000.0 if (hab_str_pos > 0): - print 'Front values = ',x_pos,y_pos - reducer.set_beam_finder(BaseBeamFinder(x_pos, y_pos),'front') + print 'Front values = ',x_pos,y_pos + reducer.set_beam_finder(BaseBeamFinder(x_pos, y_pos),'front') else: - reducer.set_beam_finder(BaseBeamFinder(x_pos, y_pos)) + reducer.set_beam_finder(BaseBeamFinder(x_pos, y_pos)) elif upper_line.startswith('SET SCALES'): values = upper_line.split() @@ -2077,9 +2077,9 @@ def read_line(self, line, reducer): reducer.transmission_calculator.loq_removePromptPeakMax = float(params[2]) else: if reducer.instrument.name() == 'LOQ': - _issueWarning('Incorrectly formatted FIT/MONITOR line, %s, line ignored' % upper_line) + _issueWarning('Incorrectly formatted FIT/MONITOR line, %s, line ignored' % upper_line) else: - _issueWarning('FIT/MONITOR line specific to LOQ instrument. Line ignored') + _issueWarning('FIT/MONITOR line specific to LOQ instrument. Line ignored') elif upper_line == 'SANS2D' or upper_line == 'LOQ': self._check_instrument(upper_line, reducer) @@ -2532,9 +2532,9 @@ def _read_calibfile_line(self, arguments, reducer): path2file = parts[1] try: - file_path, suggested_name = getFileAndName(path2file) - __calibrationWs = Load(file_path, OutputWorkspace=suggested_name) - reducer.instrument.setCalibrationWorkspace(__calibrationWs) + file_path, suggested_name = getFileAndName(path2file) + __calibrationWs = Load(file_path, OutputWorkspace=suggested_name) + reducer.instrument.setCalibrationWorkspace(__calibrationWs) except: # If we throw a runtime here, then we cannot execute 'Load Data'. raise RuntimeError("Invalid input for tube calibration file (" + path2file + " ).\n" \ diff --git a/Code/Mantid/scripts/SCD_Reduction/ReduceDictionary.py b/Code/Mantid/scripts/SCD_Reduction/ReduceDictionary.py index 63749321d7d5..1997b44f22ec 100644 --- a/Code/Mantid/scripts/SCD_Reduction/ReduceDictionary.py +++ b/Code/Mantid/scripts/SCD_Reduction/ReduceDictionary.py @@ -14,44 +14,44 @@ # def LoadDictionary( *filenames, **kwargs ): # create a dictionary to load into - params_dictionary = kwargs.get("existing", {}) + params_dictionary = kwargs.get("existing", {}) # create a list of run numbers - run_nums = params_dictionary.get("run_nums", []) + run_nums = params_dictionary.get("run_nums", []) - file = open(filenames[0]) - for line in file: - line = line.strip(); - line = line.rstrip(); - if (not line.startswith('#')) and len(line) > 2: - words = line.split() + file = open(filenames[0]) + for line in file: + line = line.strip() + line = line.rstrip() + if (not line.startswith('#')) and len(line) > 2: + words = line.split() # error check the number of values - if len(words) < 2: - print "Syntax Error On Line: " + line + if len(words) < 2: + print "Syntax Error On Line: " + line # set the value - else: - (key, value) = words[0:2] + else: + (key, value) = words[0:2] # fix up special values - if value.lower() == "none": - value = None - elif value.lower() == "true": - value = True - elif value.lower() == "false": - value = False + if value.lower() == "none": + value = None + elif value.lower() == "true": + value = True + elif value.lower() == "false": + value = False # set the values - if key == "run_nums": - run_nums.extend(ParseRunList(value)) - else: - params_dictionary[key] = value + if key == "run_nums": + run_nums.extend(ParseRunList(value)) + else: + params_dictionary[key] = value - params_dictionary["run_nums"]=run_nums + params_dictionary["run_nums"]=run_nums # it isn't awesome without recursion - if len(filenames) > 1: - return LoadDictionary(*filenames[1:], existing=params_dictionary) - else: - return params_dictionary; + if len(filenames) > 1: + return LoadDictionary(*filenames[1:], existing=params_dictionary) + else: + return params_dictionary # # Return a list of run numbers from a string containing a comma separated @@ -59,17 +59,17 @@ def LoadDictionary( *filenames, **kwargs ): # with a colon separator. # def ParseRunList( run_string ): - run_list = [] - groups = run_string.split(",") - for group in groups: - runs = group.split(":") - if len(runs) == 1: - run_list.append( runs[0] ) - else: - first = int(runs[0]) - last = int(runs[1]) - for run in range(first, last+1): - run_list.append(str(run)) + run_list = [] + groups = run_string.split(",") + for group in groups: + runs = group.split(":") + if len(runs) == 1: + run_list.append( runs[0] ) + else: + first = int(runs[0]) + last = int(runs[1]) + for run in range(first, last+1): + run_list.append(str(run)) - return run_list + return run_list diff --git a/Code/Mantid/scripts/SCD_Reduction/ReduceSCD_OneRun.py b/Code/Mantid/scripts/SCD_Reduction/ReduceSCD_OneRun.py index 68db7ee58d43..4ba4a06d53fb 100644 --- a/Code/Mantid/scripts/SCD_Reduction/ReduceSCD_OneRun.py +++ b/Code/Mantid/scripts/SCD_Reduction/ReduceSCD_OneRun.py @@ -54,8 +54,8 @@ # Get the config file name and the run number to process from the command line # if (len(sys.argv) < 3): - print "You MUST give the config file name(s) and run number on the command line" - exit(0) + print "You MUST give the config file name(s) and run number on the command line" + exit(0) config_files = sys.argv[1:-1] run = sys.argv[-1] @@ -125,18 +125,18 @@ # short_filename = "%s_%s_event.nxs" % (instrument_name, str(run)) if data_directory is not None: - full_name = data_directory + "/" + short_filename + full_name = data_directory + "/" + short_filename else: - candidates = FileFinder.findRuns(short_filename) - full_name = "" - for item in candidates: - if os.path.exists(item): - full_name = str(item) - - if not full_name.endswith('nxs'): - print "Exiting since the data_directory was not specified and" - print "findnexus failed for event NeXus file: " + instrument_name + " " + str(run) - exit(0) + candidates = FileFinder.findRuns(short_filename) + full_name = "" + for item in candidates: + if os.path.exists(item): + full_name = str(item) + + if not full_name.endswith('nxs'): + print "Exiting since the data_directory was not specified and" + print "findnexus failed for event NeXus file: " + instrument_name + " " + str(run) + exit(0) print "\nProcessing File: " + full_name + " ......\n" @@ -157,11 +157,11 @@ # can not be None. TOPAZ has one calibration file, but SNAP may have two. # if (calibration_file_1 is not None ) or (calibration_file_2 is not None): - if (calibration_file_1 is None ): - calibration_file_1 = "" - if (calibration_file_2 is None ): - calibration_file_2 = "" - LoadIsawDetCal( event_ws, + if (calibration_file_1 is None ): + calibration_file_1 = "" + if (calibration_file_2 is None ): + calibration_file_2 = "" + LoadIsawDetCal( event_ws, Filename=calibration_file_1, Filename2=calibration_file_2 ) monitor_ws = LoadNexusMonitors( Filename=full_name ) @@ -196,19 +196,19 @@ # Read or find UB for the run if read_UB: # Read orientation matrix from file - LoadIsawUB(InputWorkspace=peaks_ws, Filename=UB_filename) - if optimize_UB: + LoadIsawUB(InputWorkspace=peaks_ws, Filename=UB_filename) + if optimize_UB: # Optimize the specifiec UB for better peak prediction - uc_a = peaks_ws.sample().getOrientedLattice().a() - uc_b = peaks_ws.sample().getOrientedLattice().b() - uc_c = peaks_ws.sample().getOrientedLattice().c() - uc_alpha = peaks_ws.sample().getOrientedLattice().alpha() - uc_beta = peaks_ws.sample().getOrientedLattice().beta() - uc_gamma = peaks_ws.sample().getOrientedLattice().gamma() - FindUBUsingLatticeParameters(PeaksWorkspace= peaks_ws,a=uc_a,b=uc_b,c=uc_c,alpha=uc_alpha,beta=uc_beta, gamma=uc_gamma,NumInitial=num_peaks_to_find,Tolerance=tolerance) + uc_a = peaks_ws.sample().getOrientedLattice().a() + uc_b = peaks_ws.sample().getOrientedLattice().b() + uc_c = peaks_ws.sample().getOrientedLattice().c() + uc_alpha = peaks_ws.sample().getOrientedLattice().alpha() + uc_beta = peaks_ws.sample().getOrientedLattice().beta() + uc_gamma = peaks_ws.sample().getOrientedLattice().gamma() + FindUBUsingLatticeParameters(PeaksWorkspace= peaks_ws,a=uc_a,b=uc_b,c=uc_c,alpha=uc_alpha,beta=uc_beta, gamma=uc_gamma,NumInitial=num_peaks_to_find,Tolerance=tolerance) else: # Find a Niggli UB matrix that indexes the peaks in this run - FindUBUsingFFT( PeaksWorkspace=peaks_ws, MinD=min_d, MaxD=max_d, Tolerance=tolerance ) + FindUBUsingFFT( PeaksWorkspace=peaks_ws, MinD=min_d, MaxD=max_d, Tolerance=tolerance ) IndexPeaks( PeaksWorkspace=peaks_ws, Tolerance=tolerance) @@ -227,27 +227,27 @@ # PeakIntegration algorithm. # if integrate_predicted_peaks: - print "PREDICTING peaks to integrate...." - peaks_ws = PredictPeaks( InputWorkspace=peaks_ws, + print "PREDICTING peaks to integrate...." + peaks_ws = PredictPeaks( InputWorkspace=peaks_ws, WavelengthMin=min_pred_wl, WavelengthMax=max_pred_wl, MinDSpacing=min_pred_dspacing, MaxDSpacing=max_pred_dspacing, ReflectionCondition='Primitive' ) else: - print "Only integrating FOUND peaks ...." + print "Only integrating FOUND peaks ...." # # Set the monitor counts for all the peaks that will be integrated # num_peaks = peaks_ws.getNumberPeaks() for i in range(num_peaks): - peak = peaks_ws.getPeak(i) - if use_monitor_counts: - peak.setMonitorCount( monitor_count ) - else: - peak.setMonitorCount( proton_charge ) + peak = peaks_ws.getPeak(i) + if use_monitor_counts: + peak.setMonitorCount( monitor_count ) + else: + peak.setMonitorCount( proton_charge ) if use_monitor_counts: - print '\n*** Beam monitor counts used for scaling.' + print '\n*** Beam monitor counts used for scaling.' else: - print '\n*** Proton charge x 1000 used for scaling.\n' + print '\n*** Proton charge x 1000 used for scaling.\n' if use_sphere_integration: # @@ -256,12 +256,12 @@ # workspace to do raw integration (we don't need high resolution or # LorentzCorrection to do the raw sphere integration ) # - MDEW = ConvertToMD( InputWorkspace=event_ws, QDimensions="Q3D", + MDEW = ConvertToMD( InputWorkspace=event_ws, QDimensions="Q3D", dEAnalysisMode="Elastic", QConversionScales="Q in A^-1", LorentzCorrection='0', MinValues=minVals, MaxValues=maxVals, SplitInto='2', SplitThreshold='500',MaxRecursionDepth='10' ) - peaks_ws = IntegratePeaksMD( InputWorkspace=MDEW, PeakRadius=peak_radius, + peaks_ws = IntegratePeaksMD( InputWorkspace=MDEW, PeakRadius=peak_radius, CoordinatesToUse="Q (sample frame)", BackgroundOuterRadius=bkg_outer_radius, BackgroundInnerRadius=bkg_inner_radius, @@ -274,12 +274,12 @@ # workspace to do raw integration (we don't need high resolution or # LorentzCorrection to do the raw sphere integration ) # - MDEW = ConvertToMD( InputWorkspace=event_ws, QDimensions="Q3D", + MDEW = ConvertToMD( InputWorkspace=event_ws, QDimensions="Q3D", dEAnalysisMode="Elastic", QConversionScales="Q in A^-1", LorentzCorrection='0', MinValues=minVals, MaxValues=maxVals, SplitInto='2', SplitThreshold='500',MaxRecursionDepth='10' ) - peaks_ws = IntegratePeaksMD( InputWorkspace=MDEW, PeakRadius=peak_radius, + peaks_ws = IntegratePeaksMD( InputWorkspace=MDEW, PeakRadius=peak_radius, CoordinatesToUse="Q (sample frame)", BackgroundOuterRadius=bkg_outer_radius, BackgroundInnerRadius=bkg_inner_radius, @@ -291,15 +291,15 @@ ProfileFunction=cylinder_profile_fit) elif use_fit_peaks_integration: - event_ws = Rebin( InputWorkspace=event_ws, + event_ws = Rebin( InputWorkspace=event_ws, Params=rebin_params, PreserveEvents=preserve_events ) - peaks_ws = PeakIntegration( InPeaksWorkspace=peaks_ws, InputWorkspace=event_ws, + peaks_ws = PeakIntegration( InPeaksWorkspace=peaks_ws, InputWorkspace=event_ws, IkedaCarpenterTOF=use_ikeda_carpenter, MatchingRunNo=True, NBadEdgePixels=n_bad_edge_pixels ) elif use_ellipse_integration: - peaks_ws= IntegrateEllipsoids( InputWorkspace=event_ws, PeaksWorkspace = peaks_ws, + peaks_ws= IntegrateEllipsoids( InputWorkspace=event_ws, PeaksWorkspace = peaks_ws, RegionRadius = ellipse_region_radius, SpecifySize = ellipse_size_specified, PeakSize = peak_radius, @@ -307,13 +307,13 @@ BackgroundInnerSize = bkg_inner_radius ) elif use_cylindrical_integration: - profiles_filename = output_directory + "/" + instrument_name + '_' + run + '.profiles' - MDEW = ConvertToMD( InputWorkspace=event_ws, QDimensions="Q3D", + profiles_filename = output_directory + "/" + instrument_name + '_' + run + '.profiles' + MDEW = ConvertToMD( InputWorkspace=event_ws, QDimensions="Q3D", dEAnalysisMode="Elastic", QConversionScales="Q in A^-1", LorentzCorrection='0', MinValues=minVals, MaxValues=maxVals, SplitInto='2', SplitThreshold='500',MaxRecursionDepth='10' ) - peaks_ws = IntegratePeaksMD( InputWorkspace=MDEW, PeakRadius=cylinder_radius, + peaks_ws = IntegratePeaksMD( InputWorkspace=MDEW, PeakRadius=cylinder_radius, CoordinatesToUse="Q (sample frame)", Cylinder='1', CylinderLength = cylinder_length, PercentBackground = '20', ProfileFunction = 'NoFit', @@ -331,25 +331,25 @@ # Print warning if user is trying to integrate using the cylindrical method and transorm the cell if use_cylindrical_integration: - if (not cell_type is None) or (not centering is None): - print "WARNING: Cylindrical profiles are NOT transformed!!!" + if (not cell_type is None) or (not centering is None): + print "WARNING: Cylindrical profiles are NOT transformed!!!" # # If requested, also switch to the specified conventional cell and save the # corresponding matrix and integrate file # else: - if (not cell_type is None) and (not centering is None) : - run_conventional_matrix_file = output_directory + "/" + run + "_" + \ + if (not cell_type is None) and (not centering is None) : + run_conventional_matrix_file = output_directory + "/" + run + "_" + \ cell_type + "_" + centering + ".mat" - run_conventional_integrate_file = output_directory + "/" + run + "_" + \ + run_conventional_integrate_file = output_directory + "/" + run + "_" + \ cell_type + "_" + centering + ".integrate" - SelectCellOfType( PeaksWorkspace=peaks_ws, + SelectCellOfType( PeaksWorkspace=peaks_ws, CellType=cell_type, Centering=centering, AllowPermutations=allow_perm, Apply=True, Tolerance=tolerance ) - SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, + SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, Filename=run_conventional_integrate_file ) - SaveIsawUB( InputWorkspace=peaks_ws, Filename=run_conventional_matrix_file ) + SaveIsawUB( InputWorkspace=peaks_ws, Filename=run_conventional_matrix_file ) end_time = time.time() print '\nReduced run ' + str(run) + ' in ' + str(end_time - start_time) + ' sec' diff --git a/Code/Mantid/scripts/SCD_Reduction/ReduceSCD_Parallel.py b/Code/Mantid/scripts/SCD_Reduction/ReduceSCD_Parallel.py index 94f90ff2aede..c9526a94b1e5 100644 --- a/Code/Mantid/scripts/SCD_Reduction/ReduceSCD_Parallel.py +++ b/Code/Mantid/scripts/SCD_Reduction/ReduceSCD_Parallel.py @@ -54,14 +54,14 @@ # a thread that starts a command line process to reduce one run. # class ProcessThread ( threading.Thread ): - command = "" + command = "" - def setCommand( self, command="" ): - self.command = command + def setCommand( self, command="" ): + self.command = command - def run ( self ): - print 'STARTING PROCESS: ' + self.command - os.system( self.command ) + def run ( self ): + print 'STARTING PROCESS: ' + self.command + os.system( self.command ) # ------------------------------------------------------------------------- @@ -69,8 +69,8 @@ def run ( self ): # Get the config file name from the command line # if (len(sys.argv) < 2): - print "You MUST give the config file name on the command line" - exit(0) + print "You MUST give the config file name on the command line" + exit(0) config_files = sys.argv[1:] @@ -105,7 +105,7 @@ def run ( self ): # determine what python executable to launch new jobs with python = sys.executable if python is None: # not all platforms define this variable - python = 'python' + python = 'python' # # Make the list of separate process commands. If a slurm queue name @@ -115,14 +115,14 @@ def run ( self ): list=[] index = 0 for r_num in run_nums: - list.append( ProcessThread() ) - cmd = '%s %s %s %s' % (python, reduce_one_run_script, " ".join(config_files), str(r_num)) - if slurm_queue_name is not None: - console_file = output_directory + "/" + str(r_num) + "_output.txt" - cmd = 'srun -p ' + slurm_queue_name + \ + list.append( ProcessThread() ) + cmd = '%s %s %s %s' % (python, reduce_one_run_script, " ".join(config_files), str(r_num)) + if slurm_queue_name is not None: + console_file = output_directory + "/" + str(r_num) + "_output.txt" + cmd = 'srun -p ' + slurm_queue_name + \ ' --cpus-per-task=3 -J ReduceSCD_Parallel.py -o ' + console_file + ' ' + cmd - list[index].setCommand( cmd ) - index = index + 1 + list[index].setCommand( cmd ) + index = index + 1 # # Now create and start a thread for each command to run the commands in parallel, @@ -131,17 +131,17 @@ def run ( self ): all_done = False active_list=[] while not all_done: - if ( len(list) > 0 and len(active_list) < max_processes ): - thread = list[0] - list.remove(thread) - active_list.append( thread ) - thread.start() - time.sleep(2) - for thread in active_list: - if not thread.isAlive(): - active_list.remove( thread ) - if len(list) == 0 and len(active_list) == 0 : - all_done = True + if ( len(list) > 0 and len(active_list) < max_processes ): + thread = list[0] + list.remove(thread) + active_list.append( thread ) + thread.start() + time.sleep(2) + for thread in active_list: + if not thread.isAlive(): + active_list.remove( thread ) + if len(list) == 0 and len(active_list) == 0 : + all_done = True print "\n**************************************************************************************" print "************** Completed Individual Runs, Starting to Combine Results ****************" @@ -157,104 +157,104 @@ def run ( self ): first_time = True if not use_cylindrical_integration: - for r_num in run_nums: - one_run_file = output_directory + '/' + str(r_num) + '_Niggli.integrate' - peaks_ws = LoadIsawPeaks( Filename=one_run_file ) - if first_time: - if UseFirstLattice and not read_UB: + for r_num in run_nums: + one_run_file = output_directory + '/' + str(r_num) + '_Niggli.integrate' + peaks_ws = LoadIsawPeaks( Filename=one_run_file ) + if first_time: + if UseFirstLattice and not read_UB: # Find a UB (using FFT) for the first run to use in the FindUBUsingLatticeParameters - FindUBUsingFFT( PeaksWorkspace=peaks_ws, MinD=min_d, MaxD=max_d, Tolerance=tolerance ) - uc_a = peaks_ws.sample().getOrientedLattice().a() - uc_b = peaks_ws.sample().getOrientedLattice().b() - uc_c = peaks_ws.sample().getOrientedLattice().c() - uc_alpha = peaks_ws.sample().getOrientedLattice().alpha() - uc_beta = peaks_ws.sample().getOrientedLattice().beta() - uc_gamma = peaks_ws.sample().getOrientedLattice().gamma() - SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, Filename=niggli_integrate_file ) - - first_time = False - else: - SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=True, Filename=niggli_integrate_file ) + FindUBUsingFFT( PeaksWorkspace=peaks_ws, MinD=min_d, MaxD=max_d, Tolerance=tolerance ) + uc_a = peaks_ws.sample().getOrientedLattice().a() + uc_b = peaks_ws.sample().getOrientedLattice().b() + uc_c = peaks_ws.sample().getOrientedLattice().c() + uc_alpha = peaks_ws.sample().getOrientedLattice().alpha() + uc_beta = peaks_ws.sample().getOrientedLattice().beta() + uc_gamma = peaks_ws.sample().getOrientedLattice().gamma() + SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, Filename=niggli_integrate_file ) + + first_time = False + else: + SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=True, Filename=niggli_integrate_file ) # # Load the combined file and re-index all of the peaks together. # Save them back to the combined Niggli file (Or selcted UB file if in use...) # - peaks_ws = LoadIsawPeaks( Filename=niggli_integrate_file ) + peaks_ws = LoadIsawPeaks( Filename=niggli_integrate_file ) # # Find a Niggli UB matrix that indexes the peaks in this run # Load UB instead of Using FFT #Index peaks using UB from UB of initial orientation run/or combined runs from first iteration of crystal orientation refinement - if read_UB: - LoadIsawUB(InputWorkspace=peaks_ws, Filename=UB_filename) - if UseFirstLattice: + if read_UB: + LoadIsawUB(InputWorkspace=peaks_ws, Filename=UB_filename) + if UseFirstLattice: # Find UB using lattice parameters from the specified file - uc_a = peaks_ws.sample().getOrientedLattice().a() - uc_b = peaks_ws.sample().getOrientedLattice().b() - uc_c = peaks_ws.sample().getOrientedLattice().c() - uc_alpha = peaks_ws.sample().getOrientedLattice().alpha() - uc_beta = peaks_ws.sample().getOrientedLattice().beta() - uc_gamma = peaks_ws.sample().getOrientedLattice().gamma() - FindUBUsingLatticeParameters(PeaksWorkspace= peaks_ws,a=uc_a,b=uc_b,c=uc_c,alpha=uc_alpha,beta=uc_beta, gamma=uc_gamma,NumInitial=num_peaks_to_find,Tolerance=tolerance) + uc_a = peaks_ws.sample().getOrientedLattice().a() + uc_b = peaks_ws.sample().getOrientedLattice().b() + uc_c = peaks_ws.sample().getOrientedLattice().c() + uc_alpha = peaks_ws.sample().getOrientedLattice().alpha() + uc_beta = peaks_ws.sample().getOrientedLattice().beta() + uc_gamma = peaks_ws.sample().getOrientedLattice().gamma() + FindUBUsingLatticeParameters(PeaksWorkspace= peaks_ws,a=uc_a,b=uc_b,c=uc_c,alpha=uc_alpha,beta=uc_beta, gamma=uc_gamma,NumInitial=num_peaks_to_find,Tolerance=tolerance) #OptimizeCrystalPlacement(PeaksWorkspace=peaks_ws,ModifiedPeaksWorkspace=peaks_ws,FitInfoTable='CrystalPlacement_info',MaxIndexingError=tolerance) - elif UseFirstLattice and not read_UB: + elif UseFirstLattice and not read_UB: # Find UB using lattice parameters using the FFT results from first run if no UB file is specified - FindUBUsingLatticeParameters(PeaksWorkspace= peaks_ws,a=uc_a,b=uc_b,c=uc_c,alpha=uc_alpha,beta=uc_beta, gamma=uc_gamma,NumInitial=num_peaks_to_find,Tolerance=tolerance) - else: - FindUBUsingFFT( PeaksWorkspace=peaks_ws, MinD=min_d, MaxD=max_d, Tolerance=tolerance ) + FindUBUsingLatticeParameters(PeaksWorkspace= peaks_ws,a=uc_a,b=uc_b,c=uc_c,alpha=uc_alpha,beta=uc_beta, gamma=uc_gamma,NumInitial=num_peaks_to_find,Tolerance=tolerance) + else: + FindUBUsingFFT( PeaksWorkspace=peaks_ws, MinD=min_d, MaxD=max_d, Tolerance=tolerance ) - IndexPeaks( PeaksWorkspace=peaks_ws, Tolerance=tolerance ) - SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, Filename=niggli_integrate_file ) - SaveIsawUB( InputWorkspace=peaks_ws, Filename=niggli_matrix_file ) + IndexPeaks( PeaksWorkspace=peaks_ws, Tolerance=tolerance ) + SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, Filename=niggli_integrate_file ) + SaveIsawUB( InputWorkspace=peaks_ws, Filename=niggli_matrix_file ) # # If requested, also switch to the specified conventional cell and save the # corresponding matrix and integrate file # if not use_cylindrical_integration: - if (not cell_type is None) and (not centering is None) : - conv_name = output_directory + "/" + exp_name + "_" + cell_type + "_" + centering - conventional_integrate_file = conv_name + ".integrate" - conventional_matrix_file = conv_name + ".mat" + if (not cell_type is None) and (not centering is None) : + conv_name = output_directory + "/" + exp_name + "_" + cell_type + "_" + centering + conventional_integrate_file = conv_name + ".integrate" + conventional_matrix_file = conv_name + ".mat" - SelectCellOfType( PeaksWorkspace=peaks_ws, CellType=cell_type, Centering=centering, + SelectCellOfType( PeaksWorkspace=peaks_ws, CellType=cell_type, Centering=centering, AllowPermutations=allow_perm, Apply=True, Tolerance=tolerance ) - SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, Filename=conventional_integrate_file ) - SaveIsawUB( InputWorkspace=peaks_ws, Filename=conventional_matrix_file ) + SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, Filename=conventional_integrate_file ) + SaveIsawUB( InputWorkspace=peaks_ws, Filename=conventional_matrix_file ) if use_cylindrical_integration: - if (not cell_type is None) or (not centering is None): - print "WARNING: Cylindrical profiles are NOT transformed!!!" + if (not cell_type is None) or (not centering is None): + print "WARNING: Cylindrical profiles are NOT transformed!!!" # Combine *.profiles files - filename = output_directory + '/' + exp_name + '.profiles' - output = open( filename, 'w' ) + filename = output_directory + '/' + exp_name + '.profiles' + output = open( filename, 'w' ) # Read and write the first run profile file with header. - r_num = run_nums[0] - filename = output_directory + '/' + instrument_name + '_' + r_num + '.profiles' - input = open( filename, 'r' ) - file_all_lines = input.read() - output.write(file_all_lines) - input.close() - os.remove(filename) + r_num = run_nums[0] + filename = output_directory + '/' + instrument_name + '_' + r_num + '.profiles' + input = open( filename, 'r' ) + file_all_lines = input.read() + output.write(file_all_lines) + input.close() + os.remove(filename) # Read and write the rest of the runs without the header. - for r_num in run_nums[1:]: - filename = output_directory + '/' + instrument_name + '_' + r_num + '.profiles' - input = open(filename, 'r') - for line in input: - if line[0] == '0': break - output.write(line) - for line in input: - output.write(line) - input.close() - os.remove(filename) + for r_num in run_nums[1:]: + filename = output_directory + '/' + instrument_name + '_' + r_num + '.profiles' + input = open(filename, 'r') + for line in input: + if line[0] == '0': break + output.write(line) + for line in input: + output.write(line) + input.close() + os.remove(filename) # Remove *.integrate file(s) ONLY USED FOR CYLINDRICAL INTEGRATION! - for file in os.listdir(output_directory): - if file.endswith('.integrate'): - os.remove(file) + for file in os.listdir(output_directory): + if file.endswith('.integrate'): + os.remove(file) end_time = time.time() diff --git a/Code/Mantid/scripts/TofConverter.py b/Code/Mantid/scripts/TofConverter.py index 8c395cb911a9..4cee4a0aa5d9 100644 --- a/Code/Mantid/scripts/TofConverter.py +++ b/Code/Mantid/scripts/TofConverter.py @@ -4,12 +4,12 @@ def qapp(): if QtGui.QApplication.instance(): - app = QtGui.QApplication.instance() + app = QtGui.QApplication.instance() else: - app = QtGui.QApplication(sys.argv) + app = QtGui.QApplication(sys.argv) return app app = qapp() reducer = converterGUI.MainWindow()#the main ui class in this file is called MainWindow reducer.show() -app.exec_() \ No newline at end of file +app.exec_() diff --git a/Code/Mantid/scripts/Vates/Inelastic_Workflow.py b/Code/Mantid/scripts/Vates/Inelastic_Workflow.py index 618a36358ae6..de2512098123 100644 --- a/Code/Mantid/scripts/Vates/Inelastic_Workflow.py +++ b/Code/Mantid/scripts/Vates/Inelastic_Workflow.py @@ -4,7 +4,7 @@ #Load an SQW file and internally convert to a Multidimensional event workspace (MDEW) if not mtd.doesExist(ws_in): - LoadSQW(filename, OutputWorkspace=ws_in) + LoadSQW(filename, OutputWorkspace=ws_in) #Bin the workspace in an axis aligned manner. Creates a Histogrammed MD workspace. BinMD(InputWorkspace=ws_in,OutputWorkspace='binned_axis_aligned',AxisAligned=True, diff --git a/Code/Mantid/scripts/Vates/SXD_NaCl.py b/Code/Mantid/scripts/Vates/SXD_NaCl.py index fe550dfa0d75..15f343be3c33 100644 --- a/Code/Mantid/scripts/Vates/SXD_NaCl.py +++ b/Code/Mantid/scripts/Vates/SXD_NaCl.py @@ -39,24 +39,24 @@ def reportUnitCell(peaks_ws): # find the Niggli cell correctly, with all angle 60 degrees, and all sides 3.99 # if use_fft: - FindUBUsingFFT(PeaksWorkspace=peaks_qLab, MinD='3', MaxD='5',Tolerance=0.08) - print '\nNiggli cell found from FindUBUsingFFT:' + FindUBUsingFFT(PeaksWorkspace=peaks_qLab, MinD='3', MaxD='5',Tolerance=0.08) + print '\nNiggli cell found from FindUBUsingFFT:' if use_cubic_lat_par: - FindUBUsingLatticeParameters(PeaksWorkspace=peaks_qLab, a=5.6402,b=5.6402,c=5.6402,alpha=90,beta=90,gamma=90,NumInitial=25,Tolerance=0.12) - print '\nCubic cell found directly from FindUBUsingLatticeParameters' + FindUBUsingLatticeParameters(PeaksWorkspace=peaks_qLab, a=5.6402,b=5.6402,c=5.6402,alpha=90,beta=90,gamma=90,NumInitial=25,Tolerance=0.12) + print '\nCubic cell found directly from FindUBUsingLatticeParameters' if use_Niggli_lat_par: - FindUBUsingLatticeParameters(PeaksWorkspace=peaks_qLab, a=3.9882,b=3.9882,c=3.9882,alpha=60,beta=60,gamma=60,NumInitial=25,Tolerance=0.12) - print '\nNiggli cell found from FindUBUsingLatticeParameters:' + FindUBUsingLatticeParameters(PeaksWorkspace=peaks_qLab, a=3.9882,b=3.9882,c=3.9882,alpha=60,beta=60,gamma=60,NumInitial=25,Tolerance=0.12) + print '\nNiggli cell found from FindUBUsingLatticeParameters:' reportUnitCell(peaks_qLab) IndexPeaks(PeaksWorkspace=peaks_qLab,Tolerance=0.12,RoundHKLs=1) if use_fft or use_Niggli_lat_par: - ShowPossibleCells(PeaksWorkspace=peaks_qLab,MaxScalarError='0.5') - SelectCellOfType(PeaksWorkspace=peaks_qLab, CellType='Cubic', Centering='F', Apply=True) + ShowPossibleCells(PeaksWorkspace=peaks_qLab,MaxScalarError='0.5') + SelectCellOfType(PeaksWorkspace=peaks_qLab, CellType='Cubic', Centering='F', Apply=True) peaks_qLab_Integrated = IntegratePeaksMD(InputWorkspace=QLab, PeaksWorkspace=peaks_qLab, PeakRadius=0.2, BackgroundInnerRadius=0.3, BackgroundOuterRadius=0.4) diff --git a/Code/Mantid/scripts/migrate1to2.py b/Code/Mantid/scripts/migrate1to2.py index a0b7f81909ff..c710b7253946 100644 --- a/Code/Mantid/scripts/migrate1to2.py +++ b/Code/Mantid/scripts/migrate1to2.py @@ -6,4 +6,4 @@ import sys -sys.exit(main.main(sys.argv[1:])) \ No newline at end of file +sys.exit(main.main(sys.argv[1:])) diff --git a/Code/Mantid/scripts/reduction/instrument.py b/Code/Mantid/scripts/reduction/instrument.py index 28aeb890e6a3..3fb42264f30e 100644 --- a/Code/Mantid/scripts/reduction/instrument.py +++ b/Code/Mantid/scripts/reduction/instrument.py @@ -40,9 +40,9 @@ def load_instrument(self): """ wrksp = '__'+self._NAME+'instrument_definition' if not AnalysisDataService.doesExist(wrksp): - api.CreateWorkspace(OutputWorkspace=wrksp,DataX="1",DataY="1",DataE="1") + api.CreateWorkspace(OutputWorkspace=wrksp,DataX="1",DataY="1",DataE="1") #read the information about the instrument that stored in its xml - api.LoadInstrument(Workspace=wrksp, InstrumentName=self._NAME) + api.LoadInstrument(Workspace=wrksp, InstrumentName=self._NAME) return AnalysisDataService.retrieve(wrksp).getInstrument() diff --git a/Code/Mantid/scripts/reduction/instruments/reflectometer/data_manipulation.py b/Code/Mantid/scripts/reduction/instruments/reflectometer/data_manipulation.py index 636b843bc708..16a0e2baba2d 100644 --- a/Code/Mantid/scripts/reduction/instruments/reflectometer/data_manipulation.py +++ b/Code/Mantid/scripts/reduction/instruments/reflectometer/data_manipulation.py @@ -104,7 +104,7 @@ def _load_entry(entry, ws, title=""): else: geo_base_file_x = "REFL_Detector_Grouping_Sum_X.xml" geo_base_file_y = "REFL_Detector_Grouping_Sum_Y.xml" - + if is_pixel_y: grouping_file = os.path.join(instr_dir, "Grouping", geo_base_file_x) diff --git a/Code/Mantid/scripts/reduction/instruments/reflectometer/wks_utility.py b/Code/Mantid/scripts/reduction/instruments/reflectometer/wks_utility.py index 0e37f61ed629..21993d251ff0 100644 --- a/Code/Mantid/scripts/reduction/instruments/reflectometer/wks_utility.py +++ b/Code/Mantid/scripts/reduction/instruments/reflectometer/wks_utility.py @@ -82,7 +82,7 @@ def getSheight(mt, index): else: tag = 'S1VHeight' value = mt_run.getProperty(tag).value - + return value[0] def getS1h(mt=None): @@ -437,7 +437,7 @@ def convertWorkspaceToQ(ws_data, a = y_range[y] _tmp_y_axis = mt1.readY(int(a))[:] - _y_axis[int(y), :] = _tmp_y_axis; + _y_axis[int(y), :] = _tmp_y_axis _tmp_y_error_axis = mt1.readE(int(a))[:] _y_error_axis[int(y),:] = _tmp_y_error_axis @@ -503,19 +503,19 @@ def angleUnitConversion(value, from_units='degree', to_units='rad'): """ if (from_units == to_units): - return value; + return value - from_factor = 1; + from_factor = 1 #convert everything into rad if (from_units == 'degree'): - from_factor = 1.745329252e-2; - value_rad = from_factor * value; + from_factor = 1.745329252e-2 + value_rad = from_factor * value if (to_units == 'rad'): - return value_rad; + return value_rad else: - to_factor = 57.2957795; - return to_factor * value_rad; + to_factor = 57.2957795 + return to_factor * value_rad def convertToThetaVsLambda(_tof_axis, _pixel_axis, @@ -840,7 +840,7 @@ def applySF(InputWorkspace, print '--> Data S2H: {0:2f}'.format(s2h_value) print '--> Data S1W: {0:2f}'.format(s1w_value) print '--> Data S2W: {0:2f}'.format(s2w_value) - + print 'mERDDEEEEDEDEED' for i in range(nbr_row): @@ -1005,7 +1005,7 @@ def rebinNeXus(inputWorkspace, params, type): print '--> rebin ', type ws_histo_data = Rebin(InputWorkspace=inputWorkspace, Params=params, - PreserveEvents=True); + PreserveEvents=True) return ws_histo_data def cropTOF(inputWorkspace, min, max, type): @@ -1170,7 +1170,7 @@ def weightedMean(data_array, error_array, error_0): sz = len(data_array) # calculate the numerator of mean - dataNum = 0; + dataNum = 0 for i in range(sz): if (error_array[i] == 0): error_array[i] = error_0 @@ -1179,7 +1179,7 @@ def weightedMean(data_array, error_array, error_0): dataNum += tmpFactor # calculate denominator - dataDen = 0; + dataDen = 0 for i in range(sz): if (error_array[i] == 0): error_array[i] = error_0 @@ -1334,7 +1334,7 @@ def ouput_ascii_file(file_name, sz_x_axis = len(x_axis) for i in range(sz_x_axis-1): - f.write(str(x_axis[i]) + "," + str(y_axis[i]) + "," + str(y_error_axis[i]) + "\n"); + f.write(str(x_axis[i]) + "," + str(y_axis[i]) + "," + str(y_error_axis[i]) + "\n") f.close @@ -1957,8 +1957,8 @@ def cropAxisToOnlyNonzeroElements(q_rebin, dataPeakRange): x_axis = q_rebin.readX(0)[:] sz = x_axis.shape[0]-1 - index_first_non_zero_value = sz; - index_last_non_zero_value = 0; + index_first_non_zero_value = sz + index_last_non_zero_value = 0 for x in range(nbrPixel): _pixel_axis = q_rebin.readY(x)[:] @@ -2043,7 +2043,7 @@ def cleanupData1D(final_data_y_axis, final_data_y_error_axis): sz = final_data_y_axis.shape nbrTof = sz[0] - notYetRemoved = True; + notYetRemoved = True for t in range(nbrTof): @@ -2076,15 +2076,15 @@ def cleanupData1D(final_data_y_axis, final_data_y_error_axis): return [final_data_y_axis, final_data_y_error_axis] def isNexusTakeAfterRefDate(nexus_date): - ''' + ''' This function parses the output.date and returns true if this date is after the ref date ''' - nexus_date_acquistion = nexus_date.split('T')[0] - - if nexus_date_acquistion > ref_date: - return True - else: - return False + nexus_date_acquistion = nexus_date.split('T')[0] + + if nexus_date_acquistion > ref_date: + return True + else: + return False diff --git a/Code/Mantid/scripts/reduction/instruments/sans/sans_reduction_steps.py b/Code/Mantid/scripts/reduction/instruments/sans/sans_reduction_steps.py index 8b44f00236db..f6bf12837a0a 100644 --- a/Code/Mantid/scripts/reduction/instruments/sans/sans_reduction_steps.py +++ b/Code/Mantid/scripts/reduction/instruments/sans/sans_reduction_steps.py @@ -540,7 +540,7 @@ def set_gravity(self, flag, override=True): self._grav_set = True if (not self._grav_set) or override: - self._use_gravity = bool(flag) + self._use_gravity = bool(flag) else: msg = "User file can't override previous gravity setting, do gravity correction remains " + str(self._use_gravity) print msg diff --git a/Code/Tools/Pylint/pylint.cfg b/Code/Tools/Pylint/pylint.cfg index e3675ca90a4e..45bc53816b56 100644 --- a/Code/Tools/Pylint/pylint.cfg +++ b/Code/Tools/Pylint/pylint.cfg @@ -81,7 +81,7 @@ comment=no [FORMAT] # Maximum number of characters on a single line. -max-line-length=100 +max-line-length=140 # Maximum number of lines in a module max-module-lines=1000 @@ -213,16 +213,16 @@ max-args=5 ignored-argument-names=_.* # Maximum number of locals for function / method body -max-locals=15 +max-locals=25 # Maximum number of return / yield for function / method body max-returns=6 # Maximum number of branch for function / method body -max-branchs=12 +max-branchs=25 # Maximum number of statements in function / method body -max-statements=50 +max-statements=150 # Maximum number of parents for a class (see R0901). max-parents=7 From 327fcf1a9c292f98b4de96c47735c57550d1e88c Mon Sep 17 00:00:00 2001 From: Andrei Savici Date: Wed, 18 Feb 2015 17:47:12 -0500 Subject: [PATCH 259/275] Fix some indentation. Refs #10945 --- .../scripts/Calibration/Examples/TubeCalibDemoWish_5panels.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoWish_5panels.py b/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoWish_5panels.py index 9d4bec946929..cc784399c72a 100644 --- a/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoWish_5panels.py +++ b/Code/Mantid/scripts/Calibration/Examples/TubeCalibDemoWish_5panels.py @@ -68,7 +68,7 @@ def CalibrateWish( run_per_panel_list): # copy data from the current panel to the whole_instrument for i in range(tube_set.getNumTubes()): for spec_num in tube_set.getTube(i): - whole_instrument.setY(spec_num,ws.dataY(spec_num)) + whole_instrument.setY(spec_num,ws.dataY(spec_num)) # calibrate the whole_instrument with the last calibrated panel which has the calibration accumulation # of all the others @@ -79,6 +79,6 @@ def CalibrateWish( run_per_panel_list): if __name__ == "__main__": - # this file is found on cycle_11_1 + # this file is found on cycle_11_1 run_per_panel_list = [ (17706, 'panel01'), (17705, 'panel02'), (17701, 'panel03'), (17702, 'panel04'), (17695, 'panel05')] CalibrateWish(run_per_panel_list) From 9be647abe2cf8232062b415ec50daecb7b944b80 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos Date: Thu, 19 Feb 2015 08:37:04 +0000 Subject: [PATCH 260/275] Re #9556 Removing more dead code --- Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp index c69970ae783c..4b7bae69801a 100644 --- a/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/DynamicKuboToyabe.cpp @@ -105,9 +105,6 @@ void DynamicKuboToyabe::function1D(double* out, const double* xValues, const siz } // Non-zero external field else{ - //for (size_t i = 0; i < nData; i++) { - // out[i] = A*HKT(xValues[i],G,F); - //} throw std::runtime_error("HKT() not implemented yet"); } } From b88d144d88310870799e192e038902ccd8a3c6e3 Mon Sep 17 00:00:00 2001 From: Owen Arnold Date: Thu, 19 Feb 2015 09:20:25 +0000 Subject: [PATCH 261/275] refs #11056. Fix IPeak::setQLabFrame defaults issue. --- Code/Mantid/Framework/Crystal/test/IndexSXPeaksTest.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Mantid/Framework/Crystal/test/IndexSXPeaksTest.h b/Code/Mantid/Framework/Crystal/test/IndexSXPeaksTest.h index b8c4ca4a2166..a69316a8dc7d 100644 --- a/Code/Mantid/Framework/Crystal/test/IndexSXPeaksTest.h +++ b/Code/Mantid/Framework/Crystal/test/IndexSXPeaksTest.h @@ -120,7 +120,7 @@ class IndexSXPeaksTest : public CxxTest::TestSuite { IPeak& peak = m_masterPeaks->getPeak(i); Mantid::Kernel::V3D v(1, 0, 0); - peak.setQSampleFrame(v); // Overwrite all Q samples to be co-linear. + peak.setQSampleFrame(v, boost::optional()); // Overwrite all Q samples to be co-linear. } TS_ASSERT_THROWS(doTest(6, "1, 2, 3, 4, 5, 6", 14.131, 19.247, 8.606, 90.0, 105.071, 90.0), std::runtime_error); From 70ada56493efa09c91819f04f7cc571b498ddb4e Mon Sep 17 00:00:00 2001 From: Roman Tolchenov Date: Thu, 19 Feb 2015 09:36:54 +0000 Subject: [PATCH 262/275] Re #11115. Fixed the tests. --- .../CurveFitting/test/GaussianTest.h | 113 +++--------------- 1 file changed, 14 insertions(+), 99 deletions(-) diff --git a/Code/Mantid/Framework/CurveFitting/test/GaussianTest.h b/Code/Mantid/Framework/CurveFitting/test/GaussianTest.h index 760c5712f462..db5fbe75d89e 100644 --- a/Code/Mantid/Framework/CurveFitting/test/GaussianTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/GaussianTest.h @@ -295,85 +295,7 @@ class GaussianTest : public CxxTest::TestSuite } - void t11estAgainstPeak2FallbackToSimplex() - { - // create peak2 mock data to test against - std::string wsName = "GaussHRP38692MockData"; - int histogramNumber = 1; - int timechannels = 41; - Workspace_sptr ws = WorkspaceFactory::Instance().create("Workspace2D",histogramNumber,timechannels,timechannels); - Workspace2D_sptr ws2D = boost::dynamic_pointer_cast(ws); - Mantid::MantidVec& x = ws2D->dataX(0); // x-values (time-of-flight) - Mantid::MantidVec& y = ws2D->dataY(0); // y-values (counts) - Mantid::MantidVec& e = ws2D->dataE(0); // error values of counts - getHRP38692Peak2Data(x, y, e); - - //put this workspace in the data service - TS_ASSERT_THROWS_NOTHING(AnalysisDataService::Instance().add(wsName, ws2D)); - - // Initialise algorithm - Fit alg; - TS_ASSERT_THROWS_NOTHING(alg.initialize()); - TS_ASSERT( alg.isInitialized() ); - - // create function you want to fit against - CompositeFunction_sptr fnWithBk( new CompositeFunction() ); - - boost::shared_ptr bk( new LinearBackground() ); - bk->initialize(); - - bk->setParameter("A0",0.0); - bk->setParameter("A1",0.0); - bk->tie("A1","0"); - - BoundaryConstraint* bc_b = new BoundaryConstraint(bk.get(),"A0",0, 20.0); - bk->addConstraint(bc_b); - - // set up Gaussian fitting function - boost::shared_ptr fn( new Gaussian() ); - fn->initialize(); - - fn->setParameter("Height",200.0); - fn->setParameter("PeakCentre",79450.0); - fn->setParameter("Sigma",300.0); - - // add constraint to function - BoundaryConstraint* bc3 = new BoundaryConstraint(fn.get(),"Sigma",20, 100.0); - fn->addConstraint(bc3); - - fnWithBk->addFunction(bk); - fnWithBk->addFunction(fn); - - alg.setProperty("Function",fnWithBk); - // Set which spectrum to fit against and initial starting values - alg.setPropertyValue("InputWorkspace", wsName); - alg.setPropertyValue("StartX","79300"); - alg.setPropertyValue("EndX","79600"); - - - // execute fit - TS_ASSERT_THROWS_NOTHING( - TS_ASSERT( alg.execute() ) - ) - TS_ASSERT( alg.isExecuted() ); - - // test the output from fit is what you expect - double dummy = alg.getProperty("OutputChi2overDoF"); - TS_ASSERT_DELTA( dummy, 0.0,0.1); - - IFunction_sptr out = alg.getProperty("Function"); - IPeakFunction *pk = dynamic_cast(dynamic_cast(out.get())->getFunction(1).get()); - TS_ASSERT_DELTA( pk->height(), 249.3187 ,0.01); - TS_ASSERT_DELTA( pk->centre(), 79430 ,0.1); - TS_ASSERT_DELTA( pk->getParameter("Sigma"), 25.3066 ,0.01); - TS_ASSERT_DELTA( out->getParameter("f0.A0"), 7.8643 ,0.001); - TS_ASSERT_DELTA( out->getParameter("f0.A1"), 0.0 ,0.01); - - AnalysisDataService::Instance().remove(wsName); - } - - - void xtestAgainstMockData() + void testAgainstMockData() { // create mock data to test against std::string wsName = "GaussMockData"; @@ -404,6 +326,7 @@ class GaussianTest : public CxxTest::TestSuite alg2.setPropertyValue("WorkspaceIndex","0"); alg2.setPropertyValue("StartX","0"); alg2.setPropertyValue("EndX","20"); + alg2.setPropertyValue("Minimizer","Levenberg-MarquardtMD"); // execute fit TS_ASSERT_THROWS_NOTHING( @@ -411,18 +334,15 @@ class GaussianTest : public CxxTest::TestSuite ) TS_ASSERT( alg2.isExecuted() ); - std::string minimizer = alg2.getProperty("Minimizer"); - TS_ASSERT( minimizer.compare("Levenberg-Marquardt") == 0 ); - // test the output from fit is what you expect double dummy = alg2.getProperty("OutputChi2overDoF"); TS_ASSERT_DELTA( dummy, 0.035,0.01); IFunction_sptr out = alg2.getProperty("Function"); IPeakFunction *pk = dynamic_cast(out.get()); - TS_ASSERT_DELTA( pk->height(), 97.9728 ,0.0001); - TS_ASSERT_DELTA( pk->centre(), 11.2194 ,0.0001); - TS_ASSERT_DELTA( pk->fwhm(), 2.6181 ,0.0001); + TS_ASSERT_DELTA( pk->height(), 97.8036 ,0.0001); + TS_ASSERT_DELTA( pk->centre(), 11.2356 ,0.0001); + TS_ASSERT_DELTA( pk->fwhm(), 2.6237 ,0.0001); } @@ -492,7 +412,7 @@ class GaussianTest : public CxxTest::TestSuite // and used a starting of Sigma = 100. // Note that the no constraint simplex with Sigma = 300 also does not locate // the correct minimum but not as badly as levenberg-marquardt - void t11estAgainstHRPD_DatasetWithConstraintsSimplex() + void testAgainstHRPD_DatasetWithConstraintsSimplex() { // create peak2 mock data to test against std::string wsName = "GaussHRP38692MockData"; @@ -500,7 +420,7 @@ class GaussianTest : public CxxTest::TestSuite int timechannels = 41; Workspace_sptr ws = WorkspaceFactory::Instance().create("Workspace2D",histogramNumber,timechannels,timechannels); Workspace2D_sptr ws2D = boost::dynamic_pointer_cast(ws); - Mantid::MantidVec& x = ws2D->dataX(0); // x-values (time-of-flight) + Mantid::MantidVec& x = ws2D->dataX(0); // x-values (time-of-flight) Mantid::MantidVec& y = ws2D->dataY(0); // y-values (counts) Mantid::MantidVec& e = ws2D->dataE(0); // error values of counts getHRP38692Peak2Data(x, y, e); @@ -536,21 +456,16 @@ class GaussianTest : public CxxTest::TestSuite fn->setParameter("Sigma",10.0); // add constraint to function - //BoundaryConstraint* bc1 = new BoundaryConstraint(fn,"Height",100, 300.0); - //BoundaryConstraint* bc2 = new BoundaryConstraint(fn,"PeakCentre",79200, 79700.0); BoundaryConstraint* bc3 = new BoundaryConstraint(fn.get(),"Sigma",20, 100.0); - //fn->addConstraint(bc1); - //fn->addConstraint(bc2); fn->addConstraint(bc3); fnWithBk->addFunction(bk); fnWithBk->addFunction(fn); - //alg.setPropertyValue("Function",*fnWithBk); - alg.setProperty("Function",fnWithBk); + alg.setProperty("Function",boost::dynamic_pointer_cast(fnWithBk)); // Set which spectrum to fit against and initial starting values - alg.setPropertyValue("InputWorkspace",wsName); + alg.setProperty("InputWorkspace",ws); alg.setPropertyValue("StartX","79300"); alg.setPropertyValue("EndX","79600"); alg.setPropertyValue("Minimizer","Simplex"); @@ -566,16 +481,16 @@ class GaussianTest : public CxxTest::TestSuite // test the output from fit is what you expect double dummy = alg.getProperty("OutputChi2overDoF"); - TS_ASSERT_DELTA( dummy, 5.1604,1); + TS_ASSERT_DELTA( dummy, 2.5911,1); IFunction_sptr fun = alg.getProperty("Function"); TS_ASSERT(fun); IFunction_sptr out = alg.getProperty("Function"); - TS_ASSERT_DELTA( out->getParameter("f1.Height"), 216.419 ,1); - TS_ASSERT_DELTA( out->getParameter("f1.PeakCentre"), 79430.1 ,1); - TS_ASSERT_DELTA( out->getParameter("f1.Sigma"), 27.08 ,0.1); - TS_ASSERT_DELTA( out->getParameter("f0.A0"), 2.18 ,0.1); + TS_ASSERT_DELTA( out->getParameter("f1.Height"), 232 ,1); + TS_ASSERT_DELTA( out->getParameter("f1.PeakCentre"), 79430 ,1); + TS_ASSERT_DELTA( out->getParameter("f1.Sigma"), 26.08 ,1); + TS_ASSERT_DELTA( out->getParameter("f0.A0"), 8 ,1); TS_ASSERT_DELTA( out->getParameter("f0.A1"), 0.0 ,0.01); AnalysisDataService::Instance().remove(wsName); From 203539339bb27a42aef20f3288d0475dbce56667 Mon Sep 17 00:00:00 2001 From: Michael Wedel Date: Thu, 19 Feb 2015 11:06:54 +0100 Subject: [PATCH 263/275] Refs #11104. Adding general test for IPeakFunction::intensity --- .../Framework/CurveFitting/CMakeLists.txt | 1 + .../test/IPeakFunctionIntensityTest.h | 152 ++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 Code/Mantid/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h diff --git a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt index edcb417d8e0a..1907f29a5e01 100644 --- a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt +++ b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt @@ -257,6 +257,7 @@ set ( TEST_FILES GaussianTest.h GramCharlierComptonProfileTest.h IkedaCarpenterPVTest.h + IPeakFunctionIntensityTest.h LeBailFitTest.h LeBailFunctionTest.h LeastSquaresTest.h diff --git a/Code/Mantid/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h b/Code/Mantid/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h new file mode 100644 index 000000000000..12fa0c8f286e --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h @@ -0,0 +1,152 @@ +#ifndef IPEAKFUNCTIONINTENSITYTEST_H +#define IPEAKFUNCTIONINTENSITYTEST_H + +#include +#include "MantidAPI/FrameworkManager.h" +#include "MantidAPI/FunctionFactory.h" +#include "MantidAPI/IPeakFunction.h" +#include + +using namespace Mantid::API; + +#define DBL2STR(x) boost::lexical_cast(x) + +struct ParameterSet { + ParameterSet(double c, double h, double f) : center(c), height(h), fwhm(f) {} + + double center; + double height; + double fwhm; +}; + +class IPeakFunctionIntensityTest : public CxxTest::TestSuite { +public: + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static IPeakFunctionIntensityTest *createSuite() { + return new IPeakFunctionIntensityTest(); + } + static void destroySuite(IPeakFunctionIntensityTest *suite) { delete suite; } + + IPeakFunctionIntensityTest() : m_blackList() { + FrameworkManager::Instance(); + + m_blackList.insert("BackToBackExponential"); + m_blackList.insert("DeltaFunction"); + m_blackList.insert("ElasticDiffRotDiscreteCircle"); + m_blackList.insert("ElasticDiffSphere"); + + m_peakFunctions = getAllPeakFunctions(m_blackList); + m_parameterSets = getParameterSets(); + } + + /* This test sets all peak function parameters (center, fwhm, height) + * to the values supplied in the first ParameterSet contained in + * m_parameterSets. + * + * Then it retrieves the intensities of the peak functions and stores them. + * Each time new parameters are set, the ratio of the height parameter to + * the previous step is compared to the intensity ratio - they should be + * the same. + */ + void testAllFunctions() { + initializePeakFunctions(m_peakFunctions, m_parameterSets[0]); + + std::vector initialIntensities = getIntensities(m_peakFunctions); + + for (size_t i = 1; i < m_parameterSets.size(); ++i) { + double oldHeight = m_parameterSets[i - 1].height; + double newHeight = m_parameterSets[i].height; + double heightRatio = newHeight / oldHeight; + + initializePeakFunctions(m_peakFunctions, m_parameterSets[i]); + + std::vector newIntensities = getIntensities(m_peakFunctions); + + for (size_t j = 0; j < initialIntensities.size(); ++j) { + double oldIntensity = initialIntensities[j]; + double newIntensity = newIntensities[j]; + double intensityRatio = newIntensity / oldIntensity; + + TSM_ASSERT_DELTA( + "ITERATION " + DBL2STR(i) + ", " + m_peakFunctions[j]->name() + + ": Height was increased from " + DBL2STR(oldHeight) + " to " + + DBL2STR(newHeight) + " (ratio " + DBL2STR(heightRatio) + + "), but intensity changed from " + DBL2STR(oldIntensity) + + " to " + DBL2STR(newIntensity) + " (ratio " + + DBL2STR(intensityRatio) + ").", + intensityRatio, heightRatio, 1e-10); + } + + initialIntensities = newIntensities; + } + } + +private: + std::vector + getAllPeakFunctions(const std::set &blackList) const { + std::vector peakFunctions; + + std::vector registeredFunctions = + FunctionFactory::Instance().getFunctionNames(); + + for (auto it = registeredFunctions.begin(); it != registeredFunctions.end(); + ++it) { + if (blackList.count(*it) == 0) { + IPeakFunction_sptr peakFunction = + boost::dynamic_pointer_cast( + FunctionFactory::Instance().createFunction(*it)); + + if (peakFunction) { + peakFunctions.push_back(peakFunction); + } + } + } + + return peakFunctions; + } + + void initializePeakFunctions(const std::vector &peaks, + const ParameterSet ¶meters) const { + + for (auto it = peaks.begin(); it != peaks.end(); ++it) { + (*it)->setCentre(parameters.center); + + // for Ikeda-Carpenter it's not allowed to set Fwhm + try { + (*it)->setFwhm(parameters.fwhm); + } + catch (std::invalid_argument) { + } + + (*it)->setHeight(parameters.height); + } + } + + std::vector getParameterSets() const { + std::vector parameterSets; + parameterSets.push_back(ParameterSet(0.0, 4.34, 0.25)); + parameterSets.push_back(ParameterSet(0.0, 5.34, 0.25)); + parameterSets.push_back(ParameterSet(0.0, 6.34, 0.25)); + parameterSets.push_back(ParameterSet(0.0, 7.34, 0.25)); + + return parameterSets; + } + + std::vector + getIntensities(const std::vector &peaks) const { + std::vector intensities; + + for (auto it = peaks.begin(); it != peaks.end(); ++it) { + intensities.push_back((*it)->intensity()); + } + + return intensities; + } + + std::vector m_peakFunctions; + std::vector m_parameterSets; + std::set m_blackList; +}; + +#endif // IPEAKFUNCTIONINTENSITYTEST_H From c7c5e1b483e581704ce280a89b0834bc853e92d9 Mon Sep 17 00:00:00 2001 From: Owen Arnold Date: Thu, 19 Feb 2015 10:50:16 +0000 Subject: [PATCH 264/275] refs #11056. Fix doxygen warning. --- .../Framework/TestHelpers/src/ComponentCreationHelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Mantid/Framework/TestHelpers/src/ComponentCreationHelper.cpp b/Code/Mantid/Framework/TestHelpers/src/ComponentCreationHelper.cpp index 0d694bc98c49..0618e788d5aa 100644 --- a/Code/Mantid/Framework/TestHelpers/src/ComponentCreationHelper.cpp +++ b/Code/Mantid/Framework/TestHelpers/src/ComponentCreationHelper.cpp @@ -573,7 +573,7 @@ Instrument_sptr createTestInstrumentRectangular2(int num_banks, int pixels, * @param detectorPos : V3D detector position * @return Instrument generated. */ -Instrument_sptr createMinimalInstrument(const V3D& sourcePos, const V3D& samplePos, const V3D& detectorPos ) +Instrument_sptr createMinimalInstrument(const Mantid::Kernel::V3D& sourcePos, const Mantid::Kernel::V3D& samplePos, const Mantid::Kernel::V3D& detectorPos ) { Instrument_sptr instrument = boost::make_shared(); instrument->setReferenceFrame( From 27e306588bf126895eccd2f79cd7aa575d8c7bb8 Mon Sep 17 00:00:00 2001 From: Michael Wedel Date: Thu, 19 Feb 2015 11:53:05 +0100 Subject: [PATCH 265/275] Refs #11104. Adding Muon_ExpDecayOscTest to blacklist --- .../Framework/CurveFitting/test/IPeakFunctionIntensityTest.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Code/Mantid/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h b/Code/Mantid/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h index 12fa0c8f286e..ade73e302e1c 100644 --- a/Code/Mantid/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h @@ -35,6 +35,7 @@ class IPeakFunctionIntensityTest : public CxxTest::TestSuite { m_blackList.insert("DeltaFunction"); m_blackList.insert("ElasticDiffRotDiscreteCircle"); m_blackList.insert("ElasticDiffSphere"); + m_blackList.insert("Muon_ExpDecayOscTest"); m_peakFunctions = getAllPeakFunctions(m_blackList); m_parameterSets = getParameterSets(); From 1ec1f8336b0b8017acc4544bcac44b058ae00686 Mon Sep 17 00:00:00 2001 From: Owen Arnold Date: Thu, 19 Feb 2015 11:11:12 +0000 Subject: [PATCH 266/275] refs #11056. CreateSampleWorkspace fixed. CreateSampleWorkspace does not set up a ReferenceFrame which is consistent with the actual layout of the instrument. I don't know how this probelem got in there in the first-place, or why it hadn't cause problem up to now! Peak calculations require that the reference frame is known so that we can dot product with the beam direction in order to determine dQ. Fixing this should now make the doc-tests pass. --- Code/Mantid/Framework/Algorithms/src/CreateSampleWorkspace.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Mantid/Framework/Algorithms/src/CreateSampleWorkspace.cpp b/Code/Mantid/Framework/Algorithms/src/CreateSampleWorkspace.cpp index f04d8ac8bb3f..99496421e98c 100644 --- a/Code/Mantid/Framework/Algorithms/src/CreateSampleWorkspace.cpp +++ b/Code/Mantid/Framework/Algorithms/src/CreateSampleWorkspace.cpp @@ -396,7 +396,7 @@ Instrument_sptr CreateSampleWorkspace::createTestInstrumentRectangular( int num_banks, int pixels, double pixelSpacing) { boost::shared_ptr testInst(new Instrument("basic_rect")); testInst->setReferenceFrame( - boost::shared_ptr(new ReferenceFrame(Y, X, Left, ""))); + boost::shared_ptr(new ReferenceFrame(Y, Z, Left, ""))); const double cylRadius(pixelSpacing / 2); const double cylHeight(0.0002); From f42f48de1ced2a4dfe573d06f9349cfd4444de26 Mon Sep 17 00:00:00 2001 From: Owen Arnold Date: Thu, 19 Feb 2015 13:31:44 +0000 Subject: [PATCH 267/275] refs #11056. Run alg as child. --- Code/Mantid/Framework/Crystal/test/AddPeakHKLTest.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Mantid/Framework/Crystal/test/AddPeakHKLTest.h b/Code/Mantid/Framework/Crystal/test/AddPeakHKLTest.h index 278cb40f270a..0c842e3da845 100644 --- a/Code/Mantid/Framework/Crystal/test/AddPeakHKLTest.h +++ b/Code/Mantid/Framework/Crystal/test/AddPeakHKLTest.h @@ -75,8 +75,8 @@ class AddPeakHKLTest : public CxxTest::TestSuite ws->mutableSample().setOrientedLattice(&orientedLattice); ws->mutableRun().setGoniometer(goniometer, false); - Mantid::API::AnalysisDataService::Instance().add("peaks_ws",ws); AddPeakHKL alg; + alg.setChild(true); alg.initialize(); std::vector hklVec; hklVec.push_back(hkl.X()); @@ -85,10 +85,10 @@ class AddPeakHKLTest : public CxxTest::TestSuite alg.setProperty("HKL", hklVec); alg.setProperty("Workspace", ws); alg.execute(); - ws = Mantid::API::AnalysisDataService::Instance().retrieveWS("peaks_ws"); + IPeaksWorkspace_sptr ws_out = alg.getProperty("Workspace"); // Get the peak just added. - const Peak& peak = ws->getPeak(0); + const IPeak& peak =ws_out->getPeak(0); /* Now we check we have made a self - consistent peak From e64f93044bf72b49fbd7ea0e4c5256d63c42d52a Mon Sep 17 00:00:00 2001 From: Michael Wedel Date: Thu, 19 Feb 2015 15:09:59 +0100 Subject: [PATCH 268/275] Refs #11104. Not giving up on setIntensity so quickly If intensity is 0, we first try to set height to a different, arbitrary value, following Roman's suggestion. If it's still 0 after that, there's nothing left to do. --- Code/Mantid/Framework/API/src/IPeakFunction.cpp | 13 +++++++++++-- .../Framework/CurveFitting/test/GaussianTest.h | 7 +++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Code/Mantid/Framework/API/src/IPeakFunction.cpp b/Code/Mantid/Framework/API/src/IPeakFunction.cpp index f5995bf995bb..07053b760fda 100644 --- a/Code/Mantid/Framework/API/src/IPeakFunction.cpp +++ b/Code/Mantid/Framework/API/src/IPeakFunction.cpp @@ -153,8 +153,17 @@ void IPeakFunction::setIntensity(const double newIntensity) { double currentIntensity = intensity(); if (currentIntensity == 0.0) { - throw std::invalid_argument( - "Cannot set new intensity, not enough information available."); + // Try to set a different height first. + setHeight(2.0); + + currentHeight = height(); + currentIntensity = intensity(); + + // If the current intensity is still 0, there's nothing left to do. + if (currentIntensity == 0.0) { + throw std::invalid_argument( + "Cannot set new intensity, not enough information available."); + } } setHeight(newIntensity / currentIntensity * currentHeight); diff --git a/Code/Mantid/Framework/CurveFitting/test/GaussianTest.h b/Code/Mantid/Framework/CurveFitting/test/GaussianTest.h index e7bc607d7898..ee2a682fdf6a 100644 --- a/Code/Mantid/Framework/CurveFitting/test/GaussianTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/GaussianTest.h @@ -621,8 +621,15 @@ class GaussianTest : public CxxTest::TestSuite TS_ASSERT_EQUALS(fn->intensity(), 0.0); + // This does not work, because fwhm is 0 and height is 0 TS_ASSERT_THROWS(fn->setIntensity(20.0), std::invalid_argument); TS_ASSERT_EQUALS(fn->intensity(), 0.0); + + // Now, fwhm is not zero + fn->setFwhm(0.02); + + TS_ASSERT_THROWS_NOTHING(fn->setIntensity(20.0)); + TS_ASSERT_DELTA(fn->intensity(), 20.0, 1e-10); } From 3a13ae5e3708ff9c83be21341e62e59927a3f929 Mon Sep 17 00:00:00 2001 From: Owen Arnold Date: Thu, 19 Feb 2015 14:13:06 +0000 Subject: [PATCH 269/275] Update SaveIsawPeaks-v1.rst Information about saving peak shape. --- Code/Mantid/docs/source/algorithms/SaveIsawPeaks-v1.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Code/Mantid/docs/source/algorithms/SaveIsawPeaks-v1.rst b/Code/Mantid/docs/source/algorithms/SaveIsawPeaks-v1.rst index 3715ca27c786..5371c65ac2ba 100644 --- a/Code/Mantid/docs/source/algorithms/SaveIsawPeaks-v1.rst +++ b/Code/Mantid/docs/source/algorithms/SaveIsawPeaks-v1.rst @@ -9,7 +9,9 @@ Description ----------- -Save a PeaksWorkspace to a ISAW-style ASCII .peaks file. +Save a :ref:`PeaksWorkspace ` to a ISAW-style ASCII .peaks file. + +The PeaksWorkspace :ref:`PeaksWorkspace ` consists of individual Peaks, each of which has an individual PeakShape relating to the way the workspace has been integrated. The PeakShape information is not saved out in the ISAW peaks format. To save the full peak information, use the NeXus format :ref:`SaveNexus `. Usage ----- From d1b4a7d7372a2237ba27c5446454fc63ef297c72 Mon Sep 17 00:00:00 2001 From: Owen Arnold Date: Thu, 19 Feb 2015 14:13:42 +0000 Subject: [PATCH 270/275] Update SaveIsawPeaks-v1.rst Remove duplication --- Code/Mantid/docs/source/algorithms/SaveIsawPeaks-v1.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Mantid/docs/source/algorithms/SaveIsawPeaks-v1.rst b/Code/Mantid/docs/source/algorithms/SaveIsawPeaks-v1.rst index 5371c65ac2ba..19e0858e28f7 100644 --- a/Code/Mantid/docs/source/algorithms/SaveIsawPeaks-v1.rst +++ b/Code/Mantid/docs/source/algorithms/SaveIsawPeaks-v1.rst @@ -11,7 +11,7 @@ Description Save a :ref:`PeaksWorkspace ` to a ISAW-style ASCII .peaks file. -The PeaksWorkspace :ref:`PeaksWorkspace ` consists of individual Peaks, each of which has an individual PeakShape relating to the way the workspace has been integrated. The PeakShape information is not saved out in the ISAW peaks format. To save the full peak information, use the NeXus format :ref:`SaveNexus `. +The :ref:`PeaksWorkspace ` consists of individual Peaks, each of which has an individual PeakShape relating to the way the workspace has been integrated. The PeakShape information is not saved out in the ISAW peaks format. To save the full peak information, use the NeXus format :ref:`SaveNexus `. Usage ----- From 35d31454a17bb408669c9c2977d6ab8f14fecd61 Mon Sep 17 00:00:00 2001 From: Owen Arnold Date: Thu, 19 Feb 2015 14:33:07 +0000 Subject: [PATCH 271/275] Update PeaksWorkspace.rst Add PeakShape information and update tools to visualise with. --- .../docs/source/concepts/PeaksWorkspace.rst | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/Code/Mantid/docs/source/concepts/PeaksWorkspace.rst b/Code/Mantid/docs/source/concepts/PeaksWorkspace.rst index 582398fdb5b5..89dc81780cdd 100644 --- a/Code/Mantid/docs/source/concepts/PeaksWorkspace.rst +++ b/Code/Mantid/docs/source/concepts/PeaksWorkspace.rst @@ -1,12 +1,10 @@ .. _PeaksWorkspace: -PeaksWorkspace -============== +# PeaksWorkspace The PeaksWorkspace is a special Workspace that holds a list of single crystal Peak objects. -Creating a PeaksWorkspace -------------------------- +## Creating a PeaksWorkspace * :ref:`FindPeaksMD ` will find peaks in reciprocal space in a :ref:`MDWorkspace `. * :ref:`FindSXPeaks ` will find peaks in detector space. @@ -15,16 +13,15 @@ Creating a PeaksWorkspace * The :ref:`SaveIsawPeaks ` algorithm will save a PeaksWorkspace to a file. * :ref:`CreatePeaksWorkspace ` will create an empty PeaksWorkspace that you can then edit. -Viewing a PeaksWorkspace ------------------------- +## Viewing a PeaksWorkspace * Double-click a PeaksWorkspace to see the full list of data of each Peak object. * In MantidPlot, you can drag/drop a PeaksWorkspace from the list of workspaces onto the `Instrument View `__ . This will overlay the peaks onto the detector face. -* Right-click a PeaksWorkspace and select the menu to show the peak positions in 3D in the `VatesSimpleInterface `__ . +* Right-click a PeaksWorkspace and select the menu to show the peak positions in 3D in the `VatesSimpleInterface `__ * In paraview, you can load a .Peaks file loader plugin to view a PeaksWorkspace. +* `PeaksViewer ` in the `SliceViewer ` -The Peak Object ---------------- +## The Peak Object Each peak object contains several pieces of information. Not all of them are necessary: @@ -34,14 +31,24 @@ Each peak object contains several pieces of information. Not all of them are nec * Goniometer rotation matrix (for finding Q in the sample frame) * Integrated intensity and error (optional) * Row/column of detector (only for :ref:`RectangularDetectors ` ) +* An integration shape (see below) -Using PeaksWorkspace's in Python --------------------------------- +### The Peak Shape + +Each Peak object contains a PeakShape. Only the integration algorithms which act on, and return PeaksWorkspaces set the shape of the peaks. The PeakShape is owned by the Peak, not the PeaksWorkspace, so when PeaksWorkspaces are split, or concatinated, the integration shapes are unaltered. Aside from the Null Peak Shape, each peak shape contains at least the following information. + +* The algorithm used to perform the integration +* The version of the algorithm used to perform the integration +* The frame in which the integration has been performed + +Subtypes of PeakShape will then provide additional information. For example PeakShapeSpherical provides the radius as well as background inner, and background outer radius. + + +## Using PeaksWorkspace's in Python The PeaksWorkspace and Peak objects are exposed to python. -PeaksWorkspace Python Interface -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +### PeaksWorkspace Python Interface .. code-block:: python @@ -50,8 +57,7 @@ PeaksWorkspace Python Interface p = pws.getPeak(12) pws.removePeak(34) -Peak Python Interface -~~~~~~~~~~~~~~~~~~~~~ +### Peak Python Interface You can get a handle to an existing peak with: @@ -64,7 +70,7 @@ Or you can create a new peak in this way: .. code-block:: python qlab = V3D(1.23, 3.45, 2.22) # Q in the lab frame of the peak - detector_distance = 2.5 # sample-detector distance in meters + detector_distance = 2.5 # sample-detector distance in meters. Detector distances are optional. Calculated in not provided. p = pws.createPeak(qlab, detector_distance) # The peak can later be added to the workspace pws.addPeak(p) @@ -89,4 +95,4 @@ Once you have a handle on a peak "p" you have several methods to query/modify it d = p.getDSpacing() -.. categories:: Concepts \ No newline at end of file +.. categories:: Concepts From 75e3198467c4649136b85a333b04beef25e7dd2e Mon Sep 17 00:00:00 2001 From: Owen Arnold Date: Thu, 19 Feb 2015 14:39:29 +0000 Subject: [PATCH 272/275] Update PeaksWorkspace.rst Fix to rst --- .../docs/source/concepts/PeaksWorkspace.rst | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/Code/Mantid/docs/source/concepts/PeaksWorkspace.rst b/Code/Mantid/docs/source/concepts/PeaksWorkspace.rst index 89dc81780cdd..e6a32575ab9a 100644 --- a/Code/Mantid/docs/source/concepts/PeaksWorkspace.rst +++ b/Code/Mantid/docs/source/concepts/PeaksWorkspace.rst @@ -1,10 +1,10 @@ -.. _PeaksWorkspace: - -# PeaksWorkspace +PeaksWorkspace +=============== The PeaksWorkspace is a special Workspace that holds a list of single crystal Peak objects. -## Creating a PeaksWorkspace +Creating a PeaksWorkspace +-------------------------- * :ref:`FindPeaksMD ` will find peaks in reciprocal space in a :ref:`MDWorkspace `. * :ref:`FindSXPeaks ` will find peaks in detector space. @@ -13,15 +13,17 @@ The PeaksWorkspace is a special Workspace that holds a list of single crystal Pe * The :ref:`SaveIsawPeaks ` algorithm will save a PeaksWorkspace to a file. * :ref:`CreatePeaksWorkspace ` will create an empty PeaksWorkspace that you can then edit. -## Viewing a PeaksWorkspace +Viewing a PeaksWorkspace +-------------------------- * Double-click a PeaksWorkspace to see the full list of data of each Peak object. * In MantidPlot, you can drag/drop a PeaksWorkspace from the list of workspaces onto the `Instrument View `__ . This will overlay the peaks onto the detector face. * Right-click a PeaksWorkspace and select the menu to show the peak positions in 3D in the `VatesSimpleInterface `__ * In paraview, you can load a .Peaks file loader plugin to view a PeaksWorkspace. -* `PeaksViewer ` in the `SliceViewer ` +* `PeaksViewer `__ in the `SliceViewer `__ -## The Peak Object +The Peak Object +-------------------------- Each peak object contains several pieces of information. Not all of them are necessary: @@ -33,7 +35,8 @@ Each peak object contains several pieces of information. Not all of them are nec * Row/column of detector (only for :ref:`RectangularDetectors ` ) * An integration shape (see below) -### The Peak Shape +The Peak Shape +~~~~~~~~~~~~~~~ Each Peak object contains a PeakShape. Only the integration algorithms which act on, and return PeaksWorkspaces set the shape of the peaks. The PeakShape is owned by the Peak, not the PeaksWorkspace, so when PeaksWorkspaces are split, or concatinated, the integration shapes are unaltered. Aside from the Null Peak Shape, each peak shape contains at least the following information. @@ -44,11 +47,13 @@ Each Peak object contains a PeakShape. Only the integration algorithms which act Subtypes of PeakShape will then provide additional information. For example PeakShapeSpherical provides the radius as well as background inner, and background outer radius. -## Using PeaksWorkspace's in Python +Using PeaksWorkspaces in Python +--------------------------------- The PeaksWorkspace and Peak objects are exposed to python. -### PeaksWorkspace Python Interface +PeaksWorkspace Python Interface +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: python @@ -57,7 +62,8 @@ The PeaksWorkspace and Peak objects are exposed to python. p = pws.getPeak(12) pws.removePeak(34) -### Peak Python Interface +Peak Python Interface +~~~~~~~~~~~~~~~~~~~~~ You can get a handle to an existing peak with: @@ -93,6 +99,7 @@ Once you have a handle on a peak "p" you have several methods to query/modify it wl = p.getWavelength() tof = p.getTOF() d = p.getDSpacing() + shape = p.getPeakShape() .. categories:: Concepts From f8445a1425781d236267bdb586e2cc33d4897c37 Mon Sep 17 00:00:00 2001 From: Michael Wedel Date: Thu, 19 Feb 2015 15:57:21 +0100 Subject: [PATCH 273/275] Refs #11104. Adding special case code for BackToBackExponential BackToBackExponential already has an intensity parameter, so the methods are overriden to get/set this parameter. --- .../BackToBackExponential.h | 4 ++++ .../test/BackToBackExponentialTest.h | 19 +++++++++++++++++++ .../test/IPeakFunctionIntensityTest.h | 1 - 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/BackToBackExponential.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/BackToBackExponential.h index 1feb4dcec305..103d8679b413 100644 --- a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/BackToBackExponential.h +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/BackToBackExponential.h @@ -61,6 +61,10 @@ class DLLExport BackToBackExponential : public API::IPeakFunction { virtual void setHeight(const double h); virtual double fwhm() const; virtual void setFwhm(const double w); + virtual double intensity() const { return getParameter("I"); } + virtual void setIntensity(const double newIntensity) { + setParameter("I", newIntensity); + } /// overwrite IFunction base class methods std::string name() const { return "BackToBackExponential"; } diff --git a/Code/Mantid/Framework/CurveFitting/test/BackToBackExponentialTest.h b/Code/Mantid/Framework/CurveFitting/test/BackToBackExponentialTest.h index ab520925e308..31d564cca1f8 100644 --- a/Code/Mantid/Framework/CurveFitting/test/BackToBackExponentialTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/BackToBackExponentialTest.h @@ -185,6 +185,25 @@ class BackToBackExponentialTest : public CxxTest::TestSuite } } + void testIntensity() + { + const double s = 4.0; + const double I = 2.1; + BackToBackExponential b2bExp; + b2bExp.initialize(); + b2bExp.setParameter("I", I); + b2bExp.setParameter("A", 6.0);// large A and B make + b2bExp.setParameter("B", 6.0);// the exponentials narrow + b2bExp.setParameter("X0",0.0); + b2bExp.setParameter("S", s); + + TS_ASSERT_EQUALS(b2bExp.intensity(), 2.1); + TS_ASSERT_THROWS_NOTHING(b2bExp.setIntensity(3.0)); + + TS_ASSERT_EQUALS(b2bExp.intensity(), 3.0); + TS_ASSERT_EQUALS(b2bExp.getParameter("I"), 3.0); + } + }; diff --git a/Code/Mantid/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h b/Code/Mantid/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h index ade73e302e1c..513f22227ae1 100644 --- a/Code/Mantid/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h @@ -31,7 +31,6 @@ class IPeakFunctionIntensityTest : public CxxTest::TestSuite { IPeakFunctionIntensityTest() : m_blackList() { FrameworkManager::Instance(); - m_blackList.insert("BackToBackExponential"); m_blackList.insert("DeltaFunction"); m_blackList.insert("ElasticDiffRotDiscreteCircle"); m_blackList.insert("ElasticDiffSphere"); From 700f6b7e98609573b304db80d8ba1d3f1ba654e9 Mon Sep 17 00:00:00 2001 From: Steven Hahn Date: Thu, 19 Feb 2015 10:12:17 -0500 Subject: [PATCH 274/275] Refs #11130. Add missing header to InternetHelper.h --- Code/Mantid/Framework/Kernel/inc/MantidKernel/InternetHelper.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/InternetHelper.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/InternetHelper.h index f655d8bb1739..88d2df21fa57 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/InternetHelper.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/InternetHelper.h @@ -5,6 +5,7 @@ #include "MantidKernel/DllConfig.h" #include "MantidKernel/ProxyInfo.h" +#include #include namespace Poco { From ee1e6ddd59c519712fad6cd526c2433fdee84e41 Mon Sep 17 00:00:00 2001 From: Steven Hahn Date: Thu, 19 Feb 2015 13:39:35 -0500 Subject: [PATCH 275/275] Refs #11132. fix boost linking errors. --- Code/Mantid/Framework/API/test/PeakTransformHKLTest.h | 10 ++++++++++ .../Mantid/Framework/API/test/PeakTransformQLabTest.h | 10 ++++++++++ .../Framework/API/test/PeakTransformQSampleTest.h | 11 +++++++++++ 3 files changed, 31 insertions(+) diff --git a/Code/Mantid/Framework/API/test/PeakTransformHKLTest.h b/Code/Mantid/Framework/API/test/PeakTransformHKLTest.h index f726f3355326..20a99d8feac7 100644 --- a/Code/Mantid/Framework/API/test/PeakTransformHKLTest.h +++ b/Code/Mantid/Framework/API/test/PeakTransformHKLTest.h @@ -10,6 +10,16 @@ using namespace Mantid::API; using Mantid::Kernel::V3D; using namespace testing; +namespace boost{ + template + std::basic_ostream& operator<<(std::basic_ostream& out, optional const& maybe) + { + if (maybe) + out << maybe; + return out; + } +} + class PeakTransformHKLTest : public CxxTest::TestSuite { public: diff --git a/Code/Mantid/Framework/API/test/PeakTransformQLabTest.h b/Code/Mantid/Framework/API/test/PeakTransformQLabTest.h index b3184387f832..849824ad26cc 100644 --- a/Code/Mantid/Framework/API/test/PeakTransformQLabTest.h +++ b/Code/Mantid/Framework/API/test/PeakTransformQLabTest.h @@ -11,6 +11,16 @@ using namespace Mantid; using Mantid::Kernel::V3D; using namespace testing; +namespace boost{ + template + std::basic_ostream& operator<<(std::basic_ostream& out, optional const& maybe) + { + if (maybe) + out << maybe; + return out; + } +} + class PeakTransformQLabTest : public CxxTest::TestSuite { diff --git a/Code/Mantid/Framework/API/test/PeakTransformQSampleTest.h b/Code/Mantid/Framework/API/test/PeakTransformQSampleTest.h index f3d01c140557..9e970ba1b51a 100644 --- a/Code/Mantid/Framework/API/test/PeakTransformQSampleTest.h +++ b/Code/Mantid/Framework/API/test/PeakTransformQSampleTest.h @@ -11,6 +11,17 @@ using namespace Mantid; using Mantid::Kernel::V3D; using namespace testing; + +namespace boost{ + template + std::basic_ostream& operator<<(std::basic_ostream& out, optional const& maybe) + { + if (maybe) + out << maybe; + return out; + } +} + class PeakTransformQSampleTest : public CxxTest::TestSuite {