Skip to content

Commit

Permalink
More general refactoring
Browse files Browse the repository at this point in the history
Refs #9344
  • Loading branch information
DanNixon committed Aug 14, 2014
1 parent d498250 commit 4aa4710
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 130 deletions.
2 changes: 1 addition & 1 deletion Code/Mantid/scripts/Inelastic/IndirectBayes.py
Expand Up @@ -972,4 +972,4 @@ def ResNormPlot(inputWS,Plot):
s_plot=mp.plotSpectrum(sWS,0,False)
if (Plot == 'Fit' or Plot == 'All'):
fWS = inputWS + '_ResNorm_Fit'
f_plot=mp.plotSpectrum(fWS,0,False)
f_plot=mp.plotSpectrum(fWS,0,False)
98 changes: 63 additions & 35 deletions Code/Mantid/scripts/Inelastic/IndirectCommon.py
Expand Up @@ -4,28 +4,34 @@

from IndirectImport import import_mantidplot

import os.path, math, datetime, re
import os.path
import math
import datetime
import re
import numpy as np
import itertools


def StartTime(prog):
logger.notice('----------')
message = 'Program ' + prog +' started @ ' + str(datetime.datetime.now())
message = 'Program ' + prog + ' started @ ' + str(datetime.datetime.now())
logger.notice(message)


def EndTime(prog):
message = 'Program ' + prog +' ended @ ' + str(datetime.datetime.now())
message = 'Program ' + prog + ' ended @ ' + str(datetime.datetime.now())
logger.notice(message)
logger.notice('----------')


def loadInst(instrument):
workspace = '__empty_' + instrument
if not mtd.doesExist(workspace):
idf_dir = config['instrumentDefinition.directory']
idf = idf_dir + instrument + '_Definition.xml'
LoadEmptyInstrument(Filename=idf, OutputWorkspace=workspace)


def loadNexus(filename):
'''
Loads a Nexus file into a workspace with the name based on the
Expand All @@ -36,6 +42,7 @@ def loadNexus(filename):
LoadNexus(Filename=filename, OutputWorkspace=name)
return name


def getInstrRun(ws_name):
'''
Get the instrument name and run number from a workspace.
Expand All @@ -46,7 +53,7 @@ def getInstrRun(ws_name):
workspace = mtd[ws_name]
run_number = str(workspace.getRunNumber())
if run_number == '0':
#attempt to parse run number off of name
# attempt to parse run number off of name
match = re.match(r'([a-zA-Z]+)([0-9]+)', ws_name)
if match:
run_number = match.group(2)
Expand All @@ -59,6 +66,7 @@ def getInstrRun(ws_name):
instrument = instrument.lower()
return instrument, run_number


def getWSprefix(wsname):
'''
Returns a string of the form '<ins><run>_<analyser><refl>_' on which
Expand All @@ -77,7 +85,7 @@ def getWSprefix(wsname):

(instrument, run_number) = getInstrRun(wsname)
if facility == 'ILL':
run_name = instrument + '_'+ run_number
run_name = instrument + '_' + run_number
else:
run_name = instrument + run_number

Expand All @@ -95,10 +103,12 @@ def getWSprefix(wsname):

return prefix


def getEfixed(workspace, det_index=0):
inst = mtd[workspace].getInstrument()
return inst.getNumberParameter("efixed-val")[0]


def checkUnitIs(ws, unit_id, axis_index=0):
"""
Check that the workspace has the correct units by comparing
Expand All @@ -108,6 +118,7 @@ def checkUnitIs(ws, unit_id, axis_index=0):
unit = axis.getUnit()
return unit.unitID() == unit_id


# Get the default save directory and check it's valid
def getDefaultWorkingDirectory():
workdir = config['defaultsave.directory']
Expand All @@ -117,6 +128,7 @@ def getDefaultWorkingDirectory():

return workdir


def createQaxis(inputWS):
result = []
workspace = mtd[inputWS]
Expand All @@ -129,7 +141,7 @@ def createQaxis(inputWS):
efixed = getEfixed(inputWS, i)
detector = workspace.getDetector(i)
theta = detector.getTwoTheta(sample_pos, beam_pos) / 2
lamda = math.sqrt(81.787/efixed)
lamda = math.sqrt(81.787 / efixed)
q_value = 4 * math.pi * math.sin(theta) / lamda
result.append(q_value)
else:
Expand All @@ -145,6 +157,7 @@ def createQaxis(inputWS):
result.append(float(axis.label(i)))
return result


def GetWSangles(in_ws):
nhist = mtd[in_ws].getNumberHistograms() # get no. of histograms/groups
source_pos = mtd[in_ws].getInstrument().getSource().getPos()
Expand All @@ -153,39 +166,44 @@ def GetWSangles(in_ws):
angles = [] # will be list of angles
for index in range(0, nhist):
detector = mtd[in_ws].getDetector(index) # get index
two_theta = detector.getTwoTheta(sample_pos, beam_pos)*180.0/math.pi # calc angle
two_theta = detector.getTwoTheta(sample_pos, beam_pos) * 180.0 / math.pi # calc angle
angles.append(two_theta) # add angle
return angles


def GetThetaQ(workspace):
efixed = getEfixed(workspace)
wavelas = math.sqrt(81.787/efixed) # elastic wavelength
k0_val = 4.0*math.pi/wavelas
wavelas = math.sqrt(81.787 / efixed) # elastic wavelength
k0_val = 4.0 * math.pi / wavelas

theta = np.array(GetWSangles(workspace))
q_val = k0_val * np.sin(0.5 * np.radians(theta))

return theta, q_val


def ExtractFloat(data_string):
""" Extract float values from an ASCII string"""
values = data_string.split()
values = map(float, values)
return values


def ExtractInt(data_string):
""" Extract int values from an ASCII string"""
values = data_string.split()
values = map(int, values)
return values


def PadArray(inarray, nfixed): # pad a list to specified size
npt = len(inarray)
padding = nfixed-npt
outarray = []
outarray.extend(inarray)
outarray += [0]*padding
return outarray
npt = len(inarray)
padding = nfixed - npt
outarray = []
outarray.extend(inarray)
outarray += [0] * padding
return outarray


def CheckAnalysers(in1_ws, in2_ws, verbose):
ws1 = mtd[in1_ws]
Expand All @@ -195,23 +213,25 @@ def CheckAnalysers(in1_ws, in2_ws, verbose):
analyser2 = ws2.getInstrument().getStringParameter('analyser')[0]
reflection2 = ws2.getInstrument().getStringParameter('reflection')[0]
if analyser1 != analyser2:
raise ValueError('Workspace '+in1_ws+' and '+in2_ws+' have different analysers')
raise ValueError('Workspace ' + in1_ws + ' and ' + in2_ws + ' have different analysers')
elif reflection1 != reflection2:
raise ValueError('Workspace '+in1_ws+' and '+in2_ws+' have different reflections')
raise ValueError('Workspace ' + in1_ws + ' and ' + in2_ws + ' have different reflections')
else:
if verbose:
logger.notice('Analyser is '+analyser1+reflection1)
logger.notice('Analyser is ' + analyser1 + reflection1)


def CheckHistZero(in_ws):
nhist = mtd[in_ws].getNumberHistograms() # no. of hist/groups in WS
if nhist == 0:
raise ValueError('Workspace '+in_ws+' has NO histograms')
raise ValueError('Workspace ' + in_ws + ' has NO histograms')
x_in = mtd[in_ws].readX(0)
ntc = len(x_in) - 1 # no. points from length of x array
if ntc == 0:
raise ValueError('Workspace '+in_ws+' has NO points')
raise ValueError('Workspace ' + in_ws + ' has NO points')
return nhist, ntc


def CheckHistSame(in1_ws, name1, in2_ws, name2):
num_hist1 = mtd[in1_ws].getNumberHistograms() # no. of hist/groups in WS1
x_range1 = mtd[in1_ws].readX(0)
Expand All @@ -228,31 +248,34 @@ def CheckHistSame(in1_ws, name1, in2_ws, name2):
name1, in1_ws, x_len1, name2, in2_ws, x_len2)
raise ValueError(error_str)


def CheckXrange(x_range, range_type):
if not ((len(x_range) == 2) or (len(x_range) == 4)):
raise ValueError(range_type + ' - Range must contain either 2 or 4 numbers')

for lower, upper in zip(x_range[::2], x_range[1::2]):
if math.fabs(lower) < 1e-5:
raise ValueError(range_type+' - input minimum ('+str(lower)+') is Zero')
raise ValueError(range_type + ' - input minimum (' + str(lower) + ') is Zero')
if math.fabs(upper) < 1e-5:
raise ValueError(range_type+' - input maximum ('+str(upper)+') is Zero')
raise ValueError(range_type + ' - input maximum (' + str(upper) + ') is Zero')
if upper < lower:
raise ValueError(range_type+' - input max ('+str(upper)+') < min ('+str(lower)+')')
raise ValueError(range_type + ' - input max (' + str(upper) + ') < min (' + str(lower) + ')')


def CheckElimits(e_range, x_in):
x_len = len(x_in) - 1

if math.fabs(e_range[0]) < 1e-5:
raise ValueError('Elimits - input emin ( '+str(e_range[0])+' ) is Zero')
raise ValueError('Elimits - input emin ( ' + str(e_range[0]) + ' ) is Zero')
if e_range[0] < x_in[0]:
raise ValueError('Elimits - input emin ( '+str(e_range[0])+' ) < data emin ( '+str(x_in[0])+' )')
raise ValueError('Elimits - input emin ( ' + str(e_range[0]) + ' ) < data emin ( ' + str(x_in[0]) + ' )')
if math.fabs(e_range[1]) < 1e-5:
raise ValueError('Elimits - input emax ( '+str(e_range[1])+' ) is Zero')
raise ValueError('Elimits - input emax ( ' + str(e_range[1]) + ' ) is Zero')
if e_range[1] > x_in[x_len]:
raise ValueError('Elimits - input emax ( '+str(e_range[1])+' ) > data emax ( '+str(x_in[x_len])+' )')
raise ValueError('Elimits - input emax ( ' + str(e_range[1]) + ' ) > data emax ( ' + str(x_in[x_len]) + ' )')
if e_range[1] < e_range[0]:
raise ValueError('Elimits - input emax ( '+str(e_range[1])+' ) < emin ( '+str(e_range[0])+' )')
raise ValueError('Elimits - input emax ( ' + str(e_range[1]) + ' ) < emin ( ' + str(e_range[0]) + ' )')


def getInstrumentParameter(ws, param_name):
"""Get an named instrument parameter from a workspace.
Expand All @@ -279,6 +302,7 @@ def getInstrumentParameter(ws, param_name):

return param


def plotSpectra(ws, y_axis_title, indicies=[]):
"""
Plot a selection of spectra given a list of indicies
Expand All @@ -301,6 +325,7 @@ def plotSpectra(ws, y_axis_title, indicies=[]):
# User clicked cancel on plot so don't do anything
return


def plotParameters(ws, *param_names):
"""
Plot a number of spectra given a list of parameter names
Expand All @@ -319,6 +344,7 @@ def plotParameters(ws, *param_names):
if len(indicies) > 0:
plotSpectra(ws, name, indicies)


def convertToElasticQ(input_ws, output_ws=None):
"""
Helper function to convert the spectrum axis of a sample to ElasticQ.
Expand All @@ -344,6 +370,7 @@ def convertToElasticQ(input_ws, output_ws=None):
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.
Expand All @@ -359,7 +386,7 @@ def transposeFitParametersTable(params_table, output_table=None):
table_ws = '__tmp_table_ws'
table_ws = CreateEmptyTableWorkspace(OutputWorkspace=table_ws)

param_names = params_table.column(0)[:-1] #-1 to remove cost function
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]

Expand All @@ -381,11 +408,11 @@ def transposeFitParametersTable(params_table, output_table=None):
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]
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
row = [i / num_params] + row
table_ws.addRow(row)

if output_table is None:
Expand Down Expand Up @@ -422,7 +449,7 @@ def convertParametersToWorkspace(params_table, x_column, param_names, output_nam
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)
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)
Expand All @@ -443,7 +470,7 @@ def convertParametersToWorkspace(params_table, x_column, param_names, output_nam
temp_workspaces.append(temp_peak_ws)

# join all peaks into a single workspace
##TODO: I'm not sure exactly what this is supposed to do
# TODO: I'm not sure exactly what this is supposed to do
temp_workspace = temp_workspaces[0]
for temp_ws in temp_workspaces[1:]:
ConjoinWorkspaces(temp_workspace, temp_peak_ws, False)
Expand All @@ -458,6 +485,7 @@ def convertParametersToWorkspace(params_table, x_column, param_names, output_nam

mtd[output_name].replaceAxis(1, axis)


def addSampleLogs(ws, sample_logs):
"""
Add a dictionary of logs to a workspace.
Expand Down

0 comments on commit 4aa4710

Please sign in to comment.