Skip to content

Commit

Permalink
Re #10836 Simplified update_defaults_from_instrument logic
Browse files Browse the repository at this point in the history
and add common PropertyManager interface (returning empty dependencies list by default)
  • Loading branch information
abuts committed Jan 12, 2015
1 parent 76f16eb commit 932f44c
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 55 deletions.
30 changes: 18 additions & 12 deletions Code/Mantid/scripts/Inelastic/Direct/PropertiesDescriptors.py
Expand Up @@ -15,7 +15,13 @@
#-----------------------------------------------------------------------------------------
# Descriptors, providing overloads for complex properties in NonIDF_Properties class
#-----------------------------------------------------------------------------------------
class IncidentEnergy(object):
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"""
return []
# end PropDescriptor
class IncidentEnergy(PropDescriptor):
""" descriptor for incident energy or range of incident energies to be processed """
def __init__(self):
self._incident_energy = None
Expand Down Expand Up @@ -66,7 +72,7 @@ def __set__(self,instance,value):
raise KeyError("Incident energy have to be positive number of list of positive numbers."+
" For value {0} got negative {1}".format(value,inc_en))
# end IncidentEnergy
class EnergyBins(object):
class EnergyBins(PropDescriptor):
""" Property provides various energy bin possibilities """
def __init__(self):
self._energy_bins=None
Expand All @@ -93,7 +99,7 @@ def __set__(self,instance,values):
#TODO: implement single value settings according to rebin
self._energy_bins = value
#end EnergyBins
class SaveFileName(object):
class SaveFileName(PropDescriptor):
""" Property defines default file name to save result to
See similar property get_sample_ws_name TODO: (leave only one)
Expand Down Expand Up @@ -130,7 +136,7 @@ def __set__(self,instance,value):
#end SaveFileName

#
class InstrumentDependentProp(object):
class InstrumentDependentProp(PropDescriptor):
""" Generic property describing some aspects of instrument (e.g. name, short name etc),
which are undefined if no instrument is defined
"""
Expand Down Expand Up @@ -162,7 +168,7 @@ def check_ei_bin_consistent(ei,binning_range):

return (True,'')

class VanadiumRMM(object):
class VanadiumRMM(PropDescriptor):
""" define constant static rmm for vanadium """
def __get__(self,instance,owner=None):
""" return rmm for vanadium """
Expand All @@ -178,7 +184,7 @@ def __set__(self,instance,value):
#-----------------------------------------------------------------------------------------
# Descriptors, providing overloads for some complex properties in PropertyManager
#-----------------------------------------------------------------------------------------
class PropertyFromRange(object):
class PropertyFromRange(PropDescriptor):
""" Descriptor for property, which can have one value from a list of values """
def __init__(self,availible_values,default_value):
self._availible_values = availible_values
Expand All @@ -198,7 +204,7 @@ def __set__(self,instance,val):
raise KeyError(' Property can not have value {0}'.format(val))


class DetCalFile(object):
class DetCalFile(PropDescriptor):
""" property describes various sources for the detector calibration file """
def __init__(self):
self._det_cal_file = None
Expand Down Expand Up @@ -236,7 +242,7 @@ def __set__(self,instance,val):
# Reducer.log('Setting detector calibration to detector block info from '+str(sample_run))
#end DetCalFile

class MapMaskFile(object):
class MapMaskFile(PropDescriptor):
""" common method to wrap around an auxiliary file name """
def __init__(self,file_ext,doc_string=None):
self._file_name=None;
Expand Down Expand Up @@ -404,7 +410,7 @@ def __set__(self,instance,value):
#end MonovanIntegrationRange


class SpectraToMonitorsList(object):
class SpectraToMonitorsList(PropDescriptor):
""" property describes list of spectra, used as monitors to estimate incident energy
in a direct scattering experiment.
Expand Down Expand Up @@ -453,7 +459,7 @@ def _convert_to_list(self,spectra_list):
return result
#end SpectraToMonitorsList

class SaveFormat(object):
class SaveFormat(PropDescriptor):
# formats available for saving the data
save_formats = ['spe','nxspe','nxs']
def __init__(self):
Expand Down Expand Up @@ -500,7 +506,7 @@ def __set__(self,instance,value):
self._save_format.add(value)
#end SaveFormat

class DiagSpectra(object):
class DiagSpectra(PropDescriptor):
""" class describes spectra list which should be used in diagnostics
consist of tuples list where each tuple are the numbers
Expand Down Expand Up @@ -542,7 +548,7 @@ def _process_spectra_list(self,specta_sring):
raise ValueError("Spectra For diagnostics can be a string inthe form (num1,num2);(num3,num4) etc. or None")
#end class DiagSpectra

class BackbgroundTestRange(object):
class BackbgroundTestRange(PropDescriptor):
""" The TOF range used in diagnostics to reject high background spectra.
Usually it is the same range as the TOF range used to remove
Expand Down
74 changes: 33 additions & 41 deletions Code/Mantid/scripts/Inelastic/Direct/PropertyManager.py
Expand Up @@ -321,9 +321,9 @@ def update_defaults_from_instrument(self,pInstrument,ignore_changes=False):
"*** This only works if both instruments have the same reduction properties!"\
.format(self.instr_name,pInstrument.getName()),'warning')

# Retrieve the properties, changed or set from interface earlier
old_changes_list = self.getChangedProperties()
self.setChangedProperties(set())

# record all changes, present in the old changes list
old_changes={}
for prop_name in old_changes_list:
Expand All @@ -336,36 +336,11 @@ def update_defaults_from_instrument(self,pInstrument,ignore_changes=False):
#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 complex properties first
for key,val in sorted_param.iteritems():
# complex properties change through their dependencies so we are setting them first
if isinstance(val,prop_helpers.ComplexProperty):
public_name = key[1:]
prop_new_val = val.__get__(param_list)
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)
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)
dependencies = val.dependencies()
for dep_name in dependencies:
# delete dependent properties not to deal with them again
del sorted_param[dep_name]
del sorted_param[key]
continue
else:
break # no complex properties left. finish for the time being
#end
# now the same for descriptors. Assignment to descriptors should accept the form, descriptor is written in IDF
# Walk through descriptors list and set their values
# Assignment to descriptors should accept the form, descriptor is written in IDF
for key,new_val in descr_dict.iteritems():
try: # this is reliability check, and except ideally should never be hit. May occur if old IDF contains
# properties, not present in recent IDF.
# properties, not present in recent IDF.
cur_val = getattr(self,key)
except:
self.log("property {0} have not been found in existing IDF. Ignoring this property"\
Expand All @@ -380,21 +355,38 @@ def update_defaults_from_instrument(self,pInstrument,ignore_changes=False):

for dep_name in dependencies:
if dep_name in sorted_param:
del sorted_param[dep_name]

del sorted_param[dep_name]
#end loop
# only simple properties left. Deal with them
for key,new_val in sorted_param.iteritems():

# Walk through the complex properties first and then through simple properties
for key,val in sorted_param.iteritems():
# complex properties change through their dependencies so we are setting them first
if isinstance(val,prop_helpers.ComplexProperty):
public_name = key[1:]
prop_new_val = val.__get__(param_list)
else:
# no complex properties left so we have simple key-value pairs
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
# properties, not present in recent IDF.
cur_val = getattr(self,key)
# properties, not present in recent IDF.
cur_val = getattr(self,public_name)
except:
self.log("property {0} have not been found in existing IDF. Ignoring this property"\
.format(key),'warning')
continue
if new_val != cur_val:
setattr(self,key,new_val)
#end loop
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)
try:
dependencies = val.dependencies()
except:
dependencies =[]
for dep_name in dependencies:
# delete dependent properties not to deal with them again
del sorted_param[dep_name]
#end


new_changes_list = self.getChangedProperties()
Expand Down
2 changes: 1 addition & 1 deletion Code/Mantid/scripts/Inelastic/Direct/ReductionHelpers.py
Expand Up @@ -39,7 +39,7 @@ def __set__(self,instance,value):
#changed_prop.append(key);
#return changed_prop;
def dependencies(self):
""" returns the list of properties names, this property depends on"""
""" returns the list of other properties names, this property depends on"""
return self._other_prop

def len(self):
Expand Down
2 changes: 1 addition & 1 deletion Code/Mantid/scripts/test/DirectPropertyManagerTest.py
@@ -1,5 +1,5 @@
import os
os.environ["PATH"] = r"c:/Mantid/Code/builds/br_master/bin/Release;"+os.environ["PATH"]
#os.environ["PATH"] = r"c:/Mantid/Code/builds/br_master/bin/Release;"+os.environ["PATH"]
from mantid.simpleapi import *
from mantid import api
import unittest
Expand Down

0 comments on commit 932f44c

Please sign in to comment.