diff --git a/_test/test_gen_sqw_workflow/nxspe_files/LET105694_3.7meV_1to1.nxspe b/_test/test_gen_sqw_workflow/nxspe_files/LET105694_3.7meV_1to1.nxspe new file mode 100644 index 0000000000..ac8c2a3086 Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files/LET105694_3.7meV_1to1.nxspe differ diff --git a/_test/test_gen_sqw_workflow/nxspe_files/MAP45862_250meV_1to1.nxspe b/_test/test_gen_sqw_workflow/nxspe_files/MAP45862_250meV_1to1.nxspe new file mode 100644 index 0000000000..5a8696fd2b Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files/MAP45862_250meV_1to1.nxspe differ diff --git a/_test/test_gen_sqw_workflow/nxspe_files/MAP45863_250meV_1to1.nxspe b/_test/test_gen_sqw_workflow/nxspe_files/MAP45863_250meV_1to1.nxspe new file mode 100644 index 0000000000..5d01427938 Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files/MAP45863_250meV_1to1.nxspe differ diff --git a/_test/test_gen_sqw_workflow/nxspe_files/MAP48017_50meV_1to1.nxspe b/_test/test_gen_sqw_workflow/nxspe_files/MAP48017_50meV_1to1.nxspe new file mode 100644 index 0000000000..f9b4985726 Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files/MAP48017_50meV_1to1.nxspe differ diff --git a/_test/test_gen_sqw_workflow/nxspe_files/MAP48675_100meV_1to1.nxspe b/_test/test_gen_sqw_workflow/nxspe_files/MAP48675_100meV_1to1.nxspe new file mode 100644 index 0000000000..d1180b7744 Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files/MAP48675_100meV_1to1.nxspe differ diff --git a/_test/test_gen_sqw_workflow/nxspe_files/MER62983_13.2meV_1to1.nxspe b/_test/test_gen_sqw_workflow/nxspe_files/MER62983_13.2meV_1to1.nxspe new file mode 100644 index 0000000000..b2247de459 Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files/MER62983_13.2meV_1to1.nxspe differ diff --git a/_test/test_gen_sqw_workflow/nxspe_files/MER62983_24.5meV_1to1.nxspe b/_test/test_gen_sqw_workflow/nxspe_files/MER62983_24.5meV_1to1.nxspe new file mode 100644 index 0000000000..eef78aadb4 Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files/MER62983_24.5meV_1to1.nxspe differ diff --git a/_test/test_gen_sqw_workflow/nxspe_files/MER62983_59.9meV_1to1.nxspe b/_test/test_gen_sqw_workflow/nxspe_files/MER62983_59.9meV_1to1.nxspe new file mode 100644 index 0000000000..3cdfc1b329 Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files/MER62983_59.9meV_1to1.nxspe differ diff --git a/_test/test_gen_sqw_workflow/nxspe_files/MER62984_13.2meV_1to1.nxspe b/_test/test_gen_sqw_workflow/nxspe_files/MER62984_13.2meV_1to1.nxspe new file mode 100644 index 0000000000..6ca9e461fa Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files/MER62984_13.2meV_1to1.nxspe differ diff --git a/_test/test_gen_sqw_workflow/nxspe_files/MER62984_24.5meV_1to1.nxspe b/_test/test_gen_sqw_workflow/nxspe_files/MER62984_24.5meV_1to1.nxspe new file mode 100644 index 0000000000..e5f5cb4dda Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files/MER62984_24.5meV_1to1.nxspe differ diff --git a/_test/test_gen_sqw_workflow/nxspe_files/MER62984_59.9meV_1to1.nxspe b/_test/test_gen_sqw_workflow/nxspe_files/MER62984_59.9meV_1to1.nxspe new file mode 100644 index 0000000000..4a2af56962 Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files/MER62984_59.9meV_1to1.nxspe differ diff --git a/_test/test_gen_sqw_workflow/nxspe_files/MER66671_11.2meV_1to1.nxspe b/_test/test_gen_sqw_workflow/nxspe_files/MER66671_11.2meV_1to1.nxspe new file mode 100644 index 0000000000..89ce0273c7 Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files/MER66671_11.2meV_1to1.nxspe differ diff --git a/_test/test_gen_sqw_workflow/nxspe_files/placeholder.txt b/_test/test_gen_sqw_workflow/nxspe_files/placeholder.txt new file mode 100644 index 0000000000..8eb3d7de3f --- /dev/null +++ b/_test/test_gen_sqw_workflow/nxspe_files/placeholder.txt @@ -0,0 +1 @@ +Holding this folder open for github modifications diff --git a/_test/test_gen_sqw_workflow/nxspe_files_powder/LET105694_3.7meV_powder.nxspe b/_test/test_gen_sqw_workflow/nxspe_files_powder/LET105694_3.7meV_powder.nxspe new file mode 100644 index 0000000000..dee0ae3172 Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files_powder/LET105694_3.7meV_powder.nxspe differ diff --git a/_test/test_gen_sqw_workflow/nxspe_files_powder/MAP48017_50meV_powder.nxspe b/_test/test_gen_sqw_workflow/nxspe_files_powder/MAP48017_50meV_powder.nxspe new file mode 100644 index 0000000000..d14dbb7eaf Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files_powder/MAP48017_50meV_powder.nxspe differ diff --git a/_test/test_gen_sqw_workflow/nxspe_files_powder/MAP48675_100meV_powder.nxspe b/_test/test_gen_sqw_workflow/nxspe_files_powder/MAP48675_100meV_powder.nxspe new file mode 100644 index 0000000000..980be74019 Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files_powder/MAP48675_100meV_powder.nxspe differ diff --git a/_test/test_gen_sqw_workflow/nxspe_files_powder/MAR29858_180meV_powder.nxspe b/_test/test_gen_sqw_workflow/nxspe_files_powder/MAR29858_180meV_powder.nxspe new file mode 100644 index 0000000000..d3c1c696c6 Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files_powder/MAR29858_180meV_powder.nxspe differ diff --git a/_test/test_gen_sqw_workflow/nxspe_files_powder/MER62194_22.8meV_powder.nxspe b/_test/test_gen_sqw_workflow/nxspe_files_powder/MER62194_22.8meV_powder.nxspe new file mode 100644 index 0000000000..60e1b9694b Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files_powder/MER62194_22.8meV_powder.nxspe differ diff --git a/_test/test_gen_sqw_workflow/nxspe_files_powder/MER62194_9.82meV_powder.nxspe b/_test/test_gen_sqw_workflow/nxspe_files_powder/MER62194_9.82meV_powder.nxspe new file mode 100644 index 0000000000..a03fda9079 Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files_powder/MER62194_9.82meV_powder.nxspe differ diff --git a/_test/test_gen_sqw_workflow/nxspe_files_powder/MER62194_99.5meV_powder.nxspe b/_test/test_gen_sqw_workflow/nxspe_files_powder/MER62194_99.5meV_powder.nxspe new file mode 100644 index 0000000000..e528390f48 Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files_powder/MER62194_99.5meV_powder.nxspe differ diff --git a/_test/test_gen_sqw_workflow/nxspe_files_powder/MER66671_11.2meV_powder.nxspe b/_test/test_gen_sqw_workflow/nxspe_files_powder/MER66671_11.2meV_powder.nxspe new file mode 100644 index 0000000000..d3f26a4b1b Binary files /dev/null and b/_test/test_gen_sqw_workflow/nxspe_files_powder/MER66671_11.2meV_powder.nxspe differ diff --git a/_test/test_gen_sqw_workflow/shrink_nxspe.py b/_test/test_gen_sqw_workflow/shrink_nxspe.py new file mode 100644 index 0000000000..ea03bc06e7 --- /dev/null +++ b/_test/test_gen_sqw_workflow/shrink_nxspe.py @@ -0,0 +1,126 @@ +# Script to reduce the number of energy bins in a nxspe file so its +# size is small enough to be uploaded to github as test data + +# this script has not been set up to run from the command line - input +# arguments are not available. Instead +# go down to the os.chdir call below to set the directory to work in, and +# set "infile" to the name of the file you wish to shrink in size *without* +# the nxspe extension. +# A new file will be produced with "_OUT" added after "infile". +# Input and output files have been compared using h5dump -H to get a data +# summary + +import h5py +import os + +# the input and output files are named here so they can be seen inside def listgrp +nx = [] # the original h5py File object when it is set +nx2 = [] # this is the revised file with the reduced energy bins + +def listgrp(name,obj): + + print(f"{name=}") + + # dedicated block for the 3 items with energy bins + if name=='ws_out/data/energy': + print("energy") + short = obj[0:10] + nx2.create_dataset(name, data=short) + nx2ds = nx2[name] + keys = obj.attrs.keys() + for k in keys: + val = obj.attrs.__getitem__(k) + nx2ds.attrs.__setitem__(k,val) + return + elif name == 'ws_out/data/data': + short = obj[:, 0:9] + print("data") + nx2.create_dataset(name, data=short) + nx2ds = nx2[name] + keys = obj.attrs.keys() + for k in keys: + val = obj.attrs.__getitem__(k) + nx2ds.attrs.__setitem__(k,val) + return + elif name=='ws_out/data/error': + short = obj[:,0:9] + print("error") + nx2.create_dataset(name, data=short) + nx2ds = nx2[name] + keys = obj.attrs.keys() + for k in keys: + val = obj.attrs.__getitem__(k) + nx2ds.attrs.__setitem__(k,val) + return + + # for other items, process generically as copies + # distinguishing between groups and datasets + try: + + groupname = name + + #item is dataset, extract the groupname from the dataset name and mark as not group + if isinstance(obj, h5py.Dataset): + groupname = groupname.rsplit('/',1)[0] + isgroup = False + #item is group, just accept what is given + else: + isgroup = True + + #get ouot the last item in name and create an opportunity for breaking at fixed_energy + leaf = name.rsplit('/',1) + if len(leaf)==2 and leaf[1]=='fixed_energy': + print('') + + #item is dataset, ensure the group is created in nx2 and copy the dataset from nx to nx2 + if isinstance(obj, h5py.Dataset): + id = nx2.require_group(groupname) + nx.copy(obj.name, id) + # item is group and there are no datasets in it, ensure the parent group is present nand copy the group + else: + if name=='ws_out/sample': + print('') + gid = nx2.require_group(groupname) + + keys = obj.attrs.keys() + for k in keys: + val = obj.attrs.__getitem__(k) + gid.attrs.__setitem__(k,val) + + + + #for groups, copy the attributes if need be. + if isgroup: + pass + + except Exception as err: + print(f"failed A {name}") + +# end def listgrp + +def listname(name): + print(name) + + +# Press the green button in the gutter to run the script. +if __name__ == '__main__': + + wd = os.getcwd() + print('pwd=',wd,'\n\n') + os.chdir('C:\\Users\\nvl96446\STFC\PACE\\nxspe\merlin') + + + infile = 'MER62984_59.9meV_1to1' + nx = h5py.File('original/'+infile+'.nxspe','r') + nx2 = h5py.File(infile+'_OUT.nxspe','w') + + + # the listgrp copying does not do the top level attributes, so it is done explicitly here + nxak = nx.attrs.keys() + for i in nxak: + nx2.attrs.__setitem__(i, nx.attrs.__getitem__(i)) + + nx.visititems(listgrp) + + + nx.close() diff --git a/_test/test_gen_sqw_workflow/test_gen_sqw_accumulate_sqw_tests_nxspe.m b/_test/test_gen_sqw_workflow/test_gen_sqw_accumulate_sqw_tests_nxspe.m new file mode 100644 index 0000000000..545b7261b5 --- /dev/null +++ b/_test/test_gen_sqw_workflow/test_gen_sqw_accumulate_sqw_tests_nxspe.m @@ -0,0 +1,226 @@ +classdef test_gen_sqw_accumulate_sqw_tests_nxspe < TestCaseWithSave + % Series of tests of gen_sqw and associated functions + % generated using multiple Matlab workers. + % + % Optionally writes results to output file to compare with previously + % saved sample test results + %--------------------------------------------------------------------- + % Usage: + % + %1) Normal usage: + % Run all unit tests and compare their results with previously saved + % results stored in test_gen_sqw_accumulate_sqw_output.mat file + % located in the same folder as this function: + % + %>>runtests test_gen_sqw_accumulate_sqw_sep_session + %--------------------------------------------------------------------- + %2) Run particular test case from the suite: + % + %>>tc = test_gen_sqw_accumulate_sqw_sep_session(); + %>>tc.test_[particular_test_name] e.g.: + %>>tc.test_accumulate_sqw14(); + %or + %>>tc.test_gen_sqw(); + %--------------------------------------------------------------------- + %3) Generate test file to store test results to compare with them later + % (it stores test results into tmp folder.) + % + %>>tc=test_gen_sqw_accumulate_sqw_sep_session('save'); + %>>tc.save(): + properties + % properties to use as input for data + test_data_path; + test_functions_path; + par_file; + nfiles_max=6; + + pars; + scale; + + proj; + gen_sqw_par={}; + % files; + spe_file={[]}; + + instrum + sample + % + % the field stores initial configuration, was in place when test + % was started to run + initial_config; + % + % the property describes common name of the test files allowing to + % distinguish these files from the files, generated by other type + % of test + test_pref = 'nomex'; + + working_dir + + nxspedir + nxspedir121 + nxspedirpwd + nxspefiles121 + nxspefilespwd + nxspefile + + end + + methods(Static) + function new_names = rename_file_list(input_list,new_ext) + % change extension for list of files + if ~iscell(input_list) + input_list = {input_list}; + end + new_names = cell(1,numel(input_list)); + for i=1:numel(input_list) + fls = input_list{i}; + [fpath,fn,~] = fileparts(fls); + flt = fullfile(fpath,[fn,new_ext]); + new_names{i} = flt; + if is_file(fls) + movefile(fls,flt,'f'); + end + end + end + end + + methods + function obj=test_gen_sqw_accumulate_sqw_tests_nxspe(name) + obj.nxspedir = 'C:\Users\nvl96446\STFC\PACE\H-240610\Horace\_test\test_gen_sqw_workflow\'; + obj.nxspedir121 = [obj.nxspedir 'nxspe_files']; %maps'; + obj.nxspedirpwd = [obj.nxspedir 'nxspe_files_powder']; %maps'; + %obj.nxspefile = [obj.nxspedir '\MER62983_13.2meV_1to1.nxspe']; %MAP45862_250meV_1to1.nxspe']; + obj.nxspefilespwd = {... + [obj.nxspedirpwd '\MER62194_22.8meV_powder.nxspe'], ... + [obj.nxspedirpwd '\MER62194_9.82meV_powder.nxspe'], ... + [obj.nxspedirpwd '\MER62194_99.5meV_powder.nxspe'], ... + [obj.nxspedirpwd '\MER66671_11.2meV_powder.nxspe'], ... + [obj.nxspedirpwd '\LET105694_3.7meV_powder.nxspe'], ... + [obj.nxspedirpwd '\MAP48017_50meV_powder.nxspe'] , ... + [obj.nxspedirpwd '\MAP48675_100meV_powder.nxspe'] , ... + [obj.nxspedirpwd '\MAR29858_180meV_powder.nxspe'] ... + }; + obj.nxspefiles121 = { ... + [obj.nxspedir121 '\MER66671_11.2meV_1to1.nxspe'], ... [obj.nxspedir121 '\MER66671_11.2meV_1to1.nxspe'] ... + [obj.nxspedir121 '\LET105694_3.7meV_1to1.nxspe'], ... + [obj.nxspedir121 '\MAP45862_250meV_1to1.nxspe'], ... + [obj.nxspedir121 '\MAP45863_250meV_1to1.nxspe'], ... + [obj.nxspedir121 '\MAP48017_50meV_1to1.nxspe'], ... + [obj.nxspedir121 '\MAP48675_100meV_1to1.nxspe'], ... + [obj.nxspedir121 '\MER62983_24.5meV_1to1.nxspe'], ... + [obj.nxspedir121 '\MER62983_59.9meV_1to1.nxspe'], ... + [obj.nxspedir121 '\MER62984_13.2meV_1to1.nxspe'], ... + [obj.nxspedir121 '\MER62984_24.5meV_1to1.nxspe'], ... + [obj.nxspedir121 '\MER62984_59.9meV_1to1.nxspe'] ... + }; + if ~exist(obj.nxspefile, 'file') + disp([obj.nxspefile ' not there']); + else + disp('it''s there'); + end + + obj.nfiles_max=1; + en=cell(1,obj.nfiles_max); + efix=zeros(1,obj.nfiles_max); + psi=zeros(1,obj.nfiles_max); + omega=zeros(1,obj.nfiles_max); + dpsi=zeros(1,obj.nfiles_max); + gl=zeros(1,obj.nfiles_max); + gs=zeros(1,obj.nfiles_max); + for i=1:obj.nfiles_max + efix(i)=230+0.5*i; % different ei for each file + en{i}=0.05*efix(i):0.2+i/50:0.95*efix(i); % different energy bins for each file + psi(i)=90-i+1; + omega(i)=10+i/2; + dpsi(i)=0.1+i/10; + gl(i)=3-i/6; + gs(i)=2.4+i/7; + end + psi=90:-1:90-obj.nfiles_max+1; + + emode=1; + alatt=[4.4,5.5,6.6]; + angdeg=[100,105,110]; + u=[1.02,0.99,0.02]; + v=[0.025,-0.01,1.04]; + + obj.gen_sqw_par={en,efix, emode, alatt, angdeg, u, v, psi, omega, dpsi, gl, gs}; + end + + function test_dummy(obj,varargin) + end + + function test_gen_nxspe(obj,varargin) + select = 1:1; + en =obj.gen_sqw_par{1}(select); + efix=obj.gen_sqw_par{2}(select); + emode=obj.gen_sqw_par{3}; + alatt=obj.gen_sqw_par{4}; + angdeg=obj.gen_sqw_par{5}; + u=obj.gen_sqw_par{6}; + v=obj.gen_sqw_par{7}; + psi=obj.gen_sqw_par{8}(select); + omega=obj.gen_sqw_par{9}(select); + dpsi=obj.gen_sqw_par{10}(select); + gl=obj.gen_sqw_par{11}(select); + gs=obj.gen_sqw_par{12}(select); + + % test the first powder nxspe in gen_sqw; it will fail + % because its azimuthal width range exceeds the detector height + % limit + % Remove this when the rest off the tests are working + %{ + obj.nxspefile = obj.nxspefilespwd(1); + disp(['??????? ' obj.nxspefile]); + [tmp_files,grid2,pix_data_range2]=gen_sqw (obj.nxspefile, ... + '', 'outfile', efix, emode, alatt, angdeg,... + u, v, psi, omega, ... + dpsi, gl, gs); + %} + + % test all 1to1 nxspe files to ensure they do not fail against + % the detector height formula (or indeed for ny other reason) + for ii=1:size(obj.nxspefiles121,2) + obj.nxspefile = obj.nxspefiles121{ii}; + disp(' '); + disp(['oooooo ' obj.nxspefile]) + [tmp_files,grid2,pix_data_range2]=gen_sqw (obj.nxspefile, ... + '', 'outfile', efix, emode, alatt, angdeg,... + u, v, psi, omega, ... + dpsi, gl, gs); + disp(' '); + end + + % test all powder nxspe files, all of which should fail due to + % being detected as powder and thus likely to cause detector + % height problems + for ii=1:size(obj.nxspefilespwd,2) + obj.nxspefile = obj.nxspefilespwd{ii}; + disp(' '); + disp(['xxxxxx ' obj.nxspefile]) + try + + [tmp_files,grid2,pix_data_range2]=gen_sqw (obj.nxspefile, ... + '', 'outfile', efix, emode, alatt, angdeg,... + u, v, psi, omega, ... + dpsi, gl, gs); + text = ['FAILURE: Powder nxspe was processed; expected ' ... + 'failure due to azimuthal width data did not occur.'] + assertFalse(true, text); + catch ME + text = ['FAILURE: Powder nxspe was not processed: ' ME.message]; + %assertFalse(true, text); + disp(['FAILURE:' ME.message]); + disp(''); + disp(''); + end + end + end + + + + + + % + end +end diff --git a/herbert_core/classes/data_loaders/@loader_nxspe/loader_nxspe.m b/herbert_core/classes/data_loaders/@loader_nxspe/loader_nxspe.m index de1d15cfbd..d2c18d572a 100644 --- a/herbert_core/classes/data_loaders/@loader_nxspe/loader_nxspe.m +++ b/herbert_core/classes/data_loaders/@loader_nxspe/loader_nxspe.m @@ -138,7 +138,9 @@ obj.nexus_instrument_ = obj.read_instrument_info_(); catch ME if strcmp(ME.identifier, 'HERBERT:loader_nxspe:missing_instrument_fields') - warning(ME.identifier,'%s', ME.message); + warning(ME.identifier, '%s', ME.message); + else + rethrow(ME); end % Ignore all other errors; instrument info not guaranteed to % be in all nxspe files; its absence is not an error. @@ -301,6 +303,7 @@ end function moderator = read_inst_moderator_(obj, ds) % Construct an IX_moderator from a NeXus data structure + moderator_described = true; if isfield(ds.moderator, 'pulse_shape') pulse_model = 'table'; parameters = {ds.moderator.pulse_shape.Time.value ... @@ -309,12 +312,19 @@ pulse_model = ds.moderator.empirical_pulse_shape.type.value; parameters = ds.moderator.empirical_pulse_shape.data.value; else - error('HERBERT:loader_nxspe:invalid_moderator', ... - 'moderator model in instrument info not understandable by Horace.'); + moderator_described = false; + warning('HERBERT:loader_nxspe:invalid_moderator', ... + 'moderator model in instrument info not understandable by Horace.'); + end + if moderator_described + moderator = IX_moderator(abs(ds.moderator.transforms.MOD_T_AXIS.value), ... + ds.moderator.transforms.MOD_R_AXIS.value, ... + pulse_model, parameters); + else + warning('HERBERT:loader_nxspe:invalid_moderator', ... + 'replacing moderator with predefined working one'); + moderator = IX_inst.fill_missing_moderator(ds); end - moderator = IX_moderator(abs(ds.moderator.transforms.MOD_T_AXIS.value), ... - ds.moderator.transforms.MOD_R_AXIS.value, ... - pulse_model, parameters); end function instrument = read_fermi_inst_(obj, ds, src, mod) % Construct an IX_inst_DGfermi from a NeXus data structure diff --git a/herbert_core/classes/data_loaders/@nxspepar_loader/private/load_nxspe_par_.m b/herbert_core/classes/data_loaders/@nxspepar_loader/private/load_nxspe_par_.m index 35394511c8..7de874d83d 100644 --- a/herbert_core/classes/data_loaders/@nxspepar_loader/private/load_nxspe_par_.m +++ b/herbert_core/classes/data_loaders/@nxspepar_loader/private/load_nxspe_par_.m @@ -57,10 +57,26 @@ par(6,:)= 1:n_det; d_pol = h5read(file_name,[root_folder,'/data/polar_width']); d_azim = h5read(file_name,[root_folder,'/data/azimuthal_width']); + + % reject powder inputs that are not 1to1 from number of azimuthal width + % values + AZIMUTHAL_WIDTH_DETECTOR_NUMBER_LIMIT = 3000; + if size(d_azim) < AZIMUTHAL_WIDTH_DETECTOR_NUMBER_LIMIT + error('HERBERT:load_nxspe_par_:invalid_input', ... + 'number of azimuthal width values>%d shows nxspe input is not 1to1, so invalid', ... + AZIMUTHAL_WIDTH_DETECTOR_NUMBER_LIMIT); + end - - par(4,:) = 2*dist.*tand(0.5*d_pol); % get detector's height according to Toby's definition - par(5,:) = 2*dist.*sind(polar).*tand(0.5*d_azim); % get detector's width according to Toby's definition + % reject powder inputs that are not 1to1 from max azimuthal width + AZIMUTHAL_WIDTH_1TO1_LIMIT = 180; % degrees + if max(d_azim) > AZIMUTHAL_WIDTH_1TO1_LIMIT + error('HERBERT:load_nxspe_par_:invalid_input', ... + 'azimuthal width>%d shows nxspe input is not 1to1, so invalid', ... + AZIMUTHAL_WIDTH_1TO1_LIMIT); + end + + par(4,:) = 2*dist.*tand(0.5*d_pol); % get detector's width according to Toby's definition + par(5,:) = 2*dist.*sind(polar).*tand(0.5*d_azim); % get detector's height according to Toby's definition if get(hor_config,'log_level')>1 disp(['LOADER_NXSPE:load_par::loaded ' num2str(n_det) ' detector(s)']); diff --git a/herbert_core/classes/instrument_classes/instrument/@IX_fermi_chopper/private/get_pulse_props_.m b/herbert_core/classes/instrument_classes/instrument/@IX_fermi_chopper/private/get_pulse_props_.m index d83641b193..76ac01f1e1 100644 --- a/herbert_core/classes/instrument_classes/instrument/@IX_fermi_chopper/private/get_pulse_props_.m +++ b/herbert_core/classes/instrument_classes/instrument/@IX_fermi_chopper/private/get_pulse_props_.m @@ -37,10 +37,14 @@ else % One or more chopper parameters have been set vi = 1e6 * sqrt(ei) / obj.c_e_to_t_; % incident velocity (m/s) - - omega=2*pi*obj.frequency_; + + % attempt to fix problem with obj.frequency coming in from nxspe files populated + % with instrument information as int32. + % Cast to double for omega effective and makes gam for pk_fwhh==0 to be Inf not max(int32). + % Ordering change for pk_fwhh left in although it doesn't persuade the calc to widen to double. + omega=2*pi*double(obj.frequency_); s=2*omega*obj.curvature_; - pk_fwhh=obj.slit_width_/(2*obj.radius_*omega); + pk_fwhh=obj.slit_width_/(2*omega*obj.radius_); if phase gam=(2*obj.radius_/pk_fwhh)*abs(1/s-1./vi); 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 3caaed7929..9bdfd480eb 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 @@ -37,6 +37,27 @@ function rv = xxx(obj) rv = isa(obj,'IX_inst'); end + + function mod = fill_missing_moderator(ds) + % temporary fix to moderator input while there is an upstream defect in moderator + % population. This code fills in "a" valid moderator. This is not intended to be used, + % rather it enables gen_sqw to reach the point where the user can populate the moderator + % manually to fix the problem. + % Currently only a default MAPS moderator is coded, other instrument defaults will be + % added as and when they are found to be needed. + if isfield(ds,'name') + if (strcmp(ds.name.value,'MAPS')) + instr = maps_instrument(300,250,'S'); + mod = instr.moderator; + else + error('HORACE:IX_inst:invalid_argument', ... + 'instruments other than MAPS not yet included'); + end + else + error('HORACE:IX_inst:invalid_argument', ... + 'name not given for instrument'); + end + end end methods %------------------------------------------------------------------ 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..f83715096a 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 @@ -68,6 +68,8 @@ end function obj=set.energy(obj,val) + % Temporary fix while some variables are coming in from Matlab populated as int32 + val = double(val); obj.moderator_.energy = val; obj.fermi_chopper_.energy = val; end diff --git a/herbert_core/utilities/hdf_nexus/read_nexus_groups_recursive.m b/herbert_core/utilities/hdf_nexus/read_nexus_groups_recursive.m index adffa20db8..3a368988ff 100644 --- a/herbert_core/utilities/hdf_nexus/read_nexus_groups_recursive.m +++ b/herbert_core/utilities/hdf_nexus/read_nexus_groups_recursive.m @@ -18,7 +18,6 @@ elseif exist('nexus_path', 'var') error('HERBERT:hdf_nexus:read_nexus_groups_recursive', 'filename provided as struct, but nexus_path also provided'); end - dinfo = filename; filename = dinfo.Filename; case {'string', 'char'} @@ -31,7 +30,6 @@ else dinfo = nexus_path; end - otherwise error('HERBERT:hdf_nexus:read_nexus_groups_recursive', ... 'filename (%s) and nexus_path (%s) must be struct, char or string', ... @@ -41,7 +39,24 @@ datastruct = read_nexus_datasets(filename, dinfo); for ii = 1:numel(dinfo.Groups) pathfields = split(dinfo.Groups(ii).Name, '/'); - datastruct.(pathfields{end}) = read_nexus_groups_recursive(filename, dinfo.Groups(ii)); + + % while spurious fields starting 'rep_' are present in nxspe files, ignore them. + % the formation of the datastruct field has been split up to ensure that the 'rep_' + % field does not generate an invalid field error (unclear why this was happening + % but the refactor here fixes it.) + pfe = pathfields(end); + if strncmp(pfe{1},'rep_',4) + isrep = true; + elseif strcmp(pfe{1},'moderator') + isrep = false; + else + isrep = false; + end + if ~isrep + substruct = read_nexus_groups_recursive(filename, dinfo.Groups(ii)); + datastruct.(pfe{1}) = substruct; + + end end end