Skip to content

Commit

Permalink
Re #10881 Descriptor in working state for single file
Browse files Browse the repository at this point in the history
  • Loading branch information
abuts committed Jan 14, 2015
1 parent 8748b7c commit 911d3d8
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 111 deletions.
86 changes: 5 additions & 81 deletions Code/Mantid/scripts/Inelastic/Direct/DirectEnergyConversion.py
Expand Up @@ -1021,37 +1021,6 @@ def remap(self, result_ws, spec_masks, map_file):

return mtd[ws_name]

def get_monitors_ws(self,data_ws,method,mon_number=None):
""" 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.
"""


if mon_number is None:
if method == 'monitor-2':
mon_spectr_num=int(self.prop_man.mon2_norm_spec)
else:
mon_spectr_num=int(self.prop_man.mon1_norm_spec)
else:
mon_spectr_num=mon_number

monWS_name = data_ws.getName()+'_monitors'
if monWS_name in mtd:
mon_ws = mtd[monWS_name];
else:
# get pointer to the workspace
mon_ws=data_ws;

# get the index of the monitor spectra
ws_index= mon_ws.getIndexFromSpectrumNumber(mon_spectr_num);
# create monitor workspace consisting of single index
mon_ws = ExtractSingleSpectrum(InputWorkspace=data_ws,OutputWorkspace=monWS_name,WorkspaceIndex=ws_index);

mon_index = mon_ws.getIndexFromSpectrumNumber(mon_spectr_num);
return (mon_ws,mon_index);



def normalise(self, data_ws, result_name, method, range_offset=0.0,mon_number=None):
Expand Down Expand Up @@ -1202,11 +1171,11 @@ def load_data(self, runs,new_ws_name=None,keep_previous_ws=False):
#

self.setup_instrument_properties(result_ws)
# TODO: is it possible to have spectra_to_monitors_list defined and monitors loaded with workspace? then all below will fail miserably.
spec_to_mon = propman.spectra_to_monitors_list;
if monitor_ws and spec_to_mon :
for specID in spec_to_mon:
result_ws,monitor_ws=self.copy_spectrum2monitors(result_ws,monitor_ws,specID);
## TODO: is it possible to have spectra_to_monitors_list defined and monitors loaded with workspace? then all below will fail miserably.
#spec_to_mon = propman.spectra_to_monitors_list;
#if monitor_ws and spec_to_mon :
# for specID in spec_to_mon:
# result_ws,monitor_ws=self.copy_spectrum2monitors(result_ws,monitor_ws,specID);

return (result_ws,monitor_ws)

Expand Down Expand Up @@ -1250,51 +1219,6 @@ def check_monitor_ws(data_ws,monitor_ws,ei_mon_spectra):

return (data_ws,monitor_ws)

@staticmethod
def copy_spectrum2monitors(wsName,monWSName,spectraID):
"""
this routine copies a spectrum form workspace to monitor workspace and rebins it according to monitor workspace binning
@param wsName -- the name of event workspace which detector is considered as monitor or Mantid pointer to this workspace
@param monWSName -- the name of histogram workspace with monitors where one needs to place the detector's spectra or Mantid pointer to this workspace
@param spectraID -- the ID of the spectra to copy.
TODO: As extract single spectrum works only with WorkspaceIndex, we have to assume that WorkspaceIndex=spectraID-1;
this is not always correct, so it is better to change ExtractSingleSpectrum to accept workspaceID
"""
if isinstance(wsName,str):
ws = mtd[wsName]
else:
ws = wsName;
if isinstance(monWSName,str):
monWS = mtd[monWSName];
else:
monWS = monWSName;
# ----------------------------
try:
ws_index = monWS.getIndexFromSpectrumNumber(spectraID)
# Spectra is already in the monitor workspace
return (ws,monWS)
except:
ws_index = ws.getIndexFromSpectrumNumber(spectraID)



#
x_param = monWS.readX(0);
bins = [x_param[0],x_param[1]-x_param[0],x_param[-1]];
ExtractSingleSpectrum(InputWorkspace=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 = monWS.getName();
ConjoinWorkspaces(InputWorkspace1=monWS,InputWorkspace2='tmp_mon')
monWS=mtd[mon_ws_name]

if 'tmp_mon' in mtd:
DeleteWorkspace(WorkspaceName='tmp_mon');
return (ws,monWS);

@property
def prop_man(self):
""" Return property manager containing DirectEnergyConversion parameters """
Expand Down
4 changes: 2 additions & 2 deletions Code/Mantid/scripts/Inelastic/Direct/NonIDF_Properties.py
Expand Up @@ -46,8 +46,8 @@ def __init__(self,Instrument,run_workspace=None):
self._set_instrument_and_facility(Instrument,run_workspace)

# set up descriptors holder class reference
RunDescriptor.__holder_class__ = self
RunDescriptor.logger = self.log
RunDescriptor._holder = self
RunDescriptor._logger = self.log

#end
#-----------------------------------------------------------------------------
Expand Down
123 changes: 96 additions & 27 deletions Code/Mantid/scripts/Inelastic/Direct/RunDescriptor.py
Expand Up @@ -11,8 +11,8 @@ class RunDescriptor(PropDescriptor):
# the host class referencing contained all instantiated descriptors.
# Descriptors methods rely on it to work (e.g. to extract file loader preferences)
# so it has to be set up manually by PropertyManager __init__ method
__holder_class__=None
logger = None
_holder=None
_logger = None

def __init__(self,ws_preffix,DocString=None):
""" """
Expand All @@ -28,9 +28,6 @@ def __init__(self,ws_preffix,DocString=None):
if not DocString is None:
self.__doc__ = DocString

if RunDescriptor.__holder_class__:
logger = RunDescriptor.__holder_class__.log()

def __get__(self,instance,owner=None):
""" return current run number"""
if instance is None:
Expand All @@ -45,7 +42,7 @@ def __set__(self,instance,value):
self._run_ext = None
return
if isinstance(value, api.Workspace):
self._run_number = value.getRunNuber()
self._run_number = value.getRunNumber()
self._run_ws_name= value.name()
return

Expand Down Expand Up @@ -73,7 +70,7 @@ def get_file_ext(self):
if self._run_ext:
return self._run_ext
else: # return IDF default
return RunDescriptor.__holder_class__.data_file_ext
return RunDescriptor._holder.data_file_ext

def set_file_ext(self,val):
""" set non-default file extension """
Expand All @@ -89,11 +86,11 @@ def set_file_ext(self,val):
def find_file(self,run_num = None):
"""Use Mantid to search for the given run. """

inst_name = RunDescriptor.__holder_class__.short_inst_name
inst_name = RunDescriptor._holder.short_inst_name
if run_num:
run_num_str = str(run_num)
else:
run_num_str = str(self.__get__(RunDescriptor.__holder_class__))
run_num_str = str(self.__get__(RunDescriptor._holder))
#
file_hint =inst_name + run_num_str + self.get_file_ext()
try:
Expand All @@ -102,12 +99,14 @@ def find_file(self,run_num = None):
message = 'Cannot find file matching hint {0} on current search paths ' \
'for instrument {1}'.format(file_hint,inst_name)

logger(message,'warning')
RunDescriptor._logger(message,'warning')
return 'ERROR:find_file '+message

def get_workspace(self):
""" Method returns workspace correspondent to current run number(s)
and loads this workspace if necessary
and loads this workspace if it has not been loaded
Returns Mantid pointer to the workspace, corresponding to this run number
"""
if not self._run_ws_name:
return None
Expand All @@ -116,29 +115,57 @@ def get_workspace(self):
return mtd[self._run_ws_name]
else:
if self._run_number:
inst_name = RunDescriptor.__holder_class__.short_inst_name
calibration = RunDescriptor.__holder_class__.det_cal_file
return self.load_run(inst_name, calibration,False, RunDescriptor.__holder_class__.load_monitors_with_workspace)
inst_name = RunDescriptor._holder.short_inst_name
calibration = RunDescriptor._holder.det_cal_file
return self.load_run(inst_name, calibration,False, RunDescriptor._holder.load_monitors_with_workspace)
else:
return None

def get_monitors_ws(self):
""" 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.
"""

data_ws = self.get_workspace()

monWS_name = self.get_ws_name()+'_monitors'
if monWS_name in mtd:
mon_ws = mtd[monWS_name]
monitors_separate = True
else:
mon_ws = data_ws
monitors_separate = False

spec_to_mon = RunDescriptor._holder.spectra_to_monitors_list
if monitors_separate and spec_to_mon :
for specID in spec_to_mon:
mon_ws=self.copy_spectrum2monitors(data_ws,mon_ws,specID);

return mon_ws

def get_ws_name(self):
""" return workspace name. If ws name is not defined, build it first and set up as target ws name
"""

if self._run_ws_name:
return self._run_ws_name

if RunDescriptor.__holder_class__:
instr_name = RunDescriptor.__holder_class__.short_inst_name
if RunDescriptor._holder:
instr_name = RunDescriptor._holder.short_inst_name
else:
instr_name = '_test_instrument'

if not RunDescriptor.__holder_class__.sum_runs:
ws_name = common.create_resultname(self._run_number,instr_name+self._ws_preffix)
suffix = '' # not implemented
if RunDescriptor._holder.sum_runs:
ws_name = "NotImplemented"
else:
ws_name = common.create_resultname(self._run_number,instr_name+self._ws_preffix,'-sum')
ws_name = '{0}{1}{2:0>#6d}{3}'.format(instr_name,self._ws_preffix,self._run_number,suffix)


self._run_ws_name = ws_name

return ws_name
Expand All @@ -153,17 +180,22 @@ def load_run(self,inst_name, calibration=None, force=False, load_with_workspace=
ws_name = self.get_ws_name()

if ws_name in mtd and not(force):
RunDescriptor.logger("{0} already loaded as workspace.".format(self._run_ws_name),'notice')
RunDescriptor._logger("{0} already loaded as workspace.".format(self._run_ws_name),'notice')
loaded_ws = mtd[ws_name]
else:
# If it doesn't exists as a workspace assume we have to try and load a file
data_file = self.find_file()
if data_file[0:4] == 'ERROR':
raise IOError(data_file)

raise IOError(data_file)

format = self.get_file_ext()
if format =='.raw' and load_with_workspace:
mon_load_option = 'Include'
else:
mon_load_option =str(int(load_with_workspace))

Load(Filename=data_file, OutputWorkspace=ws_name,LoadMonitors = str(int(load_with_workspace)))
RunDescriptor.logger("Loaded {0}".format(data_file),'notice')
Load(Filename=data_file, OutputWorkspace=ws_name,LoadMonitors = mon_load_option)
RunDescriptor._logger("Loaded {0}".format(data_file),'notice')
loaded_ws = mtd[ws_name]

######## Now we have the workspace
Expand All @@ -182,17 +214,54 @@ def apply_calibration(self,loaded_ws,calibration=None):
return # already calibrated

if type(calibration) == str : # It can be only a file (got it from calibration property)
RunDescriptor.logger('load_data: Moving detectors to positions specified in cal file {0}'.format(calibration),'debug')
RunDescriptor._logger('load_data: Moving detectors to positions specified in cal file {0}'.format(calibration),'debug')
# Pull in pressures, thicknesses & update from cal file
LoadDetectorInfo(Workspace=loaded_ws, DataFilename=calibration, RelocateDets=True)
AddSampleLog(Workspace=loaded_ws,LogName="calibrated",LogText=str(calibration))
elif isinstance(calibration, api.Workspace):
logger('load_data: Copying detectors positions from workspace {0}: '.format(calibration.name()),'debug')
RunDescriptor._logger('load_data: Copying detectors positions from workspace {0}: '.format(calibration.name()),'debug')
CopyInstrumentParameters(InputWorkspace=calibration,OutputWorkspace=loaded_ws)
AddSampleLog(Workspace=loaded_ws,LogName="calibrated",LogText=str(calibration))

@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 spectraID-- the ID of the spectra to copy.
"""

# ----------------------------
try:
ws_index = mon_ws.getIndexFromSpectrumNumber(spectraID)
# Spectra is already in the monitor workspace
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')
# 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]

if 'tmp_mon' in mtd:
DeleteWorkspace(WorkspaceName='tmp_mon')
return mon_ws


#-------------------------------------------------------------------------------------------------------------------------------
class RunDescriptorDependent(RunDescriptor):
""" A RunDescriptor class dependent on another RunDescriptor"""

def __init__(self,host_run,ws_preffix,DocString=None):
RunDescriptor.__init__(self,ws_preffix,DocString)
self._host = host_run
Expand Down
19 changes: 18 additions & 1 deletion Code/Mantid/scripts/test/RunDescriptorTest.py
Expand Up @@ -115,8 +115,25 @@ def test_load_workspace(self):
self.assertTrue(isinstance(ws, api.Workspace))
self.assertEqual(ws.name(), PropertyManager.sample_run.get_ws_name())


mon_ws = PropertyManager.sample_run.get_monitors_ws()
self.assertTrue(isinstance(mon_ws, api.Workspace))
self.assertEqual(mon_ws.name(),ws.name())

def test_copy_spectra2monitors(self):
propman = self.prop_man
run_ws = CreateSampleWorkspace( Function='Multiple Peaks', WorkspaceType = 'Event',NumBanks=1, BankPixelWidth=5, NumEvents=100)
run_ws_monitors = CreateSampleWorkspace( Function='Multiple Peaks', WorkspaceType = 'Histogram',NumBanks=1, BankPixelWidth=1, NumEvents=100)
self.assertEqual(run_ws_monitors.getNumberHistograms(),1)


propman.monovan_run = run_ws
propman.spectra_to_monitors_list = 3

mon_ws = PropertyManager.monovan_run.get_monitors_ws()
self.assertTrue(isinstance(mon_ws, api.Workspace))
self.assertEqual(mon_ws.getNumberHistograms(),2)
self.assertEqual(mon_ws.getIndexFromSpectrumNumber(3),1)



if __name__=="__main__":
Expand Down

0 comments on commit 911d3d8

Please sign in to comment.