From fe8712f93e57a0d45772c5d76f223ace9dfc507d Mon Sep 17 00:00:00 2001 From: abuts Date: Mon, 16 Dec 2024 13:30:23 +0000 Subject: [PATCH] Re #1790 Formally modified instrument-s to be hashable. Detectors incomplete. Tests needed --- .../instrument/@IX_aperture/IX_aperture.m | 23 +++++++++++++++---- .../IX_divergence_profile.m | 4 +++- .../IX_doubledisk_chopper.m | 6 ++++- .../@IX_fermi_chopper/IX_fermi_chopper.m | 9 +++++--- .../@IX_mod_shape_mono/IX_mod_shape_mono.m | 3 ++- .../instrument/@IX_moderator/IX_moderator.m | 11 ++++++++- .../instrument/@IX_mosaic/IX_mosaic.m | 5 +++- .../instrument/@IX_samp/IX_samp.m | 5 +++- .../instrument/@IX_sample/IX_sample.m | 5 ++++ .../instrument/@IX_source/IX_source.m | 5 +++- .../IX_det_abstractType.m | 2 +- .../@IX_detector_array/IX_detector_array.m | 8 +++---- .../@IX_detector_bank/IX_detector_bank.m | 4 ++-- .../instrument/instruments/@IX_inst/IX_inst.m | 9 +++++--- .../@IX_inst_DGdisk/IX_inst_DGdisk.m | 3 ++- .../@IX_inst_DGfermi/IX_inst_DGfermi.m | 2 ++ 16 files changed, 78 insertions(+), 26 deletions(-) diff --git a/herbert_core/classes/instrument_classes/instrument/@IX_aperture/IX_aperture.m b/herbert_core/classes/instrument_classes/instrument/@IX_aperture/IX_aperture.m index bd100a4419..4e4da60534 100644 --- a/herbert_core/classes/instrument_classes/instrument/@IX_aperture/IX_aperture.m +++ b/herbert_core/classes/instrument_classes/instrument/@IX_aperture/IX_aperture.m @@ -1,4 +1,4 @@ -classdef IX_aperture < serializable +classdef IX_aperture < hashable % Aperture class definition properties (Access=private) % Stored properties - but kept private and accessible only through @@ -85,14 +85,15 @@ % for the non-dependent properties. However, any interdependencies with % other properties must be checked here. function obj=set.name(obj,val) - if is_string(val) - obj.name_=val; - else + if ~is_string(val) error('HERBERT:IX_apperture:invalid_argument',... 'Sample name must be a character string (or empty string)') end obj.name_=val; + if obj.do_check_combo_arg_ + obj = obj.check_combo_arg(); + end end function obj=set.distance(obj,val) @@ -103,6 +104,10 @@ error('HERBERT:IX_apperture:invalid_argument',... 'Distance must be a numeric scalar') end + if obj.do_check_combo_arg_ + obj = obj.check_combo_arg(); + end + end function obj=set.width(obj,val) @@ -113,16 +118,24 @@ error('HERBERT:IX_apperture:invalid_argument',... 'Aperture width must be a numeric scalar greater than or equal to zero') end + if obj.do_check_combo_arg_ + obj = obj.check_combo_arg(); + end + end function obj=set.height(obj,val) if isscalar(val) && isnumeric(val) && val>=0 obj.height_=val; obj.mandatory_field_set_(3)=true; + else error('HERBERT:IX_apperture:invalid_argument',... 'Aperture height must be a numeric scalar greater than or equal to zero') end + if obj.do_check_combo_arg_ + obj = obj.check_combo_arg(); + end end %------------------------------------------------------------------ @@ -176,7 +189,7 @@ % problem it they are not, after recomputing dependent variables % if requested. - + obj = obj.clear_hash(); if ~all(obj.mandatory_field_set_) mandatory_field_names = obj.saveableFields('mandatory'); error('HERBERT:IX_aperture:invalid_argument', ... diff --git a/herbert_core/classes/instrument_classes/instrument/@IX_divergence_profile/IX_divergence_profile.m b/herbert_core/classes/instrument_classes/instrument/@IX_divergence_profile/IX_divergence_profile.m index adeab7d5e4..8183d99d10 100644 --- a/herbert_core/classes/instrument_classes/instrument/@IX_divergence_profile/IX_divergence_profile.m +++ b/herbert_core/classes/instrument_classes/instrument/@IX_divergence_profile/IX_divergence_profile.m @@ -1,4 +1,4 @@ -classdef IX_divergence_profile < serializable +classdef IX_divergence_profile < hashable % Divergence profile class definition properties (Access=private) @@ -117,6 +117,7 @@ 'IX_divergence_profile: The profile values must all be finite and greater or equal to zero') end obj.name_ = val; + obj = obj.clear_hash(); end % Currently do not permit any - it only makes sense to change the @@ -185,6 +186,7 @@ % Compute the pdf obj.pdf_ = pdf_table (obj.angles_, obj.profile_); end + obj = obj.clear_hash(); end end methods(Access=protected) diff --git a/herbert_core/classes/instrument_classes/instrument/@IX_doubledisk_chopper/IX_doubledisk_chopper.m b/herbert_core/classes/instrument_classes/instrument/@IX_doubledisk_chopper/IX_doubledisk_chopper.m index d835ee1bcf..eb90e8bb1e 100644 --- a/herbert_core/classes/instrument_classes/instrument/@IX_doubledisk_chopper/IX_doubledisk_chopper.m +++ b/herbert_core/classes/instrument_classes/instrument/@IX_doubledisk_chopper/IX_doubledisk_chopper.m @@ -1,4 +1,4 @@ -classdef IX_doubledisk_chopper < serializable +classdef IX_doubledisk_chopper < hashable % Double disk chopper class definition properties (Access=protected) @@ -122,6 +122,7 @@ error('HERBERT:IX_doubledisk_chopper:invalid_argument', ... 'Disk chopper name must be a character string (or empty string)') end + obj = obj.clear_hash(); end function obj=set.distance(obj,val) @@ -132,6 +133,7 @@ error('HERBERT:IX_doubledisk_chopper:invalid_argument', ... 'Distance must be a numeric scalar') end + obj = obj.clear_hash(); end function obj=set.frequency(obj,val) @@ -182,6 +184,7 @@ function obj=set.aperture_height(obj,val) obj = check_and_set_positive_scalar_(obj,'aperture_height_',val); + obj = obj.clear_hash(); end function obj=set.jitter(obj,val) @@ -290,6 +293,7 @@ if do_recompute_pdf obj.pdf_ = recompute_pdf_(obj); % recompute the lookup table end + obj = obj.clear_hash(); end end methods(Access=protected) diff --git a/herbert_core/classes/instrument_classes/instrument/@IX_fermi_chopper/IX_fermi_chopper.m b/herbert_core/classes/instrument_classes/instrument/@IX_fermi_chopper/IX_fermi_chopper.m index f22b49d88e..3505aca6e1 100644 --- a/herbert_core/classes/instrument_classes/instrument/@IX_fermi_chopper/IX_fermi_chopper.m +++ b/herbert_core/classes/instrument_classes/instrument/@IX_fermi_chopper/IX_fermi_chopper.m @@ -1,4 +1,4 @@ -classdef IX_fermi_chopper < serializable +classdef IX_fermi_chopper < hashable % Fermi chopper class definition properties (Constant, Access=private) % Conversion constant. Should replace by a class that gives constants @@ -146,6 +146,7 @@ 'Fermi chopper name must be a character string (or empty string). It is %s', ... disp2str(val)); end + obj = obj.clear_hash(); end function obj=set.distance(obj,val) if isscalar(val) && isnumeric(val) @@ -156,6 +157,7 @@ 'Distance must be a numeric scalar. It is: %s',... disp2str(val)); end + obj = obj.clear_hash(); end function obj=set.frequency(obj,val) obj = check_and_set_frequency_(obj,val); @@ -208,7 +210,7 @@ 'Chopper aperture width must be a numeric scalar greater or equal to zero It is: %s', ... disp2str(val)); end - + obj = obj.clear_hash(); end function obj=set.height(obj,val) @@ -219,7 +221,7 @@ 'Chopper aperture height must be a numeric scalar greater or equal to zero It is: %s', ... disp2str(val)); end - + obj = obj.clear_hash(); end function obj=set.energy(obj,val) @@ -394,6 +396,7 @@ if do_recompute_pdf obj.pdf_ = recompute_pdf_(obj); % recompute the lookup table end + obj = obj.clear_hash(); end end methods(Access=protected) diff --git a/herbert_core/classes/instrument_classes/instrument/@IX_mod_shape_mono/IX_mod_shape_mono.m b/herbert_core/classes/instrument_classes/instrument/@IX_mod_shape_mono/IX_mod_shape_mono.m index 91bbbf21f8..0745a0a971 100644 --- a/herbert_core/classes/instrument_classes/instrument/@IX_mod_shape_mono/IX_mod_shape_mono.m +++ b/herbert_core/classes/instrument_classes/instrument/@IX_mod_shape_mono/IX_mod_shape_mono.m @@ -1,4 +1,4 @@ -classdef IX_mod_shape_mono < serializable +classdef IX_mod_shape_mono < hashable % Moderator - shaping chopper - monochromating chopper as a single object properties (Access=private) @@ -226,6 +226,7 @@ obj.t_m_offset_ = obj.t_m_offset_calibrate_(); [obj.t_chop_cov_, obj.t_chop_av_] = obj.moments_ (); end + obj = obj.clear_hash(); end end diff --git a/herbert_core/classes/instrument_classes/instrument/@IX_moderator/IX_moderator.m b/herbert_core/classes/instrument_classes/instrument/@IX_moderator/IX_moderator.m index dd02360ee6..58f37eef36 100644 --- a/herbert_core/classes/instrument_classes/instrument/@IX_moderator/IX_moderator.m +++ b/herbert_core/classes/instrument_classes/instrument/@IX_moderator/IX_moderator.m @@ -1,4 +1,4 @@ -classdef IX_moderator < serializable +classdef IX_moderator < hashable % Moderator class definition properties (Constant, Access=private) @@ -152,6 +152,7 @@ error('IX_moderator:invalid_argument',... 'Moderator name must be a character string (or empty string)') end + obj = obj.clear_hash(); end function obj=set.distance(obj,val) @@ -162,6 +163,7 @@ error('IX_moderator:invalid_argument',... 'Distance must be a numeric scalar') end + obj = obj.clear_hash(); end function obj=set.angle(obj,val) @@ -172,6 +174,7 @@ error('IX_moderator:invalid_argument',... 'Moderator face angle must be a numeric scalar') end + obj = obj.clear_hash(); end function obj=set.pulse_model(obj,val) obj = check_and_set_pulse_model_(obj,val); @@ -191,22 +194,27 @@ function obj=set.width(obj,val) obj = check_and_set_nonnegative_scalar_(obj,'width',val); + obj = obj.clear_hash(); end function obj=set.height(obj,val) obj = check_and_set_nonnegative_scalar_(obj,'height',val); + obj = obj.clear_hash(); end function obj=set.thickness(obj,val) obj = check_and_set_nonnegative_scalar_(obj,'thickness',val); + obj = obj.clear_hash(); end function obj=set.temperature(obj,val) obj = check_and_set_nonnegative_scalar_(obj,'temperature',val); + obj = obj.clear_hash(); end function obj=set.energy(obj,val) obj = check_and_set_nonnegative_scalar_(obj,'energy',val); + obj = obj.clear_hash(); end %------------------------------------------------------------------ @@ -294,6 +302,7 @@ do_recompute_pdf = true; end obj = check_combo_recalc_pdf_(obj,do_recompute_pdf); + obj = obj.clear_hash(); end end diff --git a/herbert_core/classes/instrument_classes/instrument/@IX_mosaic/IX_mosaic.m b/herbert_core/classes/instrument_classes/instrument/@IX_mosaic/IX_mosaic.m index cc9800cef8..513ac546c0 100644 --- a/herbert_core/classes/instrument_classes/instrument/@IX_mosaic/IX_mosaic.m +++ b/herbert_core/classes/instrument_classes/instrument/@IX_mosaic/IX_mosaic.m @@ -1,4 +1,4 @@ -classdef IX_mosaic < serializable +classdef IX_mosaic < hashable % Mosaic spread object properties (Access=protected) % Stored properties - but kept private and accessible only through @@ -209,6 +209,7 @@ error('HERBERT:IX_mosaic:invalid_argument', ... 'Mosaic distribution function must be a function handle') end + obj = obj.clear_hash(); end function obj=set.mosaic_pdf_string(obj,val) if ~(isstring(val)||ischar(val)) @@ -217,6 +218,7 @@ class(val)) end obj.mosaic_pdf = str2func(val); + obj = obj.clear_hash(); end function obj=set.parameters(obj,val) obj.parameters_=val; @@ -282,6 +284,7 @@ '"xaxis=%s" and "yaxis=%s" are colinear, or almost colinear',... disp2str(obj.xaxis_),disp2str(obj.yaxis_)); end + obj = obj.clear_hash(); end end methods(Access=protected) diff --git a/herbert_core/classes/instrument_classes/instrument/@IX_samp/IX_samp.m b/herbert_core/classes/instrument_classes/instrument/@IX_samp/IX_samp.m index 4de65e7429..05df20d270 100644 --- a/herbert_core/classes/instrument_classes/instrument/@IX_samp/IX_samp.m +++ b/herbert_core/classes/instrument_classes/instrument/@IX_samp/IX_samp.m @@ -1,4 +1,4 @@ -classdef IX_samp < serializable +classdef IX_samp < hashable % Base class for samples to include the null sample case defined from a % structure with no fields (IX_null_sample) and the standard IX_sample @@ -95,6 +95,7 @@ 'Sample name must be a character string (or empty string)') end end + obj = obj.clear_hash(); end function name=get.name(obj) @@ -119,6 +120,7 @@ error('HERBERT:IX_samp:invalid_argument', ... 'Sample alatt must be a 1 or 3 compoment numeric vector') end + obj = obj.clear_hash(); end function alat=get.alatt(obj) alat = get_lattice(obj); @@ -147,6 +149,7 @@ end obj.angdeg_=val(:)'; + obj = obj.clear_hash(); end end methods(Access = protected) diff --git a/herbert_core/classes/instrument_classes/instrument/@IX_sample/IX_sample.m b/herbert_core/classes/instrument_classes/instrument/@IX_sample/IX_sample.m index 8b7e1688fd..07ab115680 100644 --- a/herbert_core/classes/instrument_classes/instrument/@IX_sample/IX_sample.m +++ b/herbert_core/classes/instrument_classes/instrument/@IX_sample/IX_sample.m @@ -149,6 +149,7 @@ error('HERBERT:IX_sample:invalid_argument',... 'Mosaic spread must be numeric or an IX_mosaic object') end + obj = obj.clear_hash(); end function obj=set.temperature(obj,val) @@ -158,6 +159,7 @@ error('HERBERT:IX_sample:invalid_argument',... 'Temperature must be numeric scalar greater than or equal to zero') end + obj = obj.clear_hash(); end function obj=set.hall_symbol(obj,val) @@ -171,6 +173,7 @@ 'Sample Hall symbol must be a character string (or empty string)') end end + obj = obj.clear_hash(); end function obj=set.xgeom(obj,val) if isnumeric(val) && numel(val)==3 && ~all(val==0) @@ -220,6 +223,7 @@ error('HERBERT:IX_sample:invalid_argument',... 'single_crystal must true or false (or 1 or 0)') end + obj = obj.clear_hash(); end function obj=set.shape(obj,val) @@ -352,6 +356,7 @@ error('HERBERT:IX_sample:invalid_argument',... 'The number of shape parameters is not correct for the sample type') end + obj = obj.clear_hash(); end end diff --git a/herbert_core/classes/instrument_classes/instrument/@IX_source/IX_source.m b/herbert_core/classes/instrument_classes/instrument/@IX_source/IX_source.m index ed9af84c2d..e87043988b 100644 --- a/herbert_core/classes/instrument_classes/instrument/@IX_source/IX_source.m +++ b/herbert_core/classes/instrument_classes/instrument/@IX_source/IX_source.m @@ -1,4 +1,4 @@ -classdef IX_source < serializable +classdef IX_source < hashable % Neutron source information % Basic information about the source, such as name, target_name and % operating frequency @@ -86,6 +86,7 @@ ' Its type is: %s and value %s'], ... class(val),disp2str(val)) end + obj = obj.clear_hash(); end function obj=set.target_name(obj,val) @@ -100,6 +101,7 @@ class(val),disp2str(val)) end obj.target_name_ = char(val); + obj = obj.clear_hash(); end function obj=set.frequency(obj,val) @@ -111,6 +113,7 @@ 'The target frequency must be a non-negative number') end obj.frequency_ = val; + obj = obj.clear_hash(); end %------------------------------------------------------------------ % Get methods for dependent properties diff --git a/herbert_core/classes/instrument_classes/instrument/detectors/@IX_det_abstractType/IX_det_abstractType.m b/herbert_core/classes/instrument_classes/instrument/detectors/@IX_det_abstractType/IX_det_abstractType.m index dd4f16044c..2975a1850c 100644 --- a/herbert_core/classes/instrument_classes/instrument/detectors/@IX_det_abstractType/IX_det_abstractType.m +++ b/herbert_core/classes/instrument_classes/instrument/detectors/@IX_det_abstractType/IX_det_abstractType.m @@ -1,4 +1,4 @@ -classdef (Abstract) IX_det_abstractType < serializable +classdef (Abstract) IX_det_abstractType < hashable % Abstract class to be inherited by detector classes % Defines one or more generic properties and required methods for all % detector types. diff --git a/herbert_core/classes/instrument_classes/instrument/detectors/@IX_detector_array/IX_detector_array.m b/herbert_core/classes/instrument_classes/instrument/detectors/@IX_detector_array/IX_detector_array.m index f4f898058a..2feeb09d4c 100644 --- a/herbert_core/classes/instrument_classes/instrument/detectors/@IX_detector_array/IX_detector_array.m +++ b/herbert_core/classes/instrument_classes/instrument/detectors/@IX_detector_array/IX_detector_array.m @@ -1,4 +1,4 @@ -classdef IX_detector_array < serializable +classdef IX_detector_array < hashable % Full description of a set of detector banks. Each bank is made up of % an array of detectors of a single type e.g. one can contain an array % of 3He tubes (an object of class IX_det_He3tube), another an array of @@ -12,7 +12,7 @@ % across all of the detector banks, not just within one detector % bank (which is all that an instance of IX_detector_bank will % ensure). - % (2) Methods such as calculation of detector efficieny will operate + % (2) Methods such as calculation of detector efficiency will operate % on the entire IX_detector_array, calling the correct functions % for each of the different detector types in the different % banks. @@ -23,14 +23,14 @@ % single detector bank of heterogeneous detector types. For example, get % methods of IX_detector_bank which are generic for all detector types, such % as x2 (sample-detector distance) and phi and azim (scattering angles), - % return the values for all detectors in the array of detectgor banks. + % return the values for all detectors in the array of detector banks. % Similarly, the set methods for these properties apply across all of the % detectors. This is useful, for example, when setting the distances and % scattering angles after a recalibration. % % To get or set properties that are specific to a particular detector type, % you need to get a particular detector bank, and get or set its properties - % using the approperiate getter and setter methods. For example, it has no + % using the appropriate getter and setter methods. For example, it has no % meaning to ask for the 3He pressure for an IX_detector_array if it % contains banks of scintillator detectors. Once you have changed the % properties of a particular detector bank, you can then set the detector diff --git a/herbert_core/classes/instrument_classes/instrument/detectors/@IX_detector_bank/IX_detector_bank.m b/herbert_core/classes/instrument_classes/instrument/detectors/@IX_detector_bank/IX_detector_bank.m index 001575df2a..cae1e1813e 100644 --- a/herbert_core/classes/instrument_classes/instrument/detectors/@IX_detector_bank/IX_detector_bank.m +++ b/herbert_core/classes/instrument_classes/instrument/detectors/@IX_detector_bank/IX_detector_bank.m @@ -1,8 +1,8 @@ -classdef IX_detector_bank < serializable +classdef IX_detector_bank < hashable % IX_detector_bank Defines a detector bank for detectors of one type % The object contains detector positional information and the detector % information for a detector bank of a single detector type (for example an - % array of 3He tubes, or an array of slab deteectors). + % array of 3He tubes, or an array of slab detectors). properties (Access=private) % Detector identifiers, integers greater than 0 (column vector) diff --git a/herbert_core/classes/instrument_classes/instrument/instruments/@IX_inst/IX_inst.m b/herbert_core/classes/instrument_classes/instrument/instruments/@IX_inst/IX_inst.m index 70c66a248e..5bbc18e435 100644 --- a/herbert_core/classes/instrument_classes/instrument/instruments/@IX_inst/IX_inst.m +++ b/herbert_core/classes/instrument_classes/instrument/instruments/@IX_inst/IX_inst.m @@ -1,4 +1,4 @@ -classdef IX_inst < serializable +classdef IX_inst < hashable % Defines the base instrument class containing properties common to % all instruments. % @@ -106,6 +106,7 @@ 'The source name must be a character string') end obj.name_ = char(val); + obj = obj.clear_hash(); end function obj=set.source(obj,val) @@ -118,6 +119,7 @@ else error('The source name must be a character string or an IX_source object') end + obj = obj.clear_hash(); end function obj = set.valid_from(obj,val) if ~isa(val,'datetime') @@ -125,6 +127,7 @@ end obj.valid_from_ = val; obj.validity_date_set_(1) = true; + obj = obj.clear_hash(); end function obj = set.valid_to(obj,val) if ~isa(val,'datetime') @@ -132,6 +135,7 @@ end obj.valid_to_ = val; obj.validity_date_set_(2) = true; + obj = obj.clear_hash(); end %------------------------------------------------------------------ function obj = set_mod_pulse(obj,pulse_model,pm_par) @@ -143,6 +147,7 @@ mod = get_moderator(obj); mod = mod.set_mod_pulse(pulse_model,pm_par); obj = obj.set_moderator(mod); + obj = obj.clear_hash(); end %------------------------------------------------------------------ @@ -213,8 +218,6 @@ end end - - %====================================================================== % Custom loadobj % - to enable custom saving to .mat files and bytestreams diff --git a/herbert_core/classes/instrument_classes/instrument/instruments/@IX_inst_DGdisk/IX_inst_DGdisk.m b/herbert_core/classes/instrument_classes/instrument/instruments/@IX_inst_DGdisk/IX_inst_DGdisk.m index 5917bb69eb..c6c6549807 100644 --- a/herbert_core/classes/instrument_classes/instrument/instruments/@IX_inst_DGdisk/IX_inst_DGdisk.m +++ b/herbert_core/classes/instrument_classes/instrument/instruments/@IX_inst_DGdisk/IX_inst_DGdisk.m @@ -7,7 +7,7 @@ mandatory_mod_fields_ = false(1,3); horiz_div_ = IX_divergence_profile vert_div_ = IX_divergence_profile - % divergency component fields set indicators for object to be valid + % divergence component fields set indicators for object to be valid mandatory_div_fields_ = false(1,2); end @@ -235,6 +235,7 @@ mcm = obj.mod_shape_mono; mcm.do_check_combo_arg = true; obj.mod_shape_mono_ = mcm.check_combo_arg(); + obj = obj.clear_hash(); end end %====================================================================== diff --git a/herbert_core/classes/instrument_classes/instrument/instruments/@IX_inst_DGfermi/IX_inst_DGfermi.m b/herbert_core/classes/instrument_classes/instrument/instruments/@IX_inst_DGfermi/IX_inst_DGfermi.m index ab964640fc..8a9fd4586a 100644 --- a/herbert_core/classes/instrument_classes/instrument/instruments/@IX_inst_DGfermi/IX_inst_DGfermi.m +++ b/herbert_core/classes/instrument_classes/instrument/instruments/@IX_inst_DGfermi/IX_inst_DGfermi.m @@ -70,6 +70,7 @@ function obj=set.energy(obj,val) obj.moderator_.energy = val; obj.fermi_chopper_.energy = val; + obj = obj.clear_hash(); end %------------------------------------------------------------------ @@ -174,6 +175,7 @@ 'missing properties are: %s'],... disp2str(mand_fields ),disp2str(mand_fields (~obj.mandatory_inst_fields_))) end + obj = obj.clear_hash(); end end