diff --git a/API/RATMain.m b/API/RATMain.m index b1b67f71c..b75e49515 100644 --- a/API/RATMain.m +++ b/API/RATMain.m @@ -10,40 +10,45 @@ result = makeEmptyResultStruct(problemStruct.numberOfContrasts, length(problemStruct.fitParams), domains); bayesResults = makeEmptyBayesResultsStruct(problemStruct.numberOfContrasts, domains, controls.nChains); -% Decide what we are doing.... -switch controls.procedure - case coderEnums.procedures.Calculate % Just a single reflectivity calculation +if problemStruct.numberOfContrasts > 0 + switch controls.procedure + case coderEnums.procedures.Calculate % Just a single reflectivity calculation + controls.calcSldDuringFit = true; + result = reflectivityCalculation(problemStruct,problemCells,problemLimits,controls); + case coderEnums.procedures.Simplex + if ~strcmpi(controls.display, coderEnums.displayOptions.Off) + triggerEvent(coderEnums.eventTypes.Message, sprintf('\nRunning simplex\n\n')); + end + [problemStruct,result] = runSimplex(problemStruct,problemCells,problemLimits,controls); + case coderEnums.procedures.DE + if ~strcmpi(controls.display, coderEnums.displayOptions.Off) + triggerEvent(coderEnums.eventTypes.Message, sprintf('\nRunning Differential Evolution\n\n')); + end + [problemStruct,result] = runDE(problemStruct,problemCells,problemLimits,controls); + case coderEnums.procedures.NS + if ~strcmpi(controls.display, coderEnums.displayOptions.Off) + triggerEvent(coderEnums.eventTypes.Message, sprintf('\nRunning Nested Sampler\n\n')); + end + [problemStruct,result,bayesResults] = runNestedSampler(problemStruct,problemCells,problemLimits,controls,priors); + case coderEnums.procedures.Dream + if ~strcmpi(controls.display, coderEnums.displayOptions.Off) + triggerEvent(coderEnums.eventTypes.Message, sprintf('\nRunning DREAM\n\n')); + end + [problemStruct,result,bayesResults] = runDREAM(problemStruct,problemCells,problemLimits,controls,priors); + otherwise + error('The procedure "%s" is not supported. The procedure must be one of "%s"', controls.procedure, strjoin(fieldnames(coderEnums.procedures), '", "')); + end + + % Then just do a final calculation to fill in SLD if necessary + % (i.e. if calcSLD is no for fit) + if ~controls.calcSldDuringFit + controls.calcSldDuringFit = true; + controls.procedure = coderEnums.procedures.Calculate; result = reflectivityCalculation(problemStruct,problemCells,problemLimits,controls); - case coderEnums.procedures.Simplex - if ~strcmpi(controls.display, coderEnums.displayOptions.Off) - triggerEvent(coderEnums.eventTypes.Message, sprintf('\nRunning simplex\n\n')); - end - [problemStruct,result] = runSimplex(problemStruct,problemCells,problemLimits,controls); - case coderEnums.procedures.DE - if ~strcmpi(controls.display, coderEnums.displayOptions.Off) - triggerEvent(coderEnums.eventTypes.Message, sprintf('\nRunning Differential Evolution\n\n')); - end - [problemStruct,result] = runDE(problemStruct,problemCells,problemLimits,controls); - case coderEnums.procedures.NS - if ~strcmpi(controls.display, coderEnums.displayOptions.Off) - triggerEvent(coderEnums.eventTypes.Message, sprintf('\nRunning Nested Sampler\n\n')); - end - [problemStruct,result,bayesResults] = runNestedSampler(problemStruct,problemCells,problemLimits,controls,priors); - case coderEnums.procedures.Dream - if ~strcmpi(controls.display, coderEnums.displayOptions.Off) - triggerEvent(coderEnums.eventTypes.Message, sprintf('\nRunning DREAM\n\n')); - end - [problemStruct,result,bayesResults] = runDREAM(problemStruct,problemCells,problemLimits,controls,priors); - otherwise - error('The procedure "%s" is not supported. The procedure must be one of "%s"', controls.procedure, strjoin(fieldnames(coderEnums.procedures), '", "')); -end + end -% Then just do a final calculation to fill in SLD if necessary -% (i.e. if calcSLD is no for fit) -if ~controls.calcSldDuringFit - controls.calcSldDuringFit = true; - controls.procedure = coderEnums.procedures.Calculate; - result = reflectivityCalculation(problemStruct,problemCells,problemLimits,controls); +else + error("RAT cannot proceed without at least one contrast defined in the project") end end diff --git a/API/checkIndices.m b/API/checkIndices.m index 4e41cb468..538b6defb 100644 --- a/API/checkIndices.m +++ b/API/checkIndices.m @@ -1,13 +1,30 @@ -function checkIndices(problemStruct) +function checkIndices(problemStruct, customFiles) % Make sure that the indices provided lie within the bounds of the % corresponding array. numBackgroundParams = length(problemStruct.backgroundParams); + numCustomFiles = length(customFiles); for i = 1:length(problemStruct.contrastBackgroundParams) - index = problemStruct.contrastBackgroundParams(i); - if (index < 1 && index ~= -1) || index > numBackgroundParams - throw(exceptions.indexOutOfRange(sprintf('contrastBackgroundParams(%i) is %i, which is outside the range of backgroundParams', i, index))); + + indices = problemStruct.contrastBackgroundParams{i}; + + if length(indices) > 1 + % The first index is a custom file, the rest are background parameters + index = indices(1); + if index < 1 || index > numCustomFiles + throw(exceptions.indexOutOfRange(sprintf('contrastBackgroundParams{%i}(1) is %i, which is outside the range of customFiles', i, index))); + end + indices = indices(2:end); end + + % All of these indices are background parameters + for j = 1:length(indices) + index = indices(j); + if index < 1 || index > numBackgroundParams + throw(exceptions.indexOutOfRange(sprintf('contrastBackgroundParams{%i}(%i) is %i, which is outside the range of backgroundParams', i, j, index))); + end + end + end numQzshifts = length(problemStruct.qzshifts); diff --git a/API/insertDataBackgroundIntoContrastData.m b/API/insertDataBackgroundIntoContrastData.m new file mode 100644 index 000000000..2f6f6342f --- /dev/null +++ b/API/insertDataBackgroundIntoContrastData.m @@ -0,0 +1,25 @@ +function contrastData = insertDataBackgroundIntoContrastData(contrastData,backgroundData) +% Deal with a Data background. The data and errors in this case are +% inserted into columns 5 and 6 of the relevant datafile. +% +% Currently, we throw an error if the qz column (column 1) of the two +% datafiles are different. Eventually this will be replaced by an +% interpolation to make it more general. + +% Get the arrays from the cells +dataArray = contrastData{:}; +backgroundArray = backgroundData{:}; + +% Check that we have the same q +if ~isequal(dataArray(:,1), backgroundArray(:,1)) + throw(exceptions.invalidValue("q points must be equal for Data and Background Data")); +end + +% Insert background data into columns 5 and 6 of contrast data +dataArray(:,5) = backgroundArray(:,2); +dataArray(:,6) = backgroundArray(:,3); + +% Package as a cell array for output... +contrastData = {dataArray}; + +end diff --git a/API/makeEmptyResultStruct.m b/API/makeEmptyResultStruct.m index 68e8ab917..a367f3e63 100644 --- a/API/makeEmptyResultStruct.m +++ b/API/makeEmptyResultStruct.m @@ -2,8 +2,9 @@ % A function to make an empty container to hold the results of % reflectivity calculations. The struct has the following format: % - % nPar = number of fitted parameters + % nParams = number of fitted parameters % nContrasts = number of contrasts + % nDomains = number of domains - 1 for non-polarised, 2 for domains % % result = % @@ -12,9 +13,10 @@ % reflectivity: [nContrastsx1 cell] % simulation: [nContrastsx1 cell] % shiftedData: [nContrastsx1 cell] - % layerSlds: [nContrastsx1 cell] - % sldProfiles: [nContrastsx1 cell] - % resampledLayers: [nContrastsx1 cell] + % backgrounds: [nContrastsx1 cell] + % layerSlds: [nContrastsxnDomains cell] + % sldProfiles: [nContrastsxnDomains cell] + % resampledLayers: [nContrastsxnDomains cell] % calculationResults: [1x1 struct] % contrastParams: [1x1 struct] % fitParams: [1xnParams double] @@ -36,8 +38,6 @@ % -------------------------------------------------------------------- % (2) result.contrastParams - backgroundParams = zeros(nContrasts,1); - coder.varsize('backgroundParams',[maxArraySize 1],[1 0]); scalefactors = zeros(nContrasts,1); coder.varsize('scalefactors',[maxArraySize 1],[1 0]); bulkIn = zeros(nContrasts,1); @@ -51,8 +51,7 @@ resample = zeros(1, nContrasts); coder.varsize('resample',[1 maxArraySize],[0 1]); - contrastParams = struct('backgroundParams', backgroundParams, ... - 'scalefactors', scalefactors, ... + contrastParams = struct('scalefactors', scalefactors, ... 'bulkIn', bulkIn, ... 'bulkOut', bulkOut, ... 'resolutionParams', resolutionParams, ... @@ -64,27 +63,33 @@ reflectivity = cell(nContrasts,1); refCell = ones(2,2); - coder.varsize('refCell',[10000 2],[1 0]); for i = 1:nContrasts reflectivity{i} = refCell; end + coder.varsize('reflectivity{:}',[10000 2],[1 0]); simulation = cell(nContrasts,1); simCell = ones(2,2); - coder.varsize('simCell',[10000 2],[1 0]); for i = 1:nContrasts simulation{i} = simCell; end + coder.varsize('simulation{:}',[10000 2],[1 0]); shiftedData = cell(nContrasts,1); shiftCell = ones(2,3); - coder.varsize('shiftCell',[10000 3],[1 0]); for i = 1:nContrasts shiftedData{i} = shiftCell; end + coder.varsize('shiftedData{:}',[10000 3],[1 0]); + + backgrounds = cell(nContrasts,1); + backgroundCell = ones(2,3); + for i = 1:nContrasts + backgrounds{i} = backgroundCell; + end + coder.varsize('backgrounds{:}',[10000 3],[1 0]); layerSldCell = ones(2,3); - coder.varsize('layerSldCell',[10000 6],[1 1]); if domains layerSlds = cell(nContrasts,2); for i = 1:nContrasts @@ -97,9 +102,9 @@ layerSlds{i} = layerSldCell; end end + coder.varsize('layerSlds{:}',[10000 6],[1 1]); sldProfileCell = ones(2,2); - coder.varsize('sldProfileCell',[10000 2],[1 0]); if domains sldProfiles = cell(nContrasts,2); for i = 1:nContrasts @@ -108,14 +113,13 @@ end else sldProfiles = cell(nContrasts,1); - for i = 1:nContrasts sldProfiles{i} = sldProfileCell; end - end + end + coder.varsize('sldProfiles{:}',[10000 3],[1 1]); resampledLayersCell = ones(2,3); - coder.varsize('resampledLayersCell',[10000 3],[1 0]); if domains resampledLayers = cell(nContrasts,2); for i = 1:nContrasts @@ -128,20 +132,21 @@ resampledLayers{i} = resampledLayersCell; end end + coder.varsize('resampledLayers{:}',[10000 4],[1 1]); fitParams = zeros(nParams,1); coder.varsize('fitParams',[maxArraySize 1],[1 0]); fitNames = cell(nParams,1); - fitNamesChar = ''; - coder.varsize('fitNamesChar',[1 maxArraySize],[0 1]); for i = 1:nParams - fitNames{i} = fitNamesChar; + fitNames{i} = ''; end + coder.varsize('fitNames{:}',[1 maxArraySize],[0 1]); result = struct('reflectivity', {reflectivity}, ... 'simulation', {simulation}, ... 'shiftedData', {shiftedData}, ... + 'backgrounds', {backgrounds}, ... 'layerSlds', {layerSlds}, ... 'sldProfiles', {sldProfiles}, ... 'resampledLayers', {resampledLayers}, ... diff --git a/API/parseClassToStructs.m b/API/parseClassToStructs.m index faeb5b766..aa1f3195c 100644 --- a/API/parseClassToStructs.m +++ b/API/parseClassToStructs.m @@ -9,9 +9,9 @@ % {1 x nContrasts} array of cells % Each cell is {1 x 2 double}. % -% {2} - inputProblem.data +% {2} - inputProblem.contrastData % {1 x nContrasts} array of cells -% Each cell is {Inf x 3 double} +% Each cell is {Inf x 6 double} % % {3} - inputProblem.dataLimits % {1 x nContrasts} array of cells @@ -93,9 +93,17 @@ %% First parse the class to a structure variable. inputStruct = project.toStruct(); +% Make the contrast data array up to six columns, +% adding columns of zeros if necessary +inputData = cell(1, length(inputStruct.contrastData)); +for i = 1:length(inputStruct.contrastData) + contrastData = inputStruct.contrastData{i}; + inputData{i} = [contrastData zeros(size(contrastData,1), 6-size(contrastData,2))]; +end + %% Pull out all the cell arrays (except priors) into one array problemCells{1} = inputStruct.contrastRepeatSLDs; -problemCells{2} = inputStruct.data; +problemCells{2} = inputData; problemCells{3} = inputStruct.dataLimits; problemCells{4} = inputStruct.simLimits; problemCells{5} = inputStruct.contrastLayers; @@ -185,41 +193,89 @@ %% Deal with backgrounds and resolutions -backgroundActions = zeros(1, length(inputStruct.contrastBackgrounds)); -for i = 1:length(inputStruct.contrastBackgrounds) - if strcmpi(inputStruct.contrastBackgroundActions{i}, actions.Add) - backgroundActions(i) = 1; - else - backgroundActions(i) = 2; - end +% Convert contrastBackgrounds to custom file/parameter indices +numContrastBackgrounds = length(inputStruct.contrastBackgrounds); -end +contrastBackgroundParams = cell(1, numContrastBackgrounds); +contrastBackgroundTypes = cell(1, numContrastBackgrounds); -% Convert contrastBackgrounds to parameter indices -contrastBackgrounds = inputStruct.contrastBackgrounds; -backgroundTypes = inputStruct.backgroundTypes; +for i = 1:numContrastBackgrounds + % Check the type of the background that each contrast is pointing to. + thisBack = inputStruct.contrastBackgrounds(i); % Which background + contrastBackgroundTypes{i} = inputStruct.backgroundTypes{thisBack}; % What type is it? -backgroundParamNames = inputStruct.backgroundParamNames; -contrastBackgroundParams = zeros(1, length(contrastBackgrounds)); + switch contrastBackgroundTypes{i} -for i = 1:length(contrastBackgrounds) - % Check the type of the background that each contrast is pointing to. - % If it is a constant, point to the number of the corresponding - % background param. If it's data, then set it to -1 - thisBack = contrastBackgrounds(i); % Which background - thisType = backgroundTypes{thisBack}; % What type is it? + case allowedTypes.Constant.value + % Background is a backgroundParam, the name of which should + % be in the first column of backgroundValues - if strcmpi(thisType,'data') - % Background is in the datafile. Set contrastBackgroundParams to -1 - contrastBackgroundParams(i) = -1; - else - % Background is a backgroundParam, the name of which should - % be in the first column of backgroundValues - whichBackgroundParamName = inputStruct.backgroundValues{thisBack,1}; - - % Find which backgroundParam this is, and set contrastBackgroundParams to this number - contrastBackgroundParams(i) = find(strcmpi(whichBackgroundParamName,backgroundParamNames)); + % Find which backgroundParam this is, and set contrastBackgroundParams to this number + contrastBackgroundParams{i} = find(strcmpi(inputStruct.backgroundValues{thisBack,1}, inputStruct.backgroundParamNames)); + + case allowedTypes.Data.value + % Background is in a datafile. + % + % We need to find the index of the relevant datafile, and + % append the relevant data as columns 5 and 6 of the contrast + % data. Finally, deal with the optional background offset if + % present, and set this as the (optional) contrastBackgroundParams + % entry. + + % Find corresponding background value + backgroundDatafileName = inputStruct.backgroundValues{thisBack,1}; + backgroundDataOffset = inputStruct.backgroundValues{thisBack,2}; + + % Find the index of this data name in the string array + backgroundDataIndex = find(strcmp(backgroundDatafileName,inputStruct.dataNames)); + + if isempty(backgroundDataIndex) + throw(exceptions.invalidValue(sprintf('Data background %s is not defined in the data table of the project', backgroundDatafileName))); + end + + % We append the background data as columns 5 and 6 of the + % data array of this contrast. + contrastData = problemCells{2}(i); + backgroundData = inputStruct.allData{backgroundDataIndex}; + contrastData = insertDataBackgroundIntoContrastData(contrastData,backgroundData); + problemCells{2}(i) = contrastData; + + % Add the index of the optional data offset to contrastBackgroundParams + offsetIndex = find(strcmpi(backgroundDataOffset,inputStruct.backgroundParamNames)); + if ~isempty(offsetIndex) + contrastBackgroundParams{i} = offsetIndex; + end + + case allowedTypes.Function.value + % Background is a background function + % + % We need the index of the custom file the function is defined + % in, alongside all of the function parameters. + + % Get the corresponding function name + backgroundFuncfileName = inputStruct.backgroundValues{thisBack,1}; + + % Find the index of this function name in the custom file array + backgroundFunctionIndex = find(strcmp(backgroundFuncfileName,inputStruct.fileIdentifiers)); + + if isempty(backgroundFunctionIndex) + throw(exceptions.invalidValue(sprintf('Function background %s is not defined in the custom files table of the project', backgroundFuncfileName))); + end + + contrastBackgroundParams{i}(1) = backgroundFunctionIndex; + + % Now find the indices of any defined background parameters + functionParams = inputStruct.backgroundValues(thisBack,2:end); + numDefined = length(find(~(cellfun(@(x) isequal(x,""),functionParams)))); + for n = 1:numDefined + backgroundParamIndex = find(strcmpi(functionParams{n},inputStruct.backgroundParamNames)); + contrastBackgroundParams{i}(n+1) = backgroundParamIndex; + end + + otherwise + throw(exceptions.inValidOption(sprintf('The background type "%s" is not supported. Backgrounds should be either "constant", "data", or "function"', backgroundType))); + end end @@ -291,13 +347,6 @@ %% Make the problemStruct structure from the remaining inputs -% ************************************************************************* -% NOTE - not using the more complicated background and resolution -% definitions for now - instead use the background names and -% backgroundParam values.... fix this next -% ************************************************************************* - - problemStruct.TF = inputStruct.TF; problemStruct.resample = inputStruct.resample; problemStruct.dataPresent = inputStruct.dataPresent; @@ -306,13 +355,14 @@ problemStruct.geometry = inputStruct.geometry; problemStruct.useImaginary = inputStruct.useImaginary; problemStruct.contrastBackgroundParams = contrastBackgroundParams; -problemStruct.contrastBackgroundActions = backgroundActions; +problemStruct.contrastBackgroundTypes = contrastBackgroundTypes; +problemStruct.contrastBackgroundActions = inputStruct.contrastBackgroundActions; problemStruct.contrastQzshifts = inputStruct.contrastQzshifts; problemStruct.contrastScalefactors = inputStruct.contrastScalefactors; problemStruct.contrastBulkIns = inputStruct.contrastBulkIns; problemStruct.contrastBulkOuts = inputStruct.contrastBulkOuts; problemStruct.contrastResolutionParams = contrastResolutionParams; -problemStruct.backgroundParams = inputStruct.backgroundParamValues; %inputStruct.backgrounds; % **** note backPar workaround (todo) **** +problemStruct.backgroundParams = inputStruct.backgroundParamValues; problemStruct.qzshifts = inputStruct.qzshiftValues; problemStruct.scalefactors = inputStruct.scalefactorValues; problemStruct.bulkIn = inputStruct.bulkInValues; @@ -346,7 +396,7 @@ problemStruct.otherLimits = []; % Make sure the indices cannot lie outside of the arrays -checkIndices(problemStruct) +checkIndices(problemStruct, inputStruct.files); %% Now deal with the controls class controls.procedure = inputControls.procedure; diff --git a/API/projectClass/backgroundsClass.m b/API/projectClass/backgroundsClass.m index d85f85d75..1b5a59157 100644 --- a/API/projectClass/backgroundsClass.m +++ b/API/projectClass/backgroundsClass.m @@ -1,17 +1,18 @@ classdef backgroundsClass < handle % Backgrounds are defined in a two stage process. Firstly we define the - % actual fitted parameters. These are held in a 'ParametersClass' + % actual fitted parameters. These are held in a 'Parameters' % table. Then, we group these into the backgrounds themselves using a % multiTypeTable. So, we can then use the background parameters to - % either define background as constant, data or a function. + % either define background as constant, data or a function. % - % For constant only one parameter is supplied to multi type table. + % For constant only one background parameter is supplied to multi type table. % - % For data only the itself is supplied as a cell. + % For data an entry in the data table and an optional offset is + % required % - % For function, the function name is supplied, along with up to three - % parameters (from the parameters table) which are then supplied to the - % function to calculate the background. + % For function, the function name is supplied, along with up to five + % parameters (from the background parameters table) which are then + % passed to the function to calculate the background. % % In each case, the background can either be added to the simulation or % subtracted from the data. @@ -22,24 +23,26 @@ end properties(Access = private, Constant, Hidden) + maxValues = struct('constant', 0, 'data', 1, 'function', 5) invalidTypeMessage = sprintf('Allowed type must be a allowedTypes enum or one of the following strings (%s)', ... strjoin(allowedTypes.values(), ', ')) end methods - function obj = backgroundsClass(parameters, startBackground) + function obj = backgroundsClass(parameters, startBackground, allowedNames) % Creates a background object. The arguments should be - % an instance of the parameter class with the background parameters - % and a cell array of backgrounds + % an instance of the parameter class with the background + % parameters, a cell array of backgrounds and the struct of + % allowed data and function names. % % params = parametersClass({'Background Param 1', 1e-7, 1e-6, 1e-5, false, 'uniform', 0, Inf}); - % % background = backgroundClass(params, {'Background 1', 'constant', 'Background Param 1'}); + % background = backgroundClass(params, {'Background 1', 'constant', 'Background Param 1'}, allowedNames); obj.backgroundParams = parameters; % Make a multiType table to define the actual backgrounds obj.backgrounds = multiTypeTable(); obj.backgrounds.typesAutoNameString = 'New background'; - obj.addBackground(startBackground{:}); + obj.addBackground(allowedNames, startBackground{:}); end function names = getNames(obj) @@ -50,24 +53,24 @@ names = obj.backgrounds.varTable{:,1}; end - function obj = addBackground(obj, varargin) + function obj = addBackground(obj, allowedNames, varargin) % Adds a new entry to the background table. % - % background.addBackground('New Row'); - % background.addBackground('New Row', 'constant', 'param_name'); - % background.addBackground('New Row', 'function', 'function_name', 'param_name'); - % background.addBackground('New Row', 'data'); + % background.addBackground(allowedNames, 'New Row'); + % background.addBackground(allowedNames, 'New Row', 'constant', 'param_name'); + % background.addBackground(allowedNames, 'New Row', 'function', 'function_name', 'param_name', 'param_name'); + % background.addBackground(allowedNames, 'New Row', 'data', 'data_name', 'param_name'); in = varargin; if isempty(in) - thisRow = {}; + newRow = {}; else - thisRow = {'','','','','','',''}; + newRow = {'','','','','','','',''}; if length(in) == 1 % Assume the input is just a name - thisRow = {in}; + newRow = {in}; else - thisRow{1} = in; + newRow{1} = in; end end @@ -79,37 +82,50 @@ throw(exceptions.invalidNumberOfInputs(sprintf('For type ''%s'', at least three inputs are required, but only %d are supplied', typeVal, length(in)))); end - thisRow{1} = in{1}; - thisRow{2} = in{2}; + newRow{1} = in{1}; + newRow{2} = in{2}; % Check that the other params inputted are either valid - % background names, or numbers in range.. + % background names, or numbers in range switch typeVal case allowedTypes.Constant.value - % Param 3 must be a valid parameter - thisParam = obj.validateParam(in(3)); - thisRow{3} = thisParam; + % Param 3 (source) must be a valid background parameter + newRow{3} = obj.validateParam(in(3), obj.backgroundParams.getNames(), 'Background Param'); + + + case allowedTypes.Data.value + % Background is contained within a data file. + newRow{3} = obj.validateParam(in(3), allowedNames.dataNames, 'Data'); + % We also allow for an optional data offset + if length(in) >= 4 + newRow{4} = obj.validateParam(in(4), obj.backgroundParams.getNames(), 'Background Param'); + end + case allowedTypes.Function.value - throw(exceptions.notImplemented('Function backgrounds are not yet supported.')) - % Param 3 is assumed to be function name - % any other given parameters must be in paramNames - % list or numbers in range - thisRow{3} = in{3}; - for i = 4:length(in) - thisParam = obj.validateParam(in(i)); - thisRow{i} = thisParam; + % Param 3 (source) is the function name, defined in + % the custom files table + newRow{3} = obj.validateParam(in(3), allowedNames.customFileNames, 'Custom File'); + + if length(in) >= 4 + % Any other given parameters must be valid + % background parameters + params = in(4:end); + params = params(~(cellfun(@(x) isequal(x,""), params))); + for i = 1:length(params) + thisParam = obj.validateParam(params(i), obj.backgroundParams.getNames(), 'Background Param'); + newRow{i+3} = thisParam; + end end - case allowedTypes.Data.value - throw(exceptions.notImplemented('Data backgrounds are not yet supported.')) - % Background is assumed to be given by a 4th column - % of a data file. We don't have access to the - % data files at this point so this (i.e. that data is - % [n x 4] ) will be checked downstream - thisRow = {in{1}, in{2}, '', '', '', '', ''}; - end + end + + % Check number of non-empty values + if sum(~(cellfun(@(x) isequal(x,""), in))) > obj.maxValues.(typeVal) + 3 + warning('warnings:invalidNumberOfInputs', 'Value fields %d - 5 are not required for type ''%s'' backgrounds, they will not be included', obj.maxValues.(typeVal) + 1, typeVal) + end + end - obj.backgrounds.addRow(thisRow{:}); + obj.backgrounds.addRow(newRow{:}); end function obj = removeBackground(obj, row) @@ -121,11 +137,12 @@ obj.backgrounds.removeRow(row); end - function obj = setBackground(obj, row, varargin) + function obj = setBackground(obj, row, allowedNames, varargin) % Changes the value of a given background in the table. Expects the - % index or name of background and keyword/value pairs to set. + % index or name of background, the struct of allowed data and + % function names, and keyword/value pairs to set. % - % background.setBackground(1, 'name', 'back 1', 'type', 'constant', 'value1', 'param_name'); + % background.setBackground(1, allowedNames, 'name', 'back 1', 'type', 'constant', 'source', 'param_name'); if isText(row) row = obj.backgrounds.findRowIndex(row, obj.getNames(), 'Unrecognised background'); elseif isnumeric(row) @@ -137,32 +154,59 @@ throw(exceptions.invalidType('Unrecognised row')); end - p = inputParser; - addParameter(p, 'name', obj.backgrounds.varTable{row, 1}, @isText); - addParameter(p, 'type', obj.backgrounds.varTable{row, 2}, @(x) isText(x) || isenum(x)); - addParameter(p, 'value1', obj.backgrounds.varTable{row, 3}, @isText); - addParameter(p, 'value2', obj.backgrounds.varTable{row, 4}, @isText); - addParameter(p, 'value3', obj.backgrounds.varTable{row, 5}, @isText); - addParameter(p, 'value4', obj.backgrounds.varTable{row, 6}, @isText); - - parse(p, varargin{:}); - inputBlock = p.Results; - - obj.backgrounds.setValue(row, 1, inputBlock.name); + inputBlock = obj.makeInputBlock(row, varargin{:}); if ~isempty(inputBlock.type) inputBlock.type = validateOption(inputBlock.type, 'allowedTypes', obj.invalidTypeMessage).value; - obj.backgrounds.setValue(row, 2, inputBlock.type); + + % If the type of the background is changed, clear all + % source and value fields + if ~strcmpi(inputBlock.type, obj.backgrounds.varTable{row, 2}) + warning("warnings:fieldsCleared", "When changing the type of a background all unset fields are cleared"); + for i = 3:width(obj.backgrounds.varTable) + obj.backgrounds.setValue(row, i, ''); + end + + % Having cleared the table, we need to re-parse the + % inputs to the function + inputBlock = obj.makeInputBlock(row, varargin{:}); + end + end + + % For data and function types, source is the data/function name + source = convertStringsToChars(inputBlock.source); + if ~isempty(source) + if strcmpi(inputBlock.type, allowedTypes.Constant.value) + source = obj.validateParam(source, obj.backgroundParams.getNames(), 'Background Param'); + end + if strcmpi(inputBlock.type, allowedTypes.Data.value) + source = obj.validateParam(source, allowedNames.dataNames, 'Data'); + end + if strcmpi(inputBlock.type, allowedTypes.Function.value) + source = obj.validateParam(source, allowedNames.customFileNames, 'Custom File'); + end end - values = {inputBlock.value1, inputBlock.value2, inputBlock.value3, inputBlock.value4}; - for i = 1:4 + + values = {inputBlock.value1, inputBlock.value2, inputBlock.value3, inputBlock.value4, inputBlock.value5}; + for i = 1:5 value = convertStringsToChars(values{i}); - % for function type, value 1 is the function name so no validation is done - if ~isempty(value) && ~(i==1 && strcmpi(inputBlock.type, allowedTypes.Function.value)) - value = obj.validateParam(value); + if ~isempty(value) + obj.validateParam(value, obj.backgroundParams.getNames(), 'Background Param'); + if i > obj.maxValues.(inputBlock.type) + warning('warnings:invalidNumberOfInputs', 'Value fields %d - 5 are not required for type ''%s'' backgrounds, they will be ignored by RAT', obj.maxValues.(inputBlock.type) + 1, inputBlock.type) + break + end end - obj.backgrounds.setValue(row, i + 2, value); end + + % Validation is done, so set the fields to the new values + obj.backgrounds.setValue(row, 1, inputBlock.name); + obj.backgrounds.setValue(row, 2, inputBlock.type); + obj.backgrounds.setValue(row, 3, source); + for i = 1:5 + obj.backgrounds.setValue(row, i + 3, convertStringsToChars(values{i})); + end + end function obj = setBackgroundName(obj, row, name) @@ -204,7 +248,7 @@ function displayBackgroundsObject(obj, showPriors) backgroundNames = obj.backgrounds.varTable{:,1}; backgroundTypes = obj.backgrounds.varTable{:,2}; - backgroundValues = table2cell(obj.backgrounds.varTable(:,3:7)); + backgroundValues = table2cell(obj.backgrounds.varTable(:,3:width(obj.backgrounds.varTable))); backgroundStruct.backgroundNames = backgroundNames; backgroundStruct.backgroundTypes = backgroundTypes; @@ -212,25 +256,44 @@ function displayBackgroundsObject(obj, showPriors) end end - methods (Access = protected) - function thisPar = validateParam(obj, param) + methods (Access = private) + function inputBlock = makeInputBlock(obj, row, varargin) + % Parses the input arguments. + % + % param = obj.makeInputBlock(1, 'name', 'back 1', 'type', 'constant', 'source', 'param_name'); + p = inputParser; + addParameter(p, 'name', obj.backgrounds.varTable{row, 1}, @isText); + addParameter(p, 'type', obj.backgrounds.varTable{row, 2}, @(x) isText(x) || isenum(x)); + addParameter(p, 'source', obj.backgrounds.varTable{row, 3}, @isText); + addParameter(p, 'value1', obj.backgrounds.varTable{row, 4}, @isText); + addParameter(p, 'value2', obj.backgrounds.varTable{row, 5}, @isText); + addParameter(p, 'value3', obj.backgrounds.varTable{row, 6}, @isText); + addParameter(p, 'value4', obj.backgrounds.varTable{row, 7}, @isText); + addParameter(p, 'value5', obj.backgrounds.varTable{row, 8}, @isText); + + parse(p, varargin{:}); + inputBlock = p.Results; + end + end + + methods (Static, Access = protected) + function thisPar = validateParam(param, paramList, parameterType) % Checks that given parameter index or name is valid, then returns the % parameter name. % - % param = obj.validateParam('param_name'); + % param = obj.validateParam('param_name', paramNames, 'Background Param'); if iscell(param) param = param{:}; end - parList = obj.backgroundParams.getNames(); if isnumeric(param) - if (param < 1) || (param > length(parList)) - throw(exceptions.indexOutOfRange(sprintf('Background Parameter %d is out of range', param))); + if (param < 1) || (param > length(paramList)) + throw(exceptions.indexOutOfRange(sprintf('%s %d is out of range', parameterType, param))); else - thisPar = parList(param); + thisPar = paramList(param); end elseif isText(param) - if ~strcmpi(param, parList) - throw(exceptions.nameNotRecognised(sprintf('Unrecognised parameter name %s', param))); + if ~strcmpi(param, paramList) + throw(exceptions.nameNotRecognised(sprintf('Unrecognised %s name %s', parameterType, param))); else thisPar = param; end diff --git a/API/projectClass/contrastsClass.m b/API/projectClass/contrastsClass.m index f47a4dd59..3d40e230c 100644 --- a/API/projectClass/contrastsClass.m +++ b/API/projectClass/contrastsClass.m @@ -80,7 +80,7 @@ dataPresent = zeros(1,nContrasts); dataLimits = cell(1,nContrasts); simLimits = cell(1,nContrasts); - data = cell(1,nContrasts); + contrastData = cell(1,nContrasts); oilChiDataPresent = zeros(1,nContrasts); oilChiData = cell(1,nContrasts); @@ -141,11 +141,11 @@ end dataLimits{i} = thisDataLimit; simLimits{i} = dataTable{thisDataVal,4}{:}; - data{i} = dataTable{thisDataVal,2}{:}; + contrastData{i} = dataTable{thisDataVal,2}{:}; else dataLimits{i} = [0 0]; simLimits{i} = [0 0]; - data{i} = [0 0 0]; + contrastData{i} = [0 0 0]; end end @@ -175,11 +175,11 @@ contrastStruct.contrastQzshifts = contrastQzshifts; contrastStruct.contrastScalefactors = contrastScalefactors; contrastStruct.contrastResolutions = contrastResolutions; - contrastStruct.resample = resample; + contrastStruct.contrastData = contrastData; contrastStruct.dataPresent = dataPresent; contrastStruct.dataLimits = dataLimits; contrastStruct.simLimits = simLimits; - contrastStruct.data = data; + contrastStruct.resample = resample; contrastStruct.oilChiDataPresent = oilChiDataPresent; contrastStruct.oilChiData = oilChiData; diff --git a/API/projectClass/customFileClass.m b/API/projectClass/customFileClass.m index ebbffe18d..538fd90fa 100644 --- a/API/projectClass/customFileClass.m +++ b/API/projectClass/customFileClass.m @@ -238,6 +238,7 @@ function displayTable(obj) % % customFiles.toStruct() fileStruct.files = {}; + fileStruct.fileIdentifiers = {}; numberOfFiles = obj.rowCount; if numberOfFiles > 0 filesList = cell(numberOfFiles, 1); @@ -287,6 +288,7 @@ function displayTable(obj) filesList{i} = handle; end fileStruct.files = filesList; + fileStruct.fileIdentifiers = obj.varTable{:, 1}; end end diff --git a/API/projectClass/dataClass.m b/API/projectClass/dataClass.m index efa0cbd22..351364452 100644 --- a/API/projectClass/dataClass.m +++ b/API/projectClass/dataClass.m @@ -174,6 +174,22 @@ obj.varTable{whichData,1} = {name}; end + function outStruct = toStruct(obj) + % Converts the class parameters into a structure array. + numData = obj.rowCount; + dataNames = cell(numData, 1); + allData = cell(numData, 1); + + for i = 1:numData + row = obj.varTable{i,1}; + dataNames{i} = row{1}; + allData{i} = obj.varTable{i,2}; + end + + outStruct.dataNames = dataNames; + outStruct.allData = allData; + end + function displayTable(obj) % Displays the table object. The actual obj.varTable has the % format {string, cell, double, double}, but for display we diff --git a/API/projectClass/multiTypeTable.m b/API/projectClass/multiTypeTable.m index a2f82dede..b9ddd1e62 100644 --- a/API/projectClass/multiTypeTable.m +++ b/API/projectClass/multiTypeTable.m @@ -13,9 +13,9 @@ % Initialises a multi-type table. % % multiTable = multiTypeTable(); - sz = [0 7]; - varTypes = {'string','string','string','string','string','string','string'}; - varNames = {'Name','Type','Value 1','Value 2','Value 3','Value 4','Value 5'}; + sz = [0 8]; + varTypes = {'string','string','string','string','string','string','string','string'}; + varNames = {'Name','Type','Source','Value 1','Value 2','Value 3','Value 4','Value 5'}; obj.varTable = table('Size',sz,'VariableTypes',varTypes,'VariableNames',varNames); end @@ -32,18 +32,18 @@ thisName = char(obj.typesAutoNameString); thisNum = obj.autoNameCounter; name = sprintf('%s %d', thisName, thisNum); - newRow = [name, allowedTypes.Constant.value, repmat({''}, 1, 5)]; + newRow = [name, allowedTypes.Constant.value, repmat({''}, 1, width(obj.varTable)-2)]; case 1 % One parameter: assume this is a name - newRow = [varargin, allowedTypes.Constant.value, repmat({''}, 1, 5)]; + newRow = [varargin, allowedTypes.Constant.value, repmat({''}, 1, width(obj.varTable)-2)]; otherwise % Two or more parameters are specified. % Assume the specified parameters refer to each table % entry in order, then pad the row with empty % characters if necessary - newRow = [varargin, repmat({''}, 1, 7-length(varargin))]; + newRow = [varargin, repmat({''}, 1, width(obj.varTable)-length(varargin))]; % Check type is one of the allowed types invalidTypeMessage = sprintf('Allowed type must be a allowedTypes enum or one of the following strings (%s)', ... @@ -51,8 +51,8 @@ newRow{2} = validateOption(newRow{2}, 'allowedTypes', invalidTypeMessage).value; end - % Pass in only the first seven values to ensure input is not too long - addRow@tableUtilities(obj, newRow{1:7}); + % Pass in only enough values to fit in the table + addRow@tableUtilities(obj, newRow{1:width(obj.varTable)}); end diff --git a/API/projectClass/projectClass.m b/API/projectClass/projectClass.m index 3c6705875..51b6d7061 100644 --- a/API/projectClass/projectClass.m +++ b/API/projectClass/projectClass.m @@ -115,22 +115,22 @@ % Initialise scalefactors table obj.scalefactors = parametersClass('Scalefactor 1',0.02,0.23,0.25,false,priorTypes.Uniform,0,Inf); + + % Initialise data object + obj.data = dataClass('Simulation', [], [], []); + + % Initialise custom file object + obj.customFile = customFileClass(); % Initialise backgrounds object backgroundParams = parametersClass('Background Param 1',1e-7,1e-6,1e-5,false,priorTypes.Uniform,0,Inf); backgrounds = {'Background 1',allowedTypes.Constant.value,'Background Param 1','','','',''}; - obj.background = backgroundsClass(backgroundParams, backgrounds); + obj.background = backgroundsClass(backgroundParams, backgrounds, obj.getDataAndFunctionNames()); % Initialise resolution object resolutionParams = parametersClass('Resolution par 1',0.01,0.03,0.05,false,priorTypes.Uniform,0,Inf); resolutions = {'Resolution 1',allowedTypes.Constant.value,'Resolution par 1','','','',''}; obj.resolution = resolutionsClass(resolutionParams, resolutions); - - % Initialise data object - obj.data = dataClass('Simulation', [], [], []); - - % Initialise custom file object - obj.customFile = customFileClass(); % Initialise contrasts object obj.contrasts = contrastsClass(); @@ -199,7 +199,16 @@ function delete(obj) end end - function names = getAllAllowedNames(obj) + function names = getDataAndFunctionNames(obj) + % Returns a cell array of all currently + % set data and custom file names for the project. + % These are used to check backgrounds and resolutions of the + % Data and Function types. + names.dataNames = obj.data.getNames(); + names.customFileNames = obj.customFile.getNames(); + end + + function names = getAllAllowedNames(obj) % Returns a cell array of all currently % set parameter names for the project. names.paramNames = obj.parameters.getNames(); @@ -495,7 +504,7 @@ function delete(obj) % up to 4 parameters % % project.addBackground('name', 'constant', 'par'); - obj.background.addBackground(varargin{:}); + obj.background.addBackground(obj.getDataAndFunctionNames(), varargin{:}); end function obj = removeBackground(obj, row) @@ -512,7 +521,7 @@ function delete(obj) % index or name of background and keyword/value pairs to set % % project.setBackground(1, 'name', 'Background ACMW'); - obj.background.setBackground(row, varargin{:}); + obj.background.setBackground(row, obj.getDataAndFunctionNames(), varargin{:}); end function obj = setBackgroundName(obj, row, name) @@ -767,7 +776,7 @@ function delete(obj) % "resolution", "resample", "model" % % project.addContrast('contrast 1', 'bulkIn', 'Silicon'); - allowedNames = obj.getAllAllowedNames(); + allowedNames = obj.getAllAllowedNames; obj.contrasts.addContrast(allowedNames, varargin{:}); end @@ -873,6 +882,9 @@ function delete(obj) % Custom files customFileStruct = obj.customFile.toStruct(); + + % Data + dataStruct = obj.data.toStruct(); % Contrasts allNames = obj.getAllAllowedNames; @@ -891,6 +903,7 @@ function delete(obj) qzshiftStruct, ... layersStruct, ... customFileStruct, ... + dataStruct, ... contrastStruct); end @@ -1174,6 +1187,39 @@ function modifyLayersTable(obj,~,~) script = script + newline; end + % Data class requires writing and reading the data + script = script + sprintf(options.objName + ".removeData(1);\n"); + + for i=1:obj.data.rowCount + + % Write and read data if it exists, else add an empty, + % named row + if isempty(obj.data.varTable{i, 2}{:}) + script = script + sprintf(options.objName + ".addData('%s');\n", obj.data.varTable{i, 1}); + else + if options.exportData + writematrix(obj.data.varTable{i, 2}{:}, "data_" + string(i) + ".dat"); + script = script + sprintf("data_%d = readmatrix('%s');\n", i, "data_" + string(i) + ".dat"); + script = script + sprintf(options.objName + ".addData('%s', data_%d);\n", obj.data.varTable{i, 1}, i); + else + script = script + sprintf("data_%d = %s;\n", i, mat2str(obj.data.varTable{i, 2}{:}, 15)); + script = script + sprintf(options.objName + ".addData('%s', data_%d);\n", obj.data.varTable{i, 1}, i); + end + end + + % Also need to set dataRange and simRange explicitly as they + % are optional + if ~isempty(obj.data.varTable{i, 3}{:}) + script = script + sprintf(options.objName + ".setData(%d, 'dataRange', [%.15g %.15g]);\n", i, obj.data.varTable{i, 3}{:}); + end + if ~isempty(obj.data.varTable{i, 4}{:}) + script = script + sprintf(options.objName + ".setData(%d, 'simRange', [%.15g %.15g]);\n", i, obj.data.varTable{i, 4}{:}); + end + + script = script + newline; + + end + % Now deal with background and resolutions, which have % subclasses stringClasses = ["background", "resolution"]; @@ -1214,39 +1260,6 @@ function modifyLayersTable(obj,~,~) end - % Data class requires writing and reading the data - script = script + sprintf(options.objName + ".removeData(1);\n"); - - for i=1:obj.data.rowCount - - % Write and read data if it exists, else add an empty, - % named row - if isempty(obj.data.varTable{i, 2}{:}) - script = script + sprintf(options.objName + ".addData('%s');\n", obj.data.varTable{i, 1}); - else - if options.exportData - writematrix(obj.data.varTable{i, 2}{:}, "data_" + string(i) + ".dat"); - script = script + sprintf("data_%d = readmatrix('%s');\n", i, "data_" + string(i) + ".dat"); - script = script + sprintf(options.objName + ".addData('%s', data_%d);\n", obj.data.varTable{i, 1}, i); - else - script = script + sprintf("data_%d = %s;\n", i, mat2str(obj.data.varTable{i, 2}{:}, 15)); - script = script + sprintf(options.objName + ".addData('%s', data_%d);\n", obj.data.varTable{i, 1}, i); - end - end - - % Also need to set dataRange and simRange explicitly as they - % are optional - if ~isempty(obj.data.varTable{i, 3}{:}) - script = script + sprintf(options.objName + ".setData(%d, 'dataRange', [%.15g %.15g]);\n", i, obj.data.varTable{i, 3}{:}); - end - if ~isempty(obj.data.varTable{i, 4}{:}) - script = script + sprintf(options.objName + ".setData(%d, 'simRange', [%.15g %.15g]);\n", i, obj.data.varTable{i, 4}{:}); - end - - script = script + newline; - - end - % Contrasts are a cell array rather than a table % Need to handle resample and model fields separately for i=1:obj.contrasts.numberOfContrasts diff --git a/API/projectClass/resolutionsClass.m b/API/projectClass/resolutionsClass.m index 190a06b79..52a1a0fac 100644 --- a/API/projectClass/resolutionsClass.m +++ b/API/projectClass/resolutionsClass.m @@ -30,7 +30,7 @@ % cell array with the first resolution entry % % params = parametersClass({'Resolution Param 1', 0.01, 0.03, 0.05, false}); - % resolution = resolutionsClass(params , {'Resolution 1', 'constant', 'Tails'}); + % resolution = resolutionsClass(params, {'Resolution 1', 'constant', 'Tails'}); obj.resolutionParams = parameters; % Make a multiType table to define the actual resolutions @@ -58,14 +58,14 @@ function addResolution(obj, varargin) in = varargin; if isempty(in) - thisRow = {}; + newRow = {}; else - thisRow = {'','','','','','',''}; + newRow = {'','','','','','',''}; if length(in) == 1 % Assume the input is just a name - thisRow = {in}; + newRow = {in}; else - thisRow{1} = in; + newRow{1} = in; end end @@ -77,36 +77,30 @@ function addResolution(obj, varargin) throw(exceptions.invalidNumberOfInputs(sprintf('For type ''%s'', at least three inputs are required, but only %d are supplied', typeVal, length(in)))); end - thisRow{1} = in{1}; - thisRow{2} = in{2}; + newRow{1} = in{1}; + newRow{2} = in{2}; % Check that the other params inputted are either valid % resolution names, or numbers in range.. switch typeVal case allowedTypes.Constant.value - % Param 3 must be a valid parameter - thisParam = obj.validateParam(in(3)); - thisRow{3} = thisParam; - - case allowedTypes.Function.value - % Param 3 is assumed to be function name - % any other given parameters must be in paramNames - % list or numbers in range - thisRow{3} = in{3}; - for i = 4:length(in) - thisParam = obj.validateParam(in(i)); - thisRow{i} = thisParam; + % Param 3 (source) must be a valid resolution parameter + newRow{3} = obj.validateParam(in(3), obj.resolutionParams.getNames(), 'Resolution Param'); + if sum(~(cellfun(@(x) isequal(x,""), in))) > 3 + warning('warnings:invalidNumberOfInputs', 'Value fields 1 - 5 are not required for type ''constant'' resolutions, they will not be included') end case allowedTypes.Data.value % Resolution is assumed to be given by a 4th column - % of a data file. We don't have access to the - % data files at this point so this (i.e. that data is - % [n x 4] ) will be checked downstream - thisRow = {in{1}, in{2}, '', '', '', '', ''}; - end + % of a data file, so no further parameters are + % required + if sum(~(cellfun(@(x) isequal(x,""), in))) > 3 + warning('warnings:invalidNumberOfInputs', 'The Source and Value fields 1 - 5 are not required for type ''data'' resolutions, they will not be included') + end + end + end - obj.resolutions.addRow(thisRow{:}); + obj.resolutions.addRow(newRow{:}); end function removeResolution(obj, row) @@ -122,7 +116,7 @@ function setResolution(obj, row, varargin) % Changes the value of a given resolution in the table. Expects the % index or name of resolution and keyword/value pairs to set. % - % resolution.setResolution(1, 'name', 'resolution 1', 'type', 'constant', 'value1', 'param_name'); + % resolution.setResolution(1, 'name', 'resolution 1', 'type', 'constant', 'source', 'param_name'); if isText(row) row = obj.resolutions.findRowIndex(row, obj.getNames(), 'Unrecognised resolution'); elseif isnumeric(row) @@ -134,31 +128,51 @@ function setResolution(obj, row, varargin) throw(exceptions.invalidType('Unrecognised row')); end - p = inputParser; - addParameter(p, 'name', obj.resolutions.varTable{row, 1}, @isText); - addParameter(p, 'type', obj.resolutions.varTable{row, 2}, @(x) isText(x) || isenum(x)); - addParameter(p, 'value1', obj.resolutions.varTable{row, 3}, @isText); - addParameter(p, 'value2', obj.resolutions.varTable{row, 4}, @isText); - addParameter(p, 'value3', obj.resolutions.varTable{row, 5}, @isText); - addParameter(p, 'value4', obj.resolutions.varTable{row, 6}, @isText); - - parse(p, varargin{:}); - inputBlock = p.Results; - - obj.resolutions.setValue(row, 1, inputBlock.name); + inputBlock = obj.makeInputBlock(row, varargin{:}); if ~isempty(inputBlock.type) inputBlock.type = validateOption(inputBlock.type, 'allowedTypes', obj.invalidTypeMessage).value; - obj.resolutions.setValue(row, 2, inputBlock.type); - end - values = {inputBlock.value1, inputBlock.value2, inputBlock.value3, inputBlock.value4}; - for i = 1:4 + + % If the type of the resolution is changed, clear all + % source and value fields + if ~strcmpi(inputBlock.type, obj.resolutions.varTable{row, 2}) + warning('warnings:fieldsCleared', "When changing the type of a resolution all unset fields are cleared"); + for i = 3:width(obj.resolutions.varTable) + obj.resolutions.setValue(row, i, ''); + end + + % Having cleared the table, we need to re-parse the + % inputs to the function + inputBlock = obj.makeInputBlock(row, varargin{:}); + end + end + + % For data and function types, source is the data/function name + source = convertStringsToChars(inputBlock.source); + if ~isempty(source) + if strcmpi(inputBlock.type, allowedTypes.Constant.value) + source = obj.validateParam(source, obj.resolutionParams.getNames(), 'Resolution Param'); + elseif strcmpi(inputBlock.type, allowedTypes.Data.value) + warning('warnings:invalidNumberOfInputs', 'The Source field is not required for type ''Data'' resolutions, they will be ignored by RAT') + end + end + + values = {inputBlock.value1, inputBlock.value2, inputBlock.value3, inputBlock.value4, inputBlock.value5}; + for i = 1:5 value = convertStringsToChars(values{i}); - % for function type, value 1 is the function name so no validation is done - if ~isempty(value) && ~(i==1 && strcmpi(inputBlock.type,allowedTypes.Function.value)) - value = obj.validateParam(value); + if ~isempty(value) + obj.validateParam(value, obj.resolutionParams.getNames(), 'Resolution Param'); + warning('warnings:invalidNumberOfInputs', 'Value fields 1 - 5 are not required for type ''%s'' backgrounds, they will be ignored by RAT', inputBlock.type) + break end - obj.resolutions.setValue(row, i + 2, value); + end + + % Validation is done, so set the fields to the new values + obj.resolutions.setValue(row, 1, inputBlock.name); + obj.resolutions.setValue(row, 2, inputBlock.type); + obj.resolutions.setValue(row, 3, source); + for i = 1:5 + obj.resolutions.setValue(row, i + 3, convertStringsToChars(values{i})); end end @@ -185,7 +199,7 @@ function setResolution(obj, row, varargin) resolutionNames = obj.resolutions.varTable{:,1}; resolutionTypes = obj.resolutions.varTable{:,2}; - resolutionValues = table2cell(obj.resolutions.varTable(:,3:7)); + resolutionValues = table2cell(obj.resolutions.varTable(:,3:width(obj.resolutions.varTable))); resolutionStruct.resolutionNames = resolutionNames; resolutionStruct.resolutionTypes = resolutionTypes; @@ -209,8 +223,28 @@ function displayResolutionsObject(obj, showPriors) end end - methods (Access = protected) - function thisPar = validateParam(obj, param) + methods (Access = private) + function inputBlock = makeInputBlock(obj, row, varargin) + % Parses the input arguments. + % + % param = obj.makeInputBlock(1, 'name', 'back 1', 'type', 'constant', 'source', 'param_name'); + p = inputParser; + addParameter(p, 'name', obj.resolutions.varTable{row, 1}, @isText); + addParameter(p, 'type', obj.resolutions.varTable{row, 2}, @(x) isText(x) || isenum(x)); + addParameter(p, 'source', obj.resolutions.varTable{row, 3}, @isText); + addParameter(p, 'value1', obj.resolutions.varTable{row, 4}, @isText); + addParameter(p, 'value2', obj.resolutions.varTable{row, 5}, @isText); + addParameter(p, 'value3', obj.resolutions.varTable{row, 6}, @isText); + addParameter(p, 'value4', obj.resolutions.varTable{row, 7}, @isText); + addParameter(p, 'value5', obj.resolutions.varTable{row, 8}, @isText); + + parse(p, varargin{:}); + inputBlock = p.Results; + end + end + + methods (Static, Access = protected) + function thisPar = validateParam(param, paramList, parameterType) % Checks that given parameter index or name is valid, then returns the % parameter name. % @@ -218,18 +252,19 @@ function displayResolutionsObject(obj, showPriors) if iscell(param) param = param{:}; end - parList = obj.resolutionParams.getNames(); if isnumeric(param) - if (param < 1) || (param > length(parList)) - throw(exceptions.indexOutOfRange(sprintf('Resolution Parameter %d is out of range', param))); + if (param < 1) || (param > length(paramList)) + throw(exceptions.indexOutOfRange(sprintf('%s %d is out of range', parameterType, param))); + else + thisPar = paramList(param); end - thisPar = parList(param); - else - if ~strcmpi(param, parList) - throw(exceptions.nameNotRecognised(sprintf('Unrecognised parameter name %s', param))); + elseif isText(param) + if ~strcmpi(param, paramList) + throw(exceptions.nameNotRecognised(sprintf('Unrecognised %s name %s', parameterType, param))); + else + thisPar = param; end - thisPar = param; - end + end end end end diff --git a/compile/fullCompile/makeCompileArgsFull.m b/compile/fullCompile/makeCompileArgsFull.m index f6e03cac4..e70221807 100644 --- a/compile/fullCompile/makeCompileArgsFull.m +++ b/compile/fullCompile/makeCompileArgsFull.m @@ -17,8 +17,11 @@ ARGS_1_1.numberOfContrasts = coder.typeof(0); ARGS_1_1.geometry = coder.typeof('X',[1 maxArraySize],[0 1]); ARGS_1_1.useImaginary = coder.typeof(true); -ARGS_1_1.contrastBackgroundParams = coder.typeof(0,[1 maxArraySize],[0 1]); -ARGS_1_1.contrastBackgroundActions = coder.typeof(0,[1 maxArraySize],[0 1]); +ARG = coder.typeof(0,[1 5],[0 1]); +ARGS_1_1.contrastBackgroundParams = coder.typeof({ARG},[1 maxArraySize],[0 1]); +ARG = coder.typeof('X',[1 maxArraySize],[0 1]); +ARGS_1_1.contrastBackgroundTypes = coder.typeof({ARG},[1 maxArraySize],[0 1]); +ARGS_1_1.contrastBackgroundActions = coder.typeof({ARG},[1 maxArraySize],[0 1]); ARGS_1_1.contrastQzshifts = coder.typeof(0,[1 maxArraySize],[0 1]); ARGS_1_1.contrastScalefactors = coder.typeof(0,[1 maxArraySize],[0 1]); ARGS_1_1.contrastBulkIns = coder.typeof(0,[1 maxArraySize],[0 1]); @@ -45,7 +48,7 @@ ARGS_1_2 = cell([1 21]); ARG = coder.typeof(0,[1 2]); ARGS_1_2{1} = coder.typeof({ARG}, [1 maxArraySize],[0 1]); -ARG = coder.typeof(0,[maxDataSize 5],[1 1]); +ARG = coder.typeof(0,[maxDataSize 6],[1 0]); ARGS_1_2{2} = coder.typeof({ARG}, [1 maxArraySize],[0 1]); ARG = coder.typeof(0,[1 2]); ARGS_1_2{3} = coder.typeof({ARG}, [1 maxArraySize],[0 1]); diff --git a/compile/reflectivityCalculation/makeCompileArgs.m b/compile/reflectivityCalculation/makeCompileArgs.m index d3690f511..e40a0048d 100644 --- a/compile/reflectivityCalculation/makeCompileArgs.m +++ b/compile/reflectivityCalculation/makeCompileArgs.m @@ -17,8 +17,11 @@ ARGS_1_1.numberOfContrasts = coder.typeof(0); ARGS_1_1.geometry = coder.typeof('X',[1 maxArraySize],[0 1]); ARGS_1_1.useImaginary = coder.typeof(true); -ARGS_1_1.contrastBackgroundParams = coder.typeof(0,[1 maxArraySize],[0 1]); -ARGS_1_1.contrastBackgroundActions = coder.typeof(0,[1 maxArraySize],[0 1]); +ARG = coder.typeof(0,[1 5],[0 1]); +ARGS_1_1.contrastBackgroundParams = coder.typeof({ARG},[1 maxArraySize],[0 1]); +ARG = coder.typeof('X',[1 maxArraySize],[0 1]); +ARGS_1_1.contrastBackgroundTypes = coder.typeof({ARG},[1 maxArraySize],[0 1]); +ARGS_1_1.contrastBackgroundActions = coder.typeof({ARG},[1 maxArraySize],[0 1]); ARGS_1_1.contrastQzshifts = coder.typeof(0,[1 maxArraySize],[0 1]); ARGS_1_1.contrastScalefactors = coder.typeof(0,[1 maxArraySize],[0 1]); ARGS_1_1.contrastBulkIns = coder.typeof(0,[1 maxArraySize],[0 1]); @@ -45,7 +48,7 @@ ARGS_1_2 = cell([1 21]); ARG = coder.typeof(0,[1 2]); ARGS_1_2{1} = coder.typeof({ARG}, [1 maxArraySize],[0 1]); -ARG = coder.typeof(0,[maxDataSize 5],[1 1]); +ARG = coder.typeof(0,[maxDataSize 6],[1 0]); ARGS_1_2{2} = coder.typeof({ARG}, [1 maxArraySize],[0 1]); ARG = coder.typeof(0,[1 2]); ARGS_1_2{3} = coder.typeof({ARG}, [1 maxArraySize],[0 1]); diff --git a/examples/miscellaneous/alternativeLanguages/orsoDSPCCustomLayers.m b/examples/miscellaneous/alternativeLanguages/orsoDSPCCustomLayers.m index ec49b4b52..f16055886 100644 --- a/examples/miscellaneous/alternativeLanguages/orsoDSPCCustomLayers.m +++ b/examples/miscellaneous/alternativeLanguages/orsoDSPCCustomLayers.m @@ -95,7 +95,7 @@ problem.addBackground('Background H2O','constant','Backs par H2O'); % And edit the other one.... -problem.setBackground(1,'name','Background D2O', 'value1','Backs par D2O'); +problem.setBackground(1,'name','Background D2O', 'source','Backs par D2O'); % Finally modify some of the other parameters to be more suitable values % for a solid / liquid experiment. diff --git a/examples/miscellaneous/alternativeLanguages/orsoDSPCCustomLayersWorksheet.mlx b/examples/miscellaneous/alternativeLanguages/orsoDSPCCustomLayersWorksheet.mlx index 03e5fe1d7..492e32fb7 100644 Binary files a/examples/miscellaneous/alternativeLanguages/orsoDSPCCustomLayersWorksheet.mlx and b/examples/miscellaneous/alternativeLanguages/orsoDSPCCustomLayersWorksheet.mlx differ diff --git a/examples/miscellaneous/backgroundTypes/DSPCScriptWithDataBackground.m b/examples/miscellaneous/backgroundTypes/DSPCScriptWithDataBackground.m new file mode 100644 index 000000000..eac0113e7 --- /dev/null +++ b/examples/miscellaneous/backgroundTypes/DSPCScriptWithDataBackground.m @@ -0,0 +1,123 @@ +% Standard Layers fit of a DSPC floating bilayer + +% Make the project +problem = createProject(name='original_dspc_bilayer', calcType='non polarised', model='standard layers', geometry='substrate/liquid', absorption=false); + +% Make priors visible +problem.showPriors(true); + +% Set up the relevant parameters +paramGroup = { + {'Oxide thick', 5, 19.54, 60, true, 'uniform', 0, Inf}; + {'Oxide SLD', 3.39e-06, 3.39e-06, 3.41e-06, false, 'uniform', 0, Inf}; + {'Sam tails thick', 15, 22.66, 35, true, 'uniform', 0, Inf}; + {'Sam tails SLD', -5e-07, -4.01e-07, -3e-07, false, 'uniform', 0, Inf}; + {'Sam tails hydration', 1, 5.253, 50, true, 'uniform', 0, Inf}; + {'Sam rough', 1, 5.64, 15, true, 'uniform', 0, Inf}; + {'cw thick', 10, 17.12, 28, true, 'uniform', 0, Inf}; + {'cw SLD', 0, 0, 1e-09, false, 'uniform', 0, Inf}; + {'SAM head thick', 5, 8.56, 17, true, 'gaussian', 10, 2}; + {'SAM head SLD', 1e-07, 1.75e-06, 2e-06, false, 'uniform', 0, Inf}; + {'SAM head hydration', 10, 45.45, 50, true, 'uniform', 0, Inf}; + {'Bilayer head thick', 7, 10.70, 17, true, 'gaussian', 10, 2}; + {'Bilayer head SLD', 5e-07, 1.47e-06, 1.5e-06, false, 'uniform', 0, Inf}; + {'Bilayer rough', 2, 6.014, 15, true, 'uniform', 0, Inf}; + {'Bilayer tails thick', 14, 17.82, 22, true, 'uniform', 0, Inf}; + {'Bilayer tails SLD', -5e-07, -4.610e-07, 0, false, 'uniform', 0, Inf}; + {'Bilayer tails hydr', 10, 17.64, 50, true, 'uniform', 0, Inf}; + {'Bilayer heads hydr', 10, 36.15, 50, true, 'gaussian', 30, 3}; + {'cw hydration', 99.9, 100, 100, false, 'uniform', 0, Inf}; + {'Oxide Hydration', 0, 23.61, 60, true, 'uniform', 0, Inf}; + }; +problem.addParameterGroup(paramGroup); +problem.setParameter(1,'max',10); + +% Group these into layers +Layers = { + {'Oxide', 'Oxide thick', 'Oxide SLD', 'substrate roughness', 'Oxide Hydration', 'bulk out'}; + {'Sam tails', 'Sam tails thick', 'Sam tails SLD', 'Sam rough', 'Sam tails hydration', 'bulk out'}; + {'Sam heads', 'SAM head thick', 'SAM head SLD', 'Sam rough', 'SAM head hydration', 'bulk out'}; + {'Central water', 'cw thick', 'cw SLD', 'Bilayer rough', 'cw hydration', 'bulk out'}; + {'Bilayer heads', 'Bilayer head thick', 'Bilayer head SLD', 'Bilayer rough', 'Bilayer heads hydr', 'bulk out'}; + {'Bilayer tails', 'Bilayer tails thick', 'Bilayer tails SLD','Bilayer rough', 'Bilayer tails hydr', 'bulk out'}; +}; +problem.addLayerGroup(Layers); + +% Make the bulk SLD's +problem.removeBulkIn(1); +problem.addBulkIn('Silicon', 2e-06, 2.073e-06, 2.1e-06, false); + +problem.removeBulkOut(1); +problem.addBulkOut('D2O', 5.50e-06, 5.98e-06, 6.4e-06, true); +problem.addBulkOut('SMW', 1e-06, 2.21e-06, 4.99e-06, true); + +% Set the scalefactors - use one for each contrast +problem.removeScalefactor(1); +problem.addScalefactor('Scalefactor 1', 0.05, 0.10, 0.2, false); +problem.addScalefactor('Scalefactor 2', 0.05, 0.15, 0.2, false); + +% Now add the data +d2o_dat = readmatrix('DSPC_D2O.dat'); +problem.addData('dspc_bil_d2O', d2o_dat); + +smw_dat = readmatrix('DSPC_SMW.dat'); +problem.addData('dspc_bil_smw', smw_dat); + +% Now deal with the backgrounds +% Original Constant background +problem.removeBackgroundParam(1); +problem.addBackgroundParam('Backs parameter SMW', 1e-10, 3.38e-06, 4.99e-06, true); + +problem.removeBackground(1); +problem.addBackground('SMW Background','constant','Backs parameter SMW'); + +% Now deal with the data background +% Add the background data +d2oBack = readmatrix('d2o_background_data.dat'); +problem.addData('D2O Background Data',d2oBack); + +% We need an offset for the D2O Background data +problem.addBackgroundParam('D2O Data Offset',-1e-8,0,1e-8,true); + +% Add a D2O Data background +problem.addBackground('D2O data background','data','D2O Background Data','D2O Data Offset'); + +% Make the two contrasts +problem.addContrast('name', 'D2O',... + 'BulkIn', 'Silicon',... + 'BulkOut', 'D2O',... + 'background', 'D2O data background',... + 'resolution', 'Resolution 1',... + 'scalefactor', 'Scalefactor 1',... + 'data', 'dspc_bil_d2o'); + +problem.addContrast('name', 'SMW',... + 'BulkIn', 'Silicon',... + 'BulkOut', 'SMW',... + 'background', 'SMW Background',... + 'resolution', 'Resolution 1',... + 'scalefactor', 'Scalefactor 2',... + 'data', 'dspc_bil_smw'); + +% And set the model +stack = {'Oxide',... + 'Sam tails',... + 'Sam heads',... + 'Central water',... + 'Bilayer heads',... + 'Bilayer tails',... + 'Bilayer tails',... + 'Bilayer heads',... + }; + +problem.setContrastModel(1,stack); +problem.setContrastModel(2,stack); + +% Make a controls class +controls = controlsClass(); + +% Send everything to RAT +[problem,results] = RAT(problem,controls); + +plotRefSLD(problem,results); + diff --git a/examples/miscellaneous/backgroundTypes/DSPCScriptWithFunctionBackground.m b/examples/miscellaneous/backgroundTypes/DSPCScriptWithFunctionBackground.m new file mode 100644 index 000000000..1ccae8473 --- /dev/null +++ b/examples/miscellaneous/backgroundTypes/DSPCScriptWithFunctionBackground.m @@ -0,0 +1,123 @@ +% Standard Layers fit of a DSPC floating bilayer + +% Make the project +problem = createProject(name='original_dspc_bilayer', calcType='non polarised', model='standard layers', geometry='substrate/liquid', absorption=false); + +% Make priors visible +problem.showPriors(true); + +% Set up the relevant parameters +paramGroup = { + {'Oxide thick', 5, 19.54, 60, true, 'uniform', 0, Inf}; + {'Oxide SLD', 3.39e-06, 3.39e-06, 3.41e-06, false, 'uniform', 0, Inf}; + {'Sam tails thick', 15, 22.66, 35, true, 'uniform', 0, Inf}; + {'Sam tails SLD', -5e-07, -4.01e-07, -3e-07, false, 'uniform', 0, Inf}; + {'Sam tails hydration', 1, 5.253, 50, true, 'uniform', 0, Inf}; + {'Sam rough', 1, 5.64, 15, true, 'uniform', 0, Inf}; + {'cw thick', 10, 17.12, 28, true, 'uniform', 0, Inf}; + {'cw SLD', 0, 0, 1e-09, false, 'uniform', 0, Inf}; + {'SAM head thick', 5, 8.56, 17, true, 'gaussian', 10, 2}; + {'SAM head SLD', 1e-07, 1.75e-06, 2e-06, false, 'uniform', 0, Inf}; + {'SAM head hydration', 10, 45.45, 50, true, 'uniform', 0, Inf}; + {'Bilayer head thick', 7, 10.70, 17, true, 'gaussian', 10, 2}; + {'Bilayer head SLD', 5e-07, 1.47e-06, 1.5e-06, false, 'uniform', 0, Inf}; + {'Bilayer rough', 2, 6.014, 15, true, 'uniform', 0, Inf}; + {'Bilayer tails thick', 14, 17.82, 22, true, 'uniform', 0, Inf}; + {'Bilayer tails SLD', -5e-07, -4.610e-07, 0, false, 'uniform', 0, Inf}; + {'Bilayer tails hydr', 10, 17.64, 50, true, 'uniform', 0, Inf}; + {'Bilayer heads hydr', 10, 36.15, 50, true, 'gaussian', 30, 3}; + {'cw hydration', 99.9, 100, 100, false, 'uniform', 0, Inf}; + {'Oxide Hydration', 0, 23.61, 60, true, 'uniform', 0, Inf}; + }; +problem.addParameterGroup(paramGroup); +problem.setParameter(1,'max',10); + +% Group these into layers +Layers = { + {'Oxide', 'Oxide thick', 'Oxide SLD', 'substrate roughness', 'Oxide Hydration', 'bulk out'}; + {'Sam tails', 'Sam tails thick', 'Sam tails SLD', 'Sam rough', 'Sam tails hydration', 'bulk out'}; + {'Sam heads', 'SAM head thick', 'SAM head SLD', 'Sam rough', 'SAM head hydration', 'bulk out'}; + {'Central water', 'cw thick', 'cw SLD', 'Bilayer rough', 'cw hydration', 'bulk out'}; + {'Bilayer heads', 'Bilayer head thick', 'Bilayer head SLD', 'Bilayer rough', 'Bilayer heads hydr', 'bulk out'}; + {'Bilayer tails', 'Bilayer tails thick', 'Bilayer tails SLD','Bilayer rough', 'Bilayer tails hydr', 'bulk out'}; +}; +problem.addLayerGroup(Layers); + +% Make the bulk SLD's +problem.removeBulkIn(1); +problem.addBulkIn('Silicon', 2e-06, 2.073e-06, 2.1e-06, false); + +problem.removeBulkOut(1); +problem.addBulkOut('D2O', 5.50e-06, 5.98e-06, 6.4e-06, true); +problem.addBulkOut('SMW', 1e-06, 2.21e-06, 4.99e-06, true); + +% Set the scalefactors - use one for each contrast +problem.removeScalefactor(1); +problem.addScalefactor('Scalefactor 1', 0.05, 0.10, 0.2, false); +problem.addScalefactor('Scalefactor 2', 0.05, 0.15, 0.2, false); + +% Now add the data +d2o_dat = readmatrix('DSPC_D2O.dat'); +problem.addData('dspc_bil_d2O', d2o_dat); + +smw_dat = readmatrix('DSPC_SMW.dat'); +problem.addData('dspc_bil_smw', smw_dat); + +% Now deal with the backgrounds +% Original Constant background +problem.removeBackgroundParam(1); +problem.addBackgroundParam('Backs parameter SMW', 1e-10, 3.38e-06, 4.99e-06, true); + +problem.removeBackground(1); +problem.addBackground('SMW Background','constant','Backs parameter SMW'); + +% Add the function background +% Add the function to custom files, and its parameters to background +% parameters +problem.addCustomFile('Back Fun','backgroundFunction.m','matlab',pwd); + +problem.addBackgroundParam('Fn Ao',5e-7, 8e-6, 5e-5); +problem.addBackgroundParam('Fn k',40, 70, 90); +problem.addBackgroundParam('Fn Const',1e-7, 8e-6, 1e-5); + +% Add the Background +problem.addBackground('Func Background','function','Back Fun','Fn Ao','Fn k','Fn Const'); + +% Make the two contrasts +problem.addContrast('name', 'D2O',... + 'BulkIn', 'Silicon',... + 'BulkOut', 'D2O',... + 'background', 'Func background',... + 'resolution', 'Resolution 1',... + 'scalefactor', 'Scalefactor 1',... + 'data', 'dspc_bil_d2o'); + +problem.addContrast('name', 'SMW',... + 'BulkIn', 'Silicon',... + 'BulkOut', 'SMW',... + 'background', 'SMW Background',... + 'resolution', 'Resolution 1',... + 'scalefactor', 'Scalefactor 2',... + 'data', 'dspc_bil_smw'); + +% And set the model +stack = {'Oxide',... + 'Sam tails',... + 'Sam heads',... + 'Central water',... + 'Bilayer heads',... + 'Bilayer tails',... + 'Bilayer tails',... + 'Bilayer heads',... + }; + +problem.setContrastModel(1,stack); +problem.setContrastModel(2,stack); + +% Make a controls class +controls = controlsClass(); + +% Send everything to RAT +[problem,results] = RAT(problem,controls); + +plotRefSLD(problem,results); diff --git a/examples/miscellaneous/backgroundTypes/DSPC_D2O.dat b/examples/miscellaneous/backgroundTypes/DSPC_D2O.dat new file mode 100644 index 000000000..54f2f4960 --- /dev/null +++ b/examples/miscellaneous/backgroundTypes/DSPC_D2O.dat @@ -0,0 +1,82 @@ +0.011403,0.10063,0.0019003 +0.011973,0.11082,0.001883 +0.012572,0.10766,0.0016413 +0.013201,0.10652,0.0014669 +0.013861,0.090118,0.0011774 +0.014554,0.034255,0.00048888 +0.015281,0.017209,0.00026267 +0.016045,0.010465,0.00017551 +0.016848,0.0070455,0.00013083 +0.01769,0.0045958,9.7193e-05 +0.018575,0.0034925,8.0937e-05 +0.019503,0.002451,6.4505e-05 +0.020479,0.0017544,5.1254e-05 +0.021502,0.0013384,4.2675e-05 +0.022578,0.0010447,3.5865e-05 +0.023706,0.00076523,2.9299e-05 +0.024892,0.00064257,2.6236e-05 +0.026136,0.00050024,1.3657e-05 +0.027443,0.00039982,1.1639e-05 +0.028815,0.00034301,1.0137e-05 +0.030256,0.00027746,8.5758e-06 +0.031769,0.00026396,8.2806e-06 +0.033357,0.00023596,7.8864e-06 +0.035025,0.0002028,1.0041e-05 +0.036777,0.00018591,4.9391e-06 +0.038615,0.00015427,4.3142e-06 +0.040546,0.00014273,3.958e-06 +0.042573,0.00012868,3.6645e-06 +0.044702,0.00011002,3.2644e-06 +0.046937,9.1148e-05,2.8227e-06 +0.049284,9.1217e-05,2.7234e-06 +0.051748,7.6323e-05,2.3706e-06 +0.054336,6.6691e-05,2.1365e-06 +0.057052,6.4594e-05,2.4647e-06 +0.059905,6.0971e-05,1.3241e-06 +0.0629,6.3097e-05,1.2946e-06 +0.066045,6.0729e-05,1.1791e-06 +0.069348,5.9985e-05,1.1102e-06 +0.072815,6.1021e-05,1.1013e-06 +0.076456,5.6755e-05,1.035e-06 +0.080279,5.8755e-05,1.5569e-06 +0.084292,5.4071e-05,9.5338e-07 +0.088507,4.6964e-05,8.4392e-07 +0.092932,4.2634e-05,7.7134e-07 +0.097579,3.27e-05,6.528e-07 +0.10246,2.54e-05,5.4648e-07 +0.10758,1.7075e-05,4.2154e-07 +0.11296,1.2197e-05,3.4055e-07 +0.11861,7.8205e-06,2.5881e-07 +0.12454,5.091e-06,2.0153e-07 +0.13077,4.1579e-06,1.762e-07 +0.1373,3.6345e-06,1.6248e-07 +0.14417,3.3455e-06,1.5143e-07 +0.15138,2.7295e-06,1.3191e-07 +0.15895,1.8245e-06,1.0679e-07 +0.16689,1.2171e-06,8.7591e-08 +0.17524,4.9313e-07,5.6663e-08 +0.184,2.4038e-07,4.1253e-08 +0.1932,3.3832e-07,5.3216e-08 +0.20286,3.2022e-07,5.5047e-08 +0.213,4.1948e-07,6.8549e-08 +0.22365,3.1493e-07,6.3396e-08 +0.23484,2.3214e-07,5.5974e-08 +0.24658,3.3414e-07,6.8415e-08 +0.25891,3.9863e-07,8.2061e-08 +0.27185,2.5113e-07,6.271e-08 +0.28544,2.2469e-07,6.3286e-08 +0.29972,2.0862e-07,6.0631e-08 +0.3147,2.0861e-07,6.1379e-08 +0.33044,3.3381e-07,7.7193e-08 +0.34696,1.8378e-07,6.049e-08 +0.36431,2.3515e-07,6.6222e-08 +0.38252,2.1154e-07,6.3084e-08 +0.40165,2.4662e-07,6.6637e-08 +0.42173,2.017e-07,6.2432e-08 +0.44282,2.4563e-07,6.9088e-08 +0.46496,1.9906e-07,6.0793e-08 +0.48821,2.8635e-07,7.3878e-08 +0.51262,1.9471e-07,6.1764e-08 +0.53825,2.8836e-07,7.5438e-08 +0.56516,2.3816e-07,7.061e-08 +0.59342,2.1782e-07,6.6918e-08 diff --git a/examples/miscellaneous/backgroundTypes/DSPC_SMW.dat b/examples/miscellaneous/backgroundTypes/DSPC_SMW.dat new file mode 100644 index 000000000..9bdab7b0f --- /dev/null +++ b/examples/miscellaneous/backgroundTypes/DSPC_SMW.dat @@ -0,0 +1,82 @@ +0.011403,0.0018074,0.00010983 +0.011973,0.0014774,9.0584e-05 +0.012572,0.001325,7.7039e-05 +0.013201,0.0012216,6.6408e-05 +0.013861,0.0010077,5.5778e-05 +0.014554,0.0010266,5.1388e-05 +0.015281,0.00091489,4.521e-05 +0.016045,0.00080921,3.995e-05 +0.016848,0.00061576,3.3466e-05 +0.01769,0.00060308,3.1557e-05 +0.018575,0.00046074,2.6813e-05 +0.019503,0.00040453,2.4355e-05 +0.020479,0.00036496,2.2031e-05 +0.021502,0.00032468,2.0023e-05 +0.022578,0.0002479,1.6581e-05 +0.023706,0.00027709,1.7017e-05 +0.024892,0.00021141,1.4388e-05 +0.026136,0.00017034,7.5065e-06 +0.027443,0.00015127,6.7139e-06 +0.028815,0.00013632,5.9548e-06 +0.030256,0.00011151,5.2534e-06 +0.031769,9.5843e-05,4.7729e-06 +0.033357,7.5905e-05,4.2186e-06 +0.035025,6.919e-05,6.2034e-06 +0.036777,5.272e-05,2.3936e-06 +0.038615,3.9182e-05,1.9828e-06 +0.040546,2.938e-05,1.6381e-06 +0.042573,2.2329e-05,1.3936e-06 +0.044702,1.471e-05,1.0942e-06 +0.046937,8.1966e-06,7.7674e-07 +0.049284,6.4866e-06,6.6572e-07 +0.051748,3.0853e-06,4.3607e-07 +0.054336,2.6025e-06,3.888e-07 +0.057052,2.7294e-06,4.9982e-07 +0.059905,4.3615e-06,3.1992e-07 +0.0629,5.4926e-06,3.4522e-07 +0.066045,7.2943e-06,3.6968e-07 +0.069348,8.9112e-06,3.8947e-07 +0.072815,1.0612e-05,4.1912e-07 +0.076456,1.2411e-05,4.4241e-07 +0.080279,1.4576e-05,7.0225e-07 +0.084292,1.4768e-05,4.5606e-07 +0.088507,1.3957e-05,4.2438e-07 +0.092932,1.1624e-05,3.7299e-07 +0.097579,1.0598e-05,3.4827e-07 +0.10246,7.7689e-06,2.8497e-07 +0.10758,6.4311e-06,2.4647e-07 +0.11296,4.952e-06,2.0748e-07 +0.11861,2.8957e-06,1.5122e-07 +0.12454,1.9786e-06,1.2104e-07 +0.13077,1.1837e-06,9.0553e-08 +0.1373,9.5591e-07,8.0264e-08 +0.14417,9.9179e-07,7.9466e-08 +0.15138,8.1026e-07,6.9286e-08 +0.15895,7.8161e-07,6.7637e-08 +0.16689,6.039e-07,5.9878e-08 +0.17524,4.8559e-07,5.489e-08 +0.184,4.1425e-07,5.2852e-08 +0.1932,4.375e-07,5.9223e-08 +0.20286,3.0001e-07,5.1646e-08 +0.213,4.9488e-07,7.1141e-08 +0.22365,2.7977e-07,5.7809e-08 +0.23484,2.3853e-07,5.4901e-08 +0.24658,2.1767e-07,5.3744e-08 +0.25891,2.5677e-07,6.3708e-08 +0.27185,5.7975e-07,9.3465e-08 +0.28544,3.2659e-07,7.4563e-08 +0.29972,3.0527e-07,7.1553e-08 +0.3147,3.3603e-07,7.6342e-08 +0.33044,3.8583e-07,8.1122e-08 +0.34696,2.9402e-07,7.285e-08 +0.36431,3.0297e-07,7.2958e-08 +0.38252,4.0996e-07,8.5727e-08 +0.40165,4.0612e-07,8.3403e-08 +0.42173,5.3059e-07,9.7535e-08 +0.44282,4.9546e-07,9.5624e-08 +0.46496,3.5423e-07,7.8721e-08 +0.48821,3.5614e-07,7.9969e-08 +0.51262,3.7628e-07,8.3392e-08 +0.53825,5.8915e-07,1.0457e-07 +0.56516,3.2619e-07,7.9702e-08 +0.59342,3.068e-07,7.7062e-08 diff --git a/examples/miscellaneous/backgroundTypes/backgroundFunction.m b/examples/miscellaneous/backgroundTypes/backgroundFunction.m new file mode 100644 index 000000000..181e0f58d --- /dev/null +++ b/examples/miscellaneous/backgroundTypes/backgroundFunction.m @@ -0,0 +1,14 @@ +function background = backgroundFunction(xdata,params) + +% Split up the params array.... +Ao = params(1); +k = params(2); +backConst = params(3); + +% Make an exponential decay background.... +background = zeros(numel(xdata),1); +for i = 1:numel(xdata) + background(i) = Ao*exp(-k*xdata(i)) + backConst; +end + +end diff --git a/examples/miscellaneous/backgroundTypes/backgroundFunction.py b/examples/miscellaneous/backgroundTypes/backgroundFunction.py new file mode 100644 index 000000000..3c238e7b5 --- /dev/null +++ b/examples/miscellaneous/backgroundTypes/backgroundFunction.py @@ -0,0 +1,15 @@ +import numpy as np + +def backgroundFunction(xdata, params): + + # Split up the params array + Ao = params[0] + k = params[1] + back_const = params[2] + + # Make an exponential decay background + background = np.zeros(len(xdata)) + for i in range(0, len(xdata)): + background[i] = Ao*np.exp(-k*xdata[i]) + back_const + + return background diff --git a/examples/miscellaneous/backgroundTypes/d2o_background_data.dat b/examples/miscellaneous/backgroundTypes/d2o_background_data.dat new file mode 100644 index 000000000..93b2fd38a --- /dev/null +++ b/examples/miscellaneous/backgroundTypes/d2o_background_data.dat @@ -0,0 +1,82 @@ +0.011403 1.90034798968076e-06 -9.65035874608547e-07 +0.011973 1.81361996101478e-06 -4.67852140773275e-09 +0.012572 1.5763144199176e-06 -1.36151693657437e-06 +0.013201 2.66861902156408e-06 5.28737972088124e-07 +0.013861 1.19184137102607e-06 6.5429177234931e-07 +0.014554 1.75409120253422e-06 -4.50039804064594e-07 +0.015281 1.51534921649628e-06 3.54060605152339e-07 +0.016045 1.76294603973655e-06 2.30273872099416e-07 +0.016848 1.66691808740296e-06 1.02729272466451e-06 +0.01769 2.2391873415575e-06 2.02710446930881e-07 +0.018575 1.47947093349392e-06 9.31566506641381e-07 +0.019503 1.58967045467121e-06 6.58308695637623e-09 +0.020479 2.05056480300655e-06 -4.18637528083399e-07 +0.021502 2.54199126843229e-06 6.96150360898885e-08 +0.022578 1.07273638130851e-06 -5.94598550176916e-08 +0.023706 2.89987639289405e-06 8.05335897612554e-07 +0.024892 1.56081284721073e-06 5.50847432744533e-08 +0.026136 2.32386636321661e-06 -5.72991095509919e-07 +0.027443 2.52478251612625e-06 -2.38750704688337e-08 +0.028815 2.66154668842285e-06 1.05087573637142e-06 +0.030256 1.74132051718101e-06 -2.3192582338868e-07 +0.031769 2.01215747485553e-06 -4.26893410009117e-07 +0.033357 1.91881656322323e-06 8.87192534478923e-07 +0.035025 1.69716945696631e-06 1.80981995646851e-07 +0.036777 2.13585488200451e-06 -1.90164659296111e-07 +0.038615 2.17932170608953e-06 -4.91062265460096e-07 +0.040546 1.82384243860966e-06 -1.08387392818395e-06 +0.042573 2.06617996409986e-06 2.22697399577916e-07 +0.044702 3.33679088859971e-06 -1.53613977488785e-07 +0.046937 1.99621696227773e-06 3.55134601922439e-07 +0.049284 2.3551514683307e-06 -1.06523727035749e-06 +0.051748 1.76873031859355e-06 1.15746760150783e-06 +0.054336 1.73606104969994e-06 4.89763150040874e-07 +0.057052 1.82710646654775e-06 -1.15330099931726e-06 +0.059905 2.28227888686718e-06 9.45647703159621e-07 +0.0629 1.59923042799896e-06 -3.70062237263438e-07 +0.066045 1.07352660741589e-06 3.41777294345909e-07 +0.069348 2.02660800872659e-06 2.75569910736786e-07 +0.072815 1.78179239147256e-06 -6.0256088120987e-07 +0.076456 2.14000373613308e-06 -2.18911980741668e-06 +0.080279 2.04230294359047e-06 5.284442372682e-07 +0.084292 2.36455952978407e-06 -1.73629847921614e-07 +0.088507 2.45037654782291e-06 -3.78287083788833e-07 +0.092932 1.33718085273407e-06 4.35130166728242e-07 +0.097579 1.23771058575749e-06 -4.51744576618967e-07 +0.10246 2.25121666653143e-06 6.36952833032752e-07 +0.10758 2.15319571282475e-06 2.20717968415214e-07 +0.11296 1.53041976734067e-06 -6.93055107868105e-07 +0.11861 2.61870106321507e-06 7.69463958198665e-07 +0.12454 2.01650595727752e-06 4.79607176188218e-07 +0.13077 2.06178415911062e-06 1.10173268381594e-06 +0.1373 2.13696968977538e-06 -6.14098124528528e-07 +0.14417 2.3770829041412e-06 -6.16219383494697e-07 +0.15138 2.7622487528669e-06 3.50660742020884e-07 +0.15895 1.86901211887215e-06 6.33626529015099e-07 +0.16689 1.13465824611353e-06 7.62493241842828e-07 +0.17524 2.50673214999504e-06 1.05207422581854e-07 +0.184 1.53613195077685e-06 -8.87137577093779e-08 +0.1932 2.62184014311179e-06 6.22256875962273e-07 +0.20286 1.70525565120706e-06 1.67162600924891e-06 +0.213 2.74574086739327e-06 8.07667338780613e-07 +0.22365 1.59701095264287e-06 1.67629565660922e-07 +0.23484 1.4437004736234e-06 -3.59611249006791e-07 +0.24658 2.47846978404969e-06 4.99800504594724e-07 +0.25891 1.31847420553136e-06 -2.87283586089481e-07 +0.27185 2.34029248136207e-06 2.90756508518823e-07 +0.28544 2.21891181128286e-06 7.22598553179947e-07 +0.29972 1.92836622666398e-06 8.39418345516717e-07 +0.3147 1.82923374769972e-06 5.70510331434857e-07 +0.33044 3.02890531703209e-06 1.20234742176368e-06 +0.34696 1.8127324822871e-06 1.58096394623758e-06 +0.36431 1.90489840127358e-06 -1.41813181395574e-06 +0.38252 1.53063379469415e-06 -1.32294734328625e-06 +0.40165 1.59326881780842e-06 -6.38112989285387e-07 +0.42173 1.7081906242357e-06 -1.49834166690205e-06 +0.44282 2.85476268526193e-06 -1.85680046178151e-07 +0.46496 1.80479009111448e-06 -1.69120607911057e-07 +0.48821 1.6549673183601e-06 3.00340803829798e-07 +0.51262 1.77588964903545e-06 3.28929520936145e-07 +0.53825 2.35718817504981e-06 -4.48934854489947e-07 +0.56516 1.34213437585845e-06 -5.50651590195596e-07 +0.59342 2.31356104763158e-06 7.347220470815e-07 diff --git a/examples/miscellaneous/backgroundTypes/makeD2oDataBack.m b/examples/miscellaneous/backgroundTypes/makeD2oDataBack.m new file mode 100644 index 000000000..4ccd6d869 --- /dev/null +++ b/examples/miscellaneous/backgroundTypes/makeD2oDataBack.m @@ -0,0 +1,28 @@ +% Make a dummy background datasets for this problem ..... + +% Get the D2O data.... +d2o_dat = readmatrix('DSPC_D2O.dat'); + +% Use the x value.... +backgroundX = d2o_dat(:,1); +backValue = 1e-6; % A typical vlue from the existing background.... + +% Make a background set... +dummyBackValues = ones(numel(backgroundX),1) .* backValue; + +% Add Gaussian white noise to this.... +% for i = 1:numel(dummyBackValues) +% dummyBackValues(i) = dummyBackValues(i) +backNoise = normrnd(mean(dummyBackValues),5e-7,[numel(dummyBackValues),1]); +backError = normrnd(1e-7,8e-7,[numel(dummyBackValues),1]); +dummyBackValues = dummyBackValues + backNoise; + +figure(1); clf +errorbar(d2o_dat(:,1),d2o_dat(:,2)./0.1,d2o_dat(:,3)./0.1,'bo'); +hold on +errorbar(d2o_dat(:,1),dummyBackValues,backError,'ro'); +set(gca,'YScale','log'); + +% Put these together into a dummy background dataset..... +dummyBack_d2o = [d2o_dat(:,1) dummyBackValues(:) backError(:)]; +writematrix(dummyBack_d2o,'d2o_background_data.dat','FileType','text','Delimiter','\t'); diff --git a/examples/miscellaneous/roundRobin/roundRobin.mlx b/examples/miscellaneous/roundRobin/roundRobin.mlx index 2a3477b84..64de1fd2e 100644 Binary files a/examples/miscellaneous/roundRobin/roundRobin.mlx and b/examples/miscellaneous/roundRobin/roundRobin.mlx differ diff --git a/examples/normalReflectivity/customLayers/customLayersDSPCScript.m b/examples/normalReflectivity/customLayers/customLayersDSPCScript.m index 033a5ceeb..46867f77d 100644 --- a/examples/normalReflectivity/customLayers/customLayersDSPCScript.m +++ b/examples/normalReflectivity/customLayers/customLayersDSPCScript.m @@ -82,7 +82,7 @@ problem.addBackground('Background H2O','constant','Backs par H2O'); % And edit the other one.... -problem.setBackground(1,'name','Background D2O', 'value1','Backs par D2O'); +problem.setBackground(1,'name','Background D2O', 'source','Backs par D2O'); % Finally modify some of the other parameters to be more suitable values % for a solid / liquid experiment. diff --git a/examples/normalReflectivity/customLayers/customLayersDSPCSheet.mlx b/examples/normalReflectivity/customLayers/customLayersDSPCSheet.mlx index b3cbebd0a..6f7bccb95 100644 Binary files a/examples/normalReflectivity/customLayers/customLayersDSPCSheet.mlx and b/examples/normalReflectivity/customLayers/customLayersDSPCSheet.mlx differ diff --git a/examples/normalReflectivity/customXY/customXYDSPCScript.m b/examples/normalReflectivity/customXY/customXYDSPCScript.m index 6c0d10f5e..98df6b7d9 100644 --- a/examples/normalReflectivity/customXY/customXYDSPCScript.m +++ b/examples/normalReflectivity/customXY/customXYDSPCScript.m @@ -112,7 +112,7 @@ problem.addBackground('Background H2O','constant','Backs par H2O'); % And edit the other one.... -problem.setBackground(1,'name','Background D2O', 'value1','Backs par D2O'); +problem.setBackground(1,'name','Background D2O', 'source','Backs par D2O'); % Finally modify some of the other parameters to be more suitable values % for a solid / liquid experiment. diff --git a/examples/normalReflectivity/customXY/customXYDSPCSheet.mlx b/examples/normalReflectivity/customXY/customXYDSPCSheet.mlx index a566aab4b..c8eb0f481 100644 Binary files a/examples/normalReflectivity/customXY/customXYDSPCSheet.mlx and b/examples/normalReflectivity/customXY/customXYDSPCSheet.mlx differ diff --git a/examples/normalReflectivity/customXY/orsoCustomXYDSPC.m b/examples/normalReflectivity/customXY/orsoCustomXYDSPC.m index ca3fb65dc..301b1c40e 100644 --- a/examples/normalReflectivity/customXY/orsoCustomXYDSPC.m +++ b/examples/normalReflectivity/customXY/orsoCustomXYDSPC.m @@ -79,7 +79,7 @@ problem.addBackground('Background H2O','constant','Backs par H2O'); % And edit the other one.... -problem.setBackground(1,'name','Background D2O', 'value1','Backs par D2O'); +problem.setBackground(1,'name','Background D2O', 'source','Backs par D2O'); % Finally modify some of the other parameters to be more suitable values % for a solid / liquid experiment. diff --git a/examples/normalReflectivity/standardLayers/standardLayersDSPCSheet.mlx b/examples/normalReflectivity/standardLayers/standardLayersDSPCSheet.mlx index ca0689ba2..7bb3f93a9 100644 Binary files a/examples/normalReflectivity/standardLayers/standardLayersDSPCSheet.mlx and b/examples/normalReflectivity/standardLayers/standardLayersDSPCSheet.mlx differ diff --git a/minimisers/generalUtils/makeEmptyBayesResultsStruct.m b/minimisers/generalUtils/makeEmptyBayesResultsStruct.m index ba64708dd..ddba57f02 100644 --- a/minimisers/generalUtils/makeEmptyBayesResultsStruct.m +++ b/minimisers/generalUtils/makeEmptyBayesResultsStruct.m @@ -23,13 +23,12 @@ reflectivityIntervals = cell(nContrasts,1); reflectivityIntervalsCell = ones(5,1); - coder.varsize('reflectivityIntervalsCell',[5 1e4],[0 1]); for i = 1:nContrasts reflectivityIntervals{i} = reflectivityIntervalsCell; end + coder.varsize('reflectivityIntervals{:}',[5 1e4],[0 1]); sldIntervalsCell = ones(5,1); - coder.varsize('sldIntervalsCell',[5 1e4],[0 1]); if isDomains sldIntervals = cell(nContrasts,2); for i = 1:nContrasts @@ -42,7 +41,30 @@ sldIntervals{i} = sldIntervalsCell; end end + coder.varsize('sldIntervals{:}',[5 1e4],[0 1]); + + reflectivityXData = cell(nContrasts,1); + xDataCell = ones(1,3); + for i = 1:nContrasts + reflectivityXData{i} = xDataCell; + end + coder.varsize('reflectivityXData{:}',[1 1e4],[0 1]); + sldXDataCell = ones(1,3); + if isDomains + sldXData = cell(nContrasts,2); + for i = 1:nContrasts + sldXData{i,1} = sldXDataCell; + sldXData{i,2} = sldXDataCell; + end + else + sldXData = cell(nContrasts,1); + for i = 1:nContrasts + sldXData{i} = sldXDataCell; + end + end + coder.varsize('sldXData{:}',[1 1e4],[0 1]); + sampleChi = zeros(1,1); coder.varsize('sampleChi',[1e7 1],[1 0]); diff --git a/targetFunctions/+domainsTF/+customLayers/processCustomFunction.m b/targetFunctions/+domainsTF/+customLayers/processCustomFunction.m index e77a2fdfa..1a41478ce 100644 --- a/targetFunctions/+domainsTF/+customLayers/processCustomFunction.m +++ b/targetFunctions/+domainsTF/+customLayers/processCustomFunction.m @@ -3,34 +3,27 @@ % Top-level function for processing custom layers for all the % contrasts. - - % Do some pre-definitions to keep the compiler happy... resampledLayers = cell(numberOfContrasts,2); subRoughs = zeros(numberOfContrasts,1); - - for i = 1:numberOfContrasts - resampledLayers{i,1} = [0 0 0 0 0]; - resampledLayers{i,2} = [0 0 0 0 0]; - end - coder.varsize('resampledLayers{:}',[10000 6],[1 1]); bulkOuts = bulkOutArray(contrastBulkOuts); + for i = 1:numberOfContrasts % Choose which custom file is associated with this contrast functionHandle = customFiles{cCustFiles(i)}; % Find values of 'bulkIn' and 'bulkOut' for this - % contrast... + % contrast + thisBulkIn = bulkInArray(contrastBulkIns(i)); + thisBulkOut = bulkOuts(i); + thisContrastLayers1 = [1 1 1]; % typeDef coder.varsize('thisContrastLayers1',[10000 6],[1 1]); thisContrastLayers2 = [1 1 1]; % typeDef coder.varsize('thisContrastLayers2',[10000 6],[1 1]); - thisBulkIn = bulkInArray(contrastBulkIns(i)); - thisBulkOut = bulkOuts(i); - if isnan(str2double(functionHandle)) [thisContrastLayers1, subRoughs(i)] = callMatlabFunction(functionHandle, params, thisBulkIn, bulkOuts, i, 1); [thisContrastLayers2, ~] = callMatlabFunction(functionHandle, params, thisBulkIn, bulkOuts, i, 2); @@ -41,7 +34,7 @@ % If the output layers has 5 columns, then we need to do % the hydration correction (the user has not done it in the - % custom function). Do that here.... + % custom function). if ~useImaginary thisContrastLayers1 = applyHydrationReal(thisContrastLayers1,thisBulkIn,thisBulkOut); thisContrastLayers2 = applyHydrationReal(thisContrastLayers2,thisBulkIn,thisBulkOut); diff --git a/targetFunctions/+domainsTF/+customXY/processCustomFunction.m b/targetFunctions/+domainsTF/+customXY/processCustomFunction.m index 422fa574d..df0ee440c 100644 --- a/targetFunctions/+domainsTF/+customXY/processCustomFunction.m +++ b/targetFunctions/+domainsTF/+customXY/processCustomFunction.m @@ -3,8 +3,6 @@ % Top-level function for processing custom XY profiles for all the % contrasts. - - % Do some pre-definitions to keep the compiler happy... slds = cell(numberOfContrasts,2); subRoughs = zeros(numberOfContrasts,1); @@ -24,11 +22,11 @@ thisBulkIn = bulkInArray(contrastBulkIns(i)); if isnan(str2double(functionHandle)) - [slds{i, 1}, subRoughs(i)] = callMatlabFunction(functionHandle, params, thisBulkIn, bulkOuts, i, 1); - [slds{i, 2}, ~] = callMatlabFunction(functionHandle, params, thisBulkIn, bulkOuts, i, 2); + [slds{i,1}, subRoughs(i)] = callMatlabFunction(functionHandle, params, thisBulkIn, bulkOuts, i, 1); + [slds{i,2}, ~] = callMatlabFunction(functionHandle, params, thisBulkIn, bulkOuts, i, 2); else - [slds{i, 1}, subRoughs(i)] = callCppFunction(functionHandle, params, thisBulkIn, bulkOuts, i-1, 0); - [slds{i, 2}, ~] = callCppFunction(functionHandle, params, thisBulkIn, bulkOuts, i-1, 1); + [slds{i,1}, subRoughs(i)] = callCppFunction(functionHandle, params, thisBulkIn, bulkOuts, i-1, 0); + [slds{i,2}, ~] = callCppFunction(functionHandle, params, thisBulkIn, bulkOuts, i-1, 1); end end end diff --git a/targetFunctions/+domainsTF/customLayers.m b/targetFunctions/+domainsTF/customLayers.m index a2dd9eb15..368f13c27 100644 --- a/targetFunctions/+domainsTF/customLayers.m +++ b/targetFunctions/+domainsTF/customLayers.m @@ -1,5 +1,5 @@ -function [backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,... - resolutionParams,chis,reflectivity,simulation,shiftedData,domainLayerSlds,... +function [qzshifts,scalefactors,bulkIns,bulkOuts,... + resolutionParams,chis,reflectivity,simulation,shiftedData,backgrounds,domainLayerSlds,... domainSldProfiles,domainResampledLayers,subRoughs] = customLayers(problemStruct,problemCells,controls) % The custom layers, domainsTF reflectivity calculation. % The function extracts the relevant parameters from the input arrays, @@ -20,7 +20,7 @@ contrastResolutionParamIndices, contrastDomainRatioIndices, backgroundParamArray,... qzshiftArray, scalefactorArray, bulkInArray, bulkOutArray, resolutionParamArray,... domainRatioArray, dataPresent, nParams, params, ~, resample,... - contrastBackgroundActions, cCustFiles, useImaginary] = extractProblemParams(problemStruct); + contrastBackgroundTypes, contrastBackgroundActions, cCustFiles, useImaginary] = extractProblemParams(problemStruct); calcSld = controls.calcSldDuringFit; parallel = controls.parallel; @@ -28,39 +28,24 @@ resampleNPoints = controls.resampleNPoints; % Pre-Allocation of output arrays... - backgroundParams = zeros(numberOfContrasts,1); qzshifts = zeros(numberOfContrasts,1); scalefactors = zeros(numberOfContrasts,1); bulkIns = zeros(numberOfContrasts,1); bulkOuts = zeros(numberOfContrasts,1); resolutionParams = zeros(numberOfContrasts,1); - subRoughs = zeros(numberOfContrasts,1); chis = zeros(numberOfContrasts,1); - domainLayerSlds = cell(numberOfContrasts,2); - domainSldProfiles = cell(numberOfContrasts,2); - shiftedData = cell(numberOfContrasts,1); reflectivity = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - reflectivity{i} = [1 1; 1 1]; - end - simulation = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - simulation{i} = [1 1; 1 1]; - end - + shiftedData = cell(numberOfContrasts,1); + backgrounds = cell(numberOfContrasts,1); + domainLayerSlds = cell(numberOfContrasts,2); + domainSldProfiles = cell(numberOfContrasts,2); domainResampledLayers = cell(numberOfContrasts,2); - for i = 1:numberOfContrasts - domainResampledLayers{i,1} = [1 1 1; 1 1 1]; - domainResampledLayers{i,2} = [1 1 1; 1 1 1]; - end - - calcAllLayers = cell(numberOfContrasts,2); - for i = 1:numberOfContrasts - calcAllLayers{i,1} = [1; 1]; - calcAllLayers{i,2} = [1; 1]; - end + + layerSlds = cell(numberOfContrasts,1); + sldProfiles = cell(numberOfContrasts,1); + resampledLayers = cell(numberOfContrasts,1); calcAllLayers1 = cell(numberOfContrasts,1); for i = 1:numberOfContrasts @@ -72,21 +57,6 @@ calcAllLayers2{i} = [1; 1]; end - sldProfiles = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - sldProfiles{i} = {[1 1; 1 1],[1 1; 1 1]}; - end - - resampledLayers = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - resampledLayers{i} = {[1 1 1; 1 1 1],[1 1 1; 1 1 1]}; - end - - layerSlds = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - layerSlds{i} = {[1 1 1; 1 1 1],[1 1 1; 1 1 1]}; - end - % Process the custom models.... [calcAllLayers,subRoughs] = domainsTF.customLayers.processCustomFunction(contrastBulkInIndices,contrastBulkOutIndices,... bulkInArray,bulkOutArray,cCustFiles,numberOfContrasts,customFiles,params,useImaginary); @@ -95,24 +65,25 @@ calcAllLayers1{i} = calcAllLayers{i,1}; calcAllLayers2{i} = calcAllLayers{i,2}; end - + if strcmpi(parallel, coderEnums.parallelOptions.Contrasts) % Parallel over all contrasts parfor i = 1:numberOfContrasts - [backgroundParams(i),qzshifts(i),scalefactors(i),bulkIns(i),... + [qzshifts(i),scalefactors(i),bulkIns(i),... bulkOuts(i),resolutionParams(i),chis(i),reflectivity{i},... - simulation{i},shiftedData{i},layerSlds{i},sldProfiles{i},... + simulation{i},shiftedData{i},backgrounds{i},layerSlds{i},sldProfiles{i},... resampledLayers{i}... - ] = contrastCalculation(contrastBackgroundIndices(i),... + ] = contrastCalculation(contrastBackgroundIndices{i},... contrastQzshiftIndices(i),contrastScalefactorIndices(i),... contrastBulkInIndices(i),contrastBulkOutIndices(i),... contrastResolutionParamIndices(i),contrastDomainRatioIndices(i),... backgroundParamArray,qzshiftArray,scalefactorArray,bulkInArray,... bulkOutArray,resolutionParamArray,domainRatioArray,dataPresent(i),... data{i},dataLimits{i},simLimits{i},repeatLayers{i},... - contrastBackgroundActions(i),nParams,parallel,resampleMinAngle,resampleNPoints,... + contrastBackgroundTypes{i},contrastBackgroundActions{i}, ... + customFiles,nParams,parallel,resampleMinAngle,resampleNPoints,... useImaginary,resample(i),geometry,subRoughs(i),calcSld,... calcAllLayers1{i},calcAllLayers2{i}); @@ -122,18 +93,19 @@ for i = 1:numberOfContrasts - [backgroundParams(i),qzshifts(i),scalefactors(i),bulkIns(i),... + [qzshifts(i),scalefactors(i),bulkIns(i),... bulkOuts(i),resolutionParams(i),chis(i),reflectivity{i},... - simulation{i},shiftedData{i},layerSlds{i},sldProfiles{i},... + simulation{i},shiftedData{i},backgrounds{i},layerSlds{i},sldProfiles{i},... resampledLayers{i}... - ] = contrastCalculation(contrastBackgroundIndices(i),... + ] = contrastCalculation(contrastBackgroundIndices{i},... contrastQzshiftIndices(i),contrastScalefactorIndices(i),... contrastBulkInIndices(i),contrastBulkOutIndices(i),... contrastResolutionParamIndices(i),contrastDomainRatioIndices(i),... backgroundParamArray,qzshiftArray,scalefactorArray,bulkInArray,... bulkOutArray,resolutionParamArray,domainRatioArray,dataPresent(i),... data{i},dataLimits{i},simLimits{i},repeatLayers{i},... - contrastBackgroundActions(i),nParams,parallel,resampleMinAngle,resampleNPoints,... + contrastBackgroundTypes{i},contrastBackgroundActions{i}, ... + customFiles,nParams,parallel,resampleMinAngle,resampleNPoints,... useImaginary,resample(i),geometry,subRoughs(i),calcSld,... calcAllLayers1{i},calcAllLayers2{i}); @@ -160,13 +132,14 @@ end -function [backgroundParamValue,qzshiftValue,scalefactorValue,bulkInValue,... - bulkOutValue,resolutionParamValue,chi,reflectivity,simulation,shiftedData,... +function [qzshiftValue,scalefactorValue,bulkInValue,... + bulkOutValue,resolutionParamValue,chi,reflectivity,simulation,shiftedData,background,... layerSld,sldProfile,resampledLayer] = contrastCalculation(backgroundParamIndex,... qzshiftIndex,scalefactorIndex,bulkInIndex,bulkOutIndex,resolutionParamIndex,... domainRatioIndex,backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,... resolutionParams,domainRatios,dataPresent,data,dataLimits,simLimits,... - repeatLayers,contrastBackgroundActions,nParams,parallel,resampleMinAngle,resampleNPoints,... + repeatLayers,backgroundType,backgroundAction, ... + customFiles,nParams,parallel,resampleMinAngle,resampleNPoints,... useImaginary,resample,geometry,roughness,calcSld,calcAllLayers1,calcAllLayers2) % Get the domain ratio for this contrast @@ -179,22 +152,24 @@ % from the input arrays. % First need to decide which values of the backgrounds, scalefactors % data shifts and bulk contrasts are associated with this contrast - [backgroundParamValue,qzshiftValue,scalefactorValue,bulkInValue,bulkOutValue,... - resolutionParamValue] = backSort(backgroundParamIndex,qzshiftIndex,... + [qzshiftValue,scalefactorValue,bulkInValue,bulkOutValue,... + resolutionParamValue] = backSort(qzshiftIndex,... scalefactorIndex,bulkInIndex,bulkOutIndex,resolutionParamIndex,... - backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,resolutionParams); + qzshifts,scalefactors,bulkIns,bulkOuts,resolutionParams); + + % Apply scale factors and q shifts to the data + shiftedData = shiftData(scalefactorValue,qzshiftValue,dataPresent,data,dataLimits,simLimits); + background = constructBackground(backgroundType,backgroundParamIndex,shiftedData,customFiles,backgroundParams,simLimits); % Call the core layers calculation - need to do this once for each % domain - [sldProfile1,reflect1,simul1,shiftedData,layerSld1,resampledLayer1,~] = nonPolarisedTF.coreLayersCalculation(calcAllLayers1,roughness,... - geometry,bulkInValue,bulkOutValue,resample,calcSld,scalefactorValue,qzshiftValue,... - dataPresent,data,dataLimits,simLimits,repeatLayers,backgroundParamValue,... - resolutionParamValue,contrastBackgroundActions,nParams,parallel,resampleMinAngle,resampleNPoints,useImaginary); + [sldProfile1,reflect1,simul1,~,layerSld1,resampledLayer1,~] = nonPolarisedTF.coreLayersCalculation(calcAllLayers1,roughness,... + geometry,bulkInValue,bulkOutValue,resample,calcSld,shiftedData,simLimits,repeatLayers,... + resolutionParamValue,background,backgroundAction,nParams,parallel,resampleMinAngle,resampleNPoints,useImaginary); - [sldProfile2,reflect2,simul2,~,layerSld2,resampledLayer2,~] = nonPolarisedTF.coreLayersCalculation(calcAllLayers2,roughness,... - geometry,bulkInValue,bulkOutValue,resample,calcSld,scalefactorValue,qzshiftValue,... - dataPresent,data,dataLimits,simLimits,repeatLayers,backgroundParamValue,... - resolutionParamValue,contrastBackgroundActions,nParams,parallel,resampleMinAngle,resampleNPoints,useImaginary); + [sldProfile2,reflect2,simul2,shiftedData,layerSld2,resampledLayer2,~] = nonPolarisedTF.coreLayersCalculation(calcAllLayers2,roughness,... + geometry,bulkInValue,bulkOutValue,resample,calcSld,shiftedData,simLimits,repeatLayers,... + resolutionParamValue,background,backgroundAction,nParams,parallel,resampleMinAngle,resampleNPoints,useImaginary); % Calculate the average reflectivities.... [reflectivity,simulation] = domainsTF.averageReflectivity(reflect1,reflect2,simul1,simul2,domainRatio); diff --git a/targetFunctions/+domainsTF/customXY.m b/targetFunctions/+domainsTF/customXY.m index 1f1e34e34..fec1db558 100644 --- a/targetFunctions/+domainsTF/customXY.m +++ b/targetFunctions/+domainsTF/customXY.m @@ -1,5 +1,5 @@ -function [backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,... - resolutionParams,chis,reflectivity,simulation,shiftedData,domainLayerSlds,... +function [qzshifts,scalefactors,bulkIns,bulkOuts,... + resolutionParams,chis,reflectivity,simulation,shiftedData,backgrounds,domainLayerSlds,... domainSldProfiles,domainResampledLayers,subRoughs] = customXY(problemStruct,problemCells,controls) % Extract individual cell arrays @@ -15,47 +15,33 @@ contrastScalefactorIndices, contrastBulkInIndices, contrastBulkOutIndices,... contrastResolutionParamIndices, contrastDomainRatioIndices, backgroundParamArray,... qzshiftArray, scalefactorArray, bulkInArray, bulkOutArray, resolutionParamArray,... - domainRatioArray, dataPresent, nParams, params, ~, ~, contrastBackgroundActions,... - cCustFiles, useImaginary] = extractProblemParams(problemStruct); + domainRatioArray, dataPresent, nParams, params, ~, ~, contrastBackgroundTypes,... + contrastBackgroundActions, cCustFiles, useImaginary] = extractProblemParams(problemStruct); parallel = controls.parallel; resampleMinAngle = controls.resampleMinAngle; resampleNPoints = controls.resampleNPoints; %Pre-Allocation... - backgroundParams = zeros(numberOfContrasts,1); qzshifts = zeros(numberOfContrasts,1); scalefactors = zeros(numberOfContrasts,1); bulkIns = zeros(numberOfContrasts,1); bulkOuts = zeros(numberOfContrasts,1); resolutionParams = zeros(numberOfContrasts,1); - subRoughs = zeros(numberOfContrasts,1); chis = zeros(numberOfContrasts,1); - domainLayerSlds = cell(numberOfContrasts,2); - shiftedData = cell(numberOfContrasts,1); - - reflectivity = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - reflectivity{i} = [1 1; 1 1]; - end + reflectivity = cell(numberOfContrasts,1); simulation = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - simulation{i} = [1 1; 1 1]; - end - - domainResampledLayers = cell(numberOfContrasts,2); - for i = 1:numberOfContrasts - domainResampledLayers{i,1} = [1 1 1; 1 1 1]; - domainResampledLayers{i,2} = [1 1 1; 1 1 1]; - end - - domainSldProfiles = cell(numberOfContrasts,2); - for i = 1:numberOfContrasts - domainSldProfiles{i,1} = [1; 1]; - domainSldProfiles{i,2} = [1; 1]; - end - + shiftedData = cell(numberOfContrasts,1); + backgrounds = cell(numberOfContrasts,1); + domainLayerSlds = cell(numberOfContrasts,2); + domainSldProfiles = cell(numberOfContrasts,2); + domainResampledLayers = cell(numberOfContrasts,2); + + layerSlds = cell(numberOfContrasts,1); + sldProfiles = cell(numberOfContrasts,1); + resampledLayers = cell(numberOfContrasts,1); + inputSldProfiles1 = cell(numberOfContrasts,1); for i = 1:numberOfContrasts inputSldProfiles1{i} = [1; 1]; @@ -65,21 +51,6 @@ for i = 1:numberOfContrasts inputSldProfiles2{i} = [1; 1]; end - - sldProfiles = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - sldProfiles{i} = {[1 1; 1 1],[1 1; 1 1]}; - end - - resampledLayers = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - resampledLayers{i} = {[1 1 1; 1 1 1],[1 1 1; 1 1 1]}; - end - - layerSlds = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - layerSlds{i} = {[1 1 1; 1 1 1],[1 1 1; 1 1 1]}; - end [inputSldProfiles,subRoughs] = domainsTF.customXY.processCustomFunction(contrastBulkInIndices,contrastBulkOutIndices,... bulkInArray,bulkOutArray,cCustFiles,numberOfContrasts,customFiles,params); @@ -88,23 +59,24 @@ inputSldProfiles1{i} = inputSldProfiles{i,1}; inputSldProfiles2{i} = inputSldProfiles{i,2}; end - + if strcmpi(parallel, coderEnums.parallelOptions.Contrasts) parfor i = 1:numberOfContrasts - [backgroundParams(i),qzshifts(i),scalefactors(i),bulkIns(i),... + [qzshifts(i),scalefactors(i),bulkIns(i),... bulkOuts(i),resolutionParams(i),chis(i),reflectivity{i},... - simulation{i},shiftedData{i},layerSlds{i},sldProfiles{i},... + simulation{i},shiftedData{i},backgrounds{i},layerSlds{i},sldProfiles{i},... resampledLayers{i}... - ] = contrastCalculation(contrastBackgroundIndices(i),... + ] = contrastCalculation(contrastBackgroundIndices{i},... contrastQzshiftIndices(i),contrastScalefactorIndices(i),... contrastBulkInIndices(i),contrastBulkOutIndices(i),... contrastResolutionParamIndices(i),contrastDomainRatioIndices(i),... backgroundParamArray,qzshiftArray,scalefactorArray,bulkInArray,... bulkOutArray,resolutionParamArray,domainRatioArray,dataPresent(i),... data{i},dataLimits{i},simLimits{i},repeatLayers{i},... - contrastBackgroundActions(i),nParams,parallel,resampleMinAngle,resampleNPoints,... + contrastBackgroundTypes{i},contrastBackgroundActions{i}, ... + customFiles,nParams,parallel,resampleMinAngle,resampleNPoints,... useImaginary,subRoughs(i),inputSldProfiles1{i},inputSldProfiles2{i}); end @@ -113,18 +85,19 @@ for i = 1:numberOfContrasts - [backgroundParams(i),qzshifts(i),scalefactors(i),bulkIns(i),... + [qzshifts(i),scalefactors(i),bulkIns(i),... bulkOuts(i),resolutionParams(i),chis(i),reflectivity{i},... - simulation{i},shiftedData{i},layerSlds{i},sldProfiles{i},... + simulation{i},shiftedData{i},backgrounds{i},layerSlds{i},sldProfiles{i},... resampledLayers{i}... - ] = contrastCalculation(contrastBackgroundIndices(i),... + ] = contrastCalculation(contrastBackgroundIndices{i},... contrastQzshiftIndices(i),contrastScalefactorIndices(i),... contrastBulkInIndices(i),contrastBulkOutIndices(i),... contrastResolutionParamIndices(i),contrastDomainRatioIndices(i),... backgroundParamArray,qzshiftArray,scalefactorArray,bulkInArray,... bulkOutArray,resolutionParamArray,domainRatioArray,dataPresent(i),... data{i},dataLimits{i},simLimits{i},repeatLayers{i},... - contrastBackgroundActions(i),nParams,parallel,resampleMinAngle,resampleNPoints,... + contrastBackgroundTypes,contrastBackgroundActions{i}, ... + customFiles,nParams,parallel,resampleMinAngle,resampleNPoints,... useImaginary,subRoughs(i),inputSldProfiles1{i},inputSldProfiles2{i}); end @@ -150,13 +123,13 @@ end -function [backgroundParamValue,qzshiftValue,scalefactorValue,bulkInValue,... - bulkOutValue,resolutionParamValue,chi,reflectivity,simulation,shiftedData,... +function [qzshiftValue,scalefactorValue,bulkInValue,... + bulkOutValue,resolutionParamValue,chi,reflectivity,simulation,shiftedData,background,... layerSld,sldProfile,resampledLayer] = contrastCalculation(backgroundParamIndex,... qzshiftIndex,scalefactorIndex,bulkInIndex,bulkOutIndex,resolutionParamIndex,... domainRatioIndex,backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,... resolutionParams,domainRatios,dataPresent,data,dataLimits,simLimits,... - repeatLayers,contrastBackgroundActions,nParams,parallel,resampleMinAngle,resampleNPoints,... + repeatLayers,backgroundType,backgroundAction,customFiles,nParams,parallel,resampleMinAngle,resampleNPoints,... useImaginary,roughness,sldProfile1,sldProfile2) % Get the domain ratio for this contrast @@ -169,10 +142,10 @@ % from the input arrays. % First need to decide which values of the backgrounds, scalefactors % data shifts and bulk contrasts are associated with this contrast - [backgroundParamValue,qzshiftValue,scalefactorValue,bulkInValue,bulkOutValue,... - resolutionParamValue] = backSort(backgroundParamIndex,qzshiftIndex,... + [qzshiftValue,scalefactorValue,bulkInValue,bulkOutValue,... + resolutionParamValue] = backSort(qzshiftIndex,... scalefactorIndex,bulkInIndex,bulkOutIndex,resolutionParamIndex,... - backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,resolutionParams); + qzshifts,scalefactors,bulkIns,bulkOuts,resolutionParams); % Resample the sld profiles if ~useImaginary @@ -193,21 +166,21 @@ resampledLayer = {layerSld1, layerSld2}; sldProfile = {sldProfile1, sldProfile2}; - shiftedDat = shiftData(scalefactorValue,qzshiftValue,dataPresent,data,dataLimits,simLimits); - shiftedData = shiftedDat; + shiftedData = shiftData(scalefactorValue,qzshiftValue,dataPresent,data,dataLimits,simLimits); + background = constructBackground(backgroundType,backgroundParamIndex,shiftedData,customFiles,backgroundParams,simLimits); reflectivityType = 'standardAbeles'; - [reflect1,simul1] = callReflectivity(bulkInValue,bulkOutValue,simLimits,repeatLayers,shiftedDat,layerSld1,roughness,resolutionParamValue,parallel,reflectivityType,useImaginary); - [reflect2,simul2] = callReflectivity(bulkInValue,bulkOutValue,simLimits,repeatLayers,shiftedDat,layerSld2,roughness,resolutionParamValue,parallel,reflectivityType,useImaginary); - - [reflect1,simul1,shiftedDat] = applyBackgroundCorrection(reflect1,simul1,shiftedDat,backgroundParamValue,contrastBackgroundActions); - [reflect2,simul2,shiftedDat] = applyBackgroundCorrection(reflect2,simul2,shiftedDat,backgroundParamValue,contrastBackgroundActions); + [reflect1,simul1] = callReflectivity(bulkInValue,bulkOutValue,simLimits,repeatLayers,shiftedData,layerSld1,roughness,resolutionParamValue,parallel,reflectivityType,useImaginary); + [reflect2,simul2] = callReflectivity(bulkInValue,bulkOutValue,simLimits,repeatLayers,shiftedData,layerSld2,roughness,resolutionParamValue,parallel,reflectivityType,useImaginary); + + [reflect1,simul1,~] = applyBackgroundCorrection(reflect1,simul1,shiftedData,background,backgroundAction); + [reflect2,simul2,shiftedData] = applyBackgroundCorrection(reflect2,simul2,shiftedData,background,backgroundAction); % Calculate the average reflectivities.... [reflectivity,simulation] = domainsTF.averageReflectivity(reflect1,reflect2,simul1,simul2,domainRatio); if dataPresent - chi = chiSquared(shiftedDat,reflectivity,nParams); + chi = chiSquared(shiftedData,reflectivity,nParams); else chi = 0; end diff --git a/targetFunctions/+domainsTF/reflectivityCalculation.m b/targetFunctions/+domainsTF/reflectivityCalculation.m deleted file mode 100644 index 3c0a2bb98..000000000 --- a/targetFunctions/+domainsTF/reflectivityCalculation.m +++ /dev/null @@ -1,114 +0,0 @@ -function [contrastParams,calculationResults,reflectivity,simulation,shiftedData,layerSlds,sldProfiles,resampledLayers] = reflectivityCalculation(problemStruct,problemCells,controls) - -% Main function for the domainsTF reflectivity calculation. -% This function decides what type of model is being analysed and branches -% to the correct one. The main options are: -% -% Standard Layers - This is the equivalent of Standard Layers in RasCAL. -% Custom Layers - This is also a layers calculation, but the -% specification of the layers is done using a user -% defined function. -% Custom XY - This also has a model described by a user supplied -% function, but in this case the function generates an -% SLD profile (i.e. XY function) rather than a list of -% layers. -% -% We then decide on parallelisation options before calling the relevant -% version of the main custom layers calculation. It is more efficient to -% have multiple versions of the core calculation, each dealing with a -% different scheme for parallelisation. These are: -% -% single - single threaded reflectivity calculation. -% points - parallelise over points. -% contrasts - parallelise over contrasts. -% - -% Find out the model type from the input structs -type = problemStruct.modelType; -numberOfContrasts = problemStruct.numberOfContrasts; - -% Pre-allocation - It's necessary to pre-define the types for all the -% arrays for compilation, so do this in this block. -backgroundParams = zeros(numberOfContrasts,1); -qzshifts = zeros(numberOfContrasts,1); -scalefactors = zeros(numberOfContrasts,1); -bulkIns = zeros(numberOfContrasts,1); -bulkOuts = zeros(numberOfContrasts,1); -chis = zeros(numberOfContrasts,1); -resolutionParams = zeros(numberOfContrasts,1); -subRoughs = zeros(numberOfContrasts,1); - -% Pre-allocate the output arrays.. this is necessary because otherwise the -% compiler complains with 'Output argument <....> is not assigned on some -% execution paths' error. -reflectivity = cell(numberOfContrasts,1); -for i = 1:numberOfContrasts - reflectivity{i} = [1 1; 1 1]; -end - -simulation = cell(numberOfContrasts,1); -for i = 1:numberOfContrasts - simulation{i} = [1 1; 1 1]; -end - -shiftedData = cell(numberOfContrasts,1); -for i = 1:numberOfContrasts - shiftedData{i} = [1 1 1; 1 1 1]; -end - -layerSlds = cell(numberOfContrasts,2); -for i = 1:numberOfContrasts - layerSlds{i,1} = [1 1 1; 1 1 1]; - layerSlds{i,2} = [1 1 1; 1 1 1]; -end - -sldProfiles = cell(numberOfContrasts,2); -for i = 1:numberOfContrasts - sldProfiles{i,1} = [1 1; 1 1]; - sldProfiles{i,2} = [1 1; 1 1]; -end - -resampledLayers = cell(numberOfContrasts,2); -for i = 1:numberOfContrasts - resampledLayers{i,1} = [1 1 1; 1 1 1]; - resampledLayers{i,2} = [1 1 1; 1 1 1]; -end - -switch lower(type) - case coderEnums.modelTypes.StandardLayers - - [backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,... - resolutionParams,chis,reflectivity,simulation,shiftedData,... - layerSlds,sldProfiles,resampledLayers,... - subRoughs] = domainsTF.standardLayers(problemStruct,problemCells,controls); - - case coderEnums.modelTypes.CustomLayers - - [backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,... - resolutionParams,chis,reflectivity,simulation,shiftedData,... - layerSlds,sldProfiles,resampledLayers,... - subRoughs] = domainsTF.customLayers(problemStruct,problemCells,controls); - - case coderEnums.modelTypes.CustomXY - - [backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,... - resolutionParams,chis,reflectivity,simulation,shiftedData,... - layerSlds,sldProfiles,resampledLayers,... - subRoughs] = domainsTF.customXY(problemStruct,problemCells,controls); - otherwise - error('The model type "%s" is not supported', type); -end - -% Package everything into one array for tidy output -contrastParams.backgroundParams = backgroundParams; -contrastParams.scalefactors = scalefactors; -contrastParams.bulkIn = bulkIns; -contrastParams.bulkOut = bulkOuts; -contrastParams.resolutionParams = resolutionParams; -contrastParams.subRoughs = subRoughs; -contrastParams.resample = problemStruct.resample; - -calculationResults.chiValues = chis; -calculationResults.sumChi = sum(chis); - -end diff --git a/targetFunctions/+domainsTF/standardLayers.m b/targetFunctions/+domainsTF/standardLayers.m index 052af2346..8e899e2b2 100644 --- a/targetFunctions/+domainsTF/standardLayers.m +++ b/targetFunctions/+domainsTF/standardLayers.m @@ -1,5 +1,5 @@ -function [backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,... - resolutionParams,chis,reflectivity,simulation,shiftedData,domainLayerSlds,... +function [qzshifts,scalefactors,bulkIns,bulkOuts,... + resolutionParams,chis,reflectivity,simulation,shiftedData,backgrounds,domainLayerSlds,... domainSldProfiles,domainResampledLayers,subRoughs] = standardLayers(problemStruct,problemCells,controls) % This is the main reflectivity calculation of the standard layers % calculation type. It extracts the required parameters for the contrasts @@ -13,7 +13,8 @@ dataLimits,... simLimits,... contrastLayers,... - layersDetails,~] = parseCells(problemCells); + layersDetails,... + customFiles] = parseCells(problemCells); % Additionally extract the additional domain layers details domainContrastLayers = problemCells{19}; @@ -24,7 +25,7 @@ contrastResolutionParamIndices, contrastDomainRatioIndices, backgroundParamArray,... qzshiftArray, scalefactorArray, bulkInArray, bulkOutArray, resolutionParamArray,... domainRatioArray, dataPresent, nParams, params, ~, resample,... - contrastBackgroundActions, ~, useImaginary] = extractProblemParams(problemStruct); + contrastBackgroundTypes, contrastBackgroundActions, ~, useImaginary] = extractProblemParams(problemStruct); calcSld = controls.calcSldDuringFit; parallel = controls.parallel; @@ -32,7 +33,6 @@ resampleNPoints = controls.resampleNPoints; % Allocate the memory for the output arrays before the main loop - backgroundParams = zeros(numberOfContrasts,1); qzshifts = zeros(numberOfContrasts,1); scalefactors = zeros(numberOfContrasts,1); bulkIns = zeros(numberOfContrasts,1); @@ -40,51 +40,21 @@ resolutionParams = zeros(numberOfContrasts,1); subRoughs = zeros(numberOfContrasts,1); chis = zeros(numberOfContrasts,1); - domainLayerSlds = cell(numberOfContrasts,2); - domainSldProfiles = cell(numberOfContrasts,2); - shiftedData = cell(numberOfContrasts,1); - - reflectivity = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - reflectivity{i} = [1 1; 1 1]; - end + reflectivity = cell(numberOfContrasts,1); simulation = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - simulation{i} = [1 1; 1 1]; - end - + shiftedData = cell(numberOfContrasts,1); + backgrounds = cell(numberOfContrasts,1); + domainLayerSlds = cell(numberOfContrasts,2); + domainSldProfiles = cell(numberOfContrasts,2); domainResampledLayers = cell(numberOfContrasts,2); - for i = 1:numberOfContrasts - domainResampledLayers{i,1} = [1 1 1; 1 1 1]; - domainResampledLayers{i,2} = [1 1 1; 1 1 1]; - end - domainContrastLayers1 = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - domainContrastLayers1{i} = [1; 1]; - end + layerSlds = cell(numberOfContrasts,1); + sldProfiles = cell(numberOfContrasts,1); + resampledLayers = cell(numberOfContrasts,1); + domainContrastLayers1 = cell(numberOfContrasts,1); domainContrastLayers2 = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - domainContrastLayers2{i} = [1; 1]; - end - - sldProfiles = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - sldProfiles{i} = {[1 1; 1 1],[1 1; 1 1]}; - end - - resampledLayers = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - resampledLayers{i} = {[1 1 1; 1 1 1],[1 1 1; 1 1 1]}; - end - - layerSlds = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - layerSlds{i} = {[1 1 1; 1 1 1],[1 1 1; 1 1 1]}; - end - % end memory allocation. % First we need to allocate the absolute values of the input % parameters to all the layers in the layers list. This only needs @@ -106,18 +76,19 @@ % Loop over all the contrasts parfor i = 1:numberOfContrasts - [backgroundParams(i),qzshifts(i),scalefactors(i),bulkIns(i),... + [qzshifts(i),scalefactors(i),bulkIns(i),... bulkOuts(i),resolutionParams(i),chis(i),reflectivity{i},... - simulation{i},shiftedData{i},layerSlds{i},sldProfiles{i},... + simulation{i},shiftedData{i},backgrounds{i},layerSlds{i},sldProfiles{i},... resampledLayers{i}... - ] = contrastCalculation(contrastBackgroundIndices(i),... + ] = contrastCalculation(contrastBackgroundIndices{i},... contrastQzshiftIndices(i),contrastScalefactorIndices(i),... contrastBulkInIndices(i),contrastBulkOutIndices(i),... contrastResolutionParamIndices(i),contrastDomainRatioIndices(i),... backgroundParamArray,qzshiftArray,scalefactorArray,bulkInArray,... bulkOutArray,resolutionParamArray,domainRatioArray,dataPresent(i),... data{i},dataLimits{i},simLimits{i},repeatLayers{i},... - contrastBackgroundActions(i),nParams,parallel,resampleMinAngle,resampleNPoints,... + contrastBackgroundTypes{i},contrastBackgroundActions{i}, ... + customFiles,nParams,parallel,resampleMinAngle,resampleNPoints,... useImaginary,resample(i),geometry,subRoughs(i),calcSld,... domainContrastLayers1{i},domainContrastLayers2{i},outParameterisedLayers); @@ -128,18 +99,19 @@ % Loop over all the contrasts for i = 1:numberOfContrasts - [backgroundParams(i),qzshifts(i),scalefactors(i),bulkIns(i),... + [qzshifts(i),scalefactors(i),bulkIns(i),... bulkOuts(i),resolutionParams(i),chis(i),reflectivity{i},... - simulation{i},shiftedData{i},layerSlds{i},sldProfiles{i},... + simulation{i},shiftedData{i},backgrounds{i},layerSlds{i},sldProfiles{i},... resampledLayers{i}... - ] = contrastCalculation(contrastBackgroundIndices(i),... + ] = contrastCalculation(contrastBackgroundIndices{i},... contrastQzshiftIndices(i),contrastScalefactorIndices(i),... contrastBulkInIndices(i),contrastBulkOutIndices(i),... contrastResolutionParamIndices(i),contrastDomainRatioIndices(i),... backgroundParamArray,qzshiftArray,scalefactorArray,bulkInArray,... bulkOutArray,resolutionParamArray,domainRatioArray,dataPresent(i),... data{i},dataLimits{i},simLimits{i},repeatLayers{i},... - contrastBackgroundActions(i),nParams,parallel,resampleMinAngle,resampleNPoints,... + contrastBackgroundTypes{i},contrastBackgroundActions{i}, ... + customFiles,nParams,parallel,resampleMinAngle,resampleNPoints,... useImaginary,resample(i),geometry,subRoughs(i),calcSld,... domainContrastLayers1{i},domainContrastLayers2{i},outParameterisedLayers); @@ -166,13 +138,14 @@ end -function [backgroundParamValue,qzshiftValue,scalefactorValue,bulkInValue,... - bulkOutValue,resolutionParamValue,chi,reflectivity,simulation,shiftedData,... +function [qzshiftValue,scalefactorValue,bulkInValue,... + bulkOutValue,resolutionParamValue,chi,reflectivity,simulation,shiftedData,background,... layerSld,sldProfile,resampledLayer] = contrastCalculation(backgroundParamIndex,... qzshiftIndex,scalefactorIndex,bulkInIndex,bulkOutIndex,resolutionParamIndex,... domainRatioIndex,backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,... resolutionParams,domainRatios,dataPresent,data,dataLimits,simLimits,... - repeatLayers,contrastBackgroundActions,nParams,parallel,resampleMinAngle,resampleNPoints,... + repeatLayers,backgroundType,backgroundAction, ... + customFiles,nParams,parallel,resampleMinAngle,resampleNPoints,... useImaginary,resample,geometry,roughness,calcSld,domainContrastLayers1,... domainContrastLayers2,outParameterisedLayers) @@ -186,10 +159,14 @@ % from the input arrays. % First need to decide which values of the backgrounds, scalefactors % data shifts and bulk contrasts are associated with this contrast - [backgroundParamValue,qzshiftValue,scalefactorValue,bulkInValue,bulkOutValue,... - resolutionParamValue] = backSort(backgroundParamIndex,qzshiftIndex,... + [qzshiftValue,scalefactorValue,bulkInValue,bulkOutValue,... + resolutionParamValue] = backSort(qzshiftIndex,... scalefactorIndex,bulkInIndex,bulkOutIndex,resolutionParamIndex,... - backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,resolutionParams); + qzshifts,scalefactors,bulkIns,bulkOuts,resolutionParams); + + % Apply scale factors and q shifts to the data + shiftedData = shiftData(scalefactorValue,qzshiftValue,dataPresent,data,dataLimits,simLimits); + background = constructBackground(backgroundType,backgroundParamIndex,shiftedData,customFiles,backgroundParams,simLimits); % Also need to determine which layers from the overall layers list % are required for this contrast, and put them in the correct order @@ -199,15 +176,13 @@ % Call the core layers calculation - need to do this once for each % domain - [sldProfile1,reflect1,simul1,shiftedData,layerSld1,resampledLayer1,~] = nonPolarisedTF.coreLayersCalculation(thisContrastLayers1,roughness,... - geometry,bulkInValue,bulkOutValue,resample,calcSld,scalefactorValue,qzshiftValue,... - dataPresent,data,dataLimits,simLimits,repeatLayers,backgroundParamValue,... - resolutionParamValue,contrastBackgroundActions,nParams,parallel,resampleMinAngle,resampleNPoints,useImaginary); + [sldProfile1,reflect1,simul1,~,layerSld1,resampledLayer1,~] = nonPolarisedTF.coreLayersCalculation(thisContrastLayers1,roughness,... + geometry,bulkInValue,bulkOutValue,resample,calcSld,shiftedData,simLimits,repeatLayers,... + resolutionParamValue,background,backgroundAction,nParams,parallel,resampleMinAngle,resampleNPoints,useImaginary); - [sldProfile2,reflect2,simul2,~,layerSld2,resampledLayer2,~] = nonPolarisedTF.coreLayersCalculation(thisContrastLayers2,roughness,... - geometry,bulkInValue,bulkOutValue,resample,calcSld,scalefactorValue,qzshiftValue,... - dataPresent,data,dataLimits,simLimits,repeatLayers,backgroundParamValue,... - resolutionParamValue,contrastBackgroundActions,nParams,parallel,resampleMinAngle,resampleNPoints,useImaginary); + [sldProfile2,reflect2,simul2,shiftedData,layerSld2,resampledLayer2,~] = nonPolarisedTF.coreLayersCalculation(thisContrastLayers2,roughness,... + geometry,bulkInValue,bulkOutValue,resample,calcSld,shiftedData,simLimits,repeatLayers,... + resolutionParamValue,background,backgroundAction,nParams,parallel,resampleMinAngle,resampleNPoints,useImaginary); % Calculate the average reflectivities.... [reflectivity,simulation] = domainsTF.averageReflectivity(reflect1,reflect2,simul1,simul2,domainRatio); diff --git a/targetFunctions/+nonPolarisedTF/+customLayers/processCustomFunction.m b/targetFunctions/+nonPolarisedTF/+customLayers/processCustomFunction.m index 5f8df89c4..9a83062bf 100644 --- a/targetFunctions/+nonPolarisedTF/+customLayers/processCustomFunction.m +++ b/targetFunctions/+nonPolarisedTF/+customLayers/processCustomFunction.m @@ -3,38 +3,32 @@ % Top-level function for processing custom layers for all the % contrasts. - - % Do some pre-definitions to keep the compiler happy... resampledLayers = cell(numberOfContrasts,1); subRoughs = zeros(numberOfContrasts,1); - for i = 1:numberOfContrasts - resampledLayers{i} = [0 0 0 0 0]; - end - coder.varsize('resampledLayers{:}',[10000 6],[1 1]); - bulkOuts = bulkOutArray(contrastBulkOuts); + for i = 1:numberOfContrasts % TODO - the ambition is for parfor here, but would fail for Matlab and Python CM's.. % Choose which custom file is associated with this contrast functionHandle = customFiles{cCustFiles(i)}; % Find values of 'bulkIn' and 'bulkOut' for this - % contrast... + % contrast thisBulkIn = bulkInArray(contrastBulkIns(i)); thisBulkOut = bulkOuts(i); thisContrastLayers = [1 1 1]; % typeDef coder.varsize('thisContrastLayers',[10000 6],[1 1]); if isnan(str2double(functionHandle)) - [thisContrastLayers,subRoughs(i)] = callMatlabFunction(functionHandle, params, thisBulkIn, bulkOuts, i, 0); + [thisContrastLayers, subRoughs(i)] = callMatlabFunction(functionHandle, params, thisBulkIn, bulkOuts, i, 0); else [thisContrastLayers, subRoughs(i)] = callCppFunction(functionHandle, params, thisBulkIn, bulkOuts, i-1, -1); end % If the output layers has 5 columns, then we need to do % the hydration correction (the user has not done it in the - % custom function). Do that here.... + % custom function). if ~useImaginary thisContrastLayers = applyHydrationReal(thisContrastLayers,thisBulkIn,thisBulkOut); else diff --git a/targetFunctions/+nonPolarisedTF/+customXY/processCustomFunction.m b/targetFunctions/+nonPolarisedTF/+customXY/processCustomFunction.m index 7222bb98f..10e16d97d 100644 --- a/targetFunctions/+nonPolarisedTF/+customXY/processCustomFunction.m +++ b/targetFunctions/+nonPolarisedTF/+customXY/processCustomFunction.m @@ -3,8 +3,6 @@ % Top-level function for processing custom XY profiles for all the % contrasts. - - % Do some pre-definitions to keep the compiler happy... slds = cell(numberOfContrasts,1); subRoughs = zeros(numberOfContrasts,1); @@ -20,7 +18,7 @@ functionHandle = customFiles{cCustFiles(i)}; % Find values of 'bulkIn' and 'bulkOut' for this - % contrast... + % contrast thisBulkIn = bulkInArray(contrastBulkIns(i)); if isnan(str2double(functionHandle)) diff --git a/targetFunctions/+nonPolarisedTF/coreLayersCalculation.m b/targetFunctions/+nonPolarisedTF/coreLayersCalculation.m index 587333e8f..6cbc102e1 100644 --- a/targetFunctions/+nonPolarisedTF/coreLayersCalculation.m +++ b/targetFunctions/+nonPolarisedTF/coreLayersCalculation.m @@ -1,8 +1,7 @@ function [sldProfile,reflect,simulation,shiftedData,theseLayers,resamLayers,chiSq] = ... - coreLayersCalculation(contrastLayers, rough, ... - geometry, bulkIn, bulkOut, resample, calcSld, scalefactor, qzshift,... - dataPresent, data, dataLimits, simLimits, repeatLayers,... - background,resolution,contrastBackgroundActions,params,parallelPoints,resampleMinAngle,resampleNPoints,useImaginary) + coreLayersCalculation(layers, rough, ... + geometry, bulkIn, bulkOut, resample, calcSld, shiftedData, simLimits, repeatLayers,... + resolution,background,backgroundAction,params,parallelPoints,resampleMinAngle,resampleNPoints,useImaginary) % This is the main reflectivity calculation for all Layers models in the % non polarised target function. @@ -20,32 +19,6 @@ % 'simulation' which can be a different range to allow extrapolation. % The background correction is the applied, and finally chi-squared is % calculated. -% -% Inputs: -% contrastLayers : -% rough : -% geometry : -% bulkIn : -% bulkOut : -% resample : -% calcSld : -% scalefactor : -% qzshift : -% dataPresent : -% data : -% dataLimits : -% simLimits : -% repeatLayers : -% background : -% resol : -% contrastBackgroundActions : -% params : -% parallelPoints : -% -% Outputs: -% -% -% % Pre-definition for Coder sldProfile = [0 0]; @@ -53,9 +26,9 @@ % Build up the layers matrix for this contrast if ~useImaginary - [theseLayers, ssubs] = groupLayersMod(contrastLayers,rough,geometry,bulkIn,bulkOut); + [theseLayers, ssubs] = groupLayersMod(layers,rough,geometry,bulkIn,bulkOut); else - [theseLayers, ssubs] = groupLayersModImaginary(contrastLayers,rough,geometry,bulkIn,bulkOut); + [theseLayers, ssubs] = groupLayersModImaginary(layers,rough,geometry,bulkIn,bulkOut); end % Make the SLD profiles. @@ -68,25 +41,21 @@ % If calc SLD flag is set, then calculate the SLD profile if calcSld + thisSldLays = theseLayers; + % If we need them both, we process real and imaginary parts of the SLD - % seperately... + % separately if useImaginary thisSldLays = [theseLayers(:,1:2) theseLayers(:,4:end)]; thisSldLaysIm = [theseLayers(:,1) theseLayers(:,3:end)]; - else - thisSldLays = theseLayers; - thisSldLaysIm = [0 0]; % Dummy value for coder - end - - sldProfile = makeSLDProfiles(bulkIn,bulkOut,thisSldLays,ssubs,repeatLayers); - % If we have imaginary, we are also - % going to need an SLD profile for the imaginary part - if useImaginary % Note bulkIn and bulkOut = 0 since there is never any imaginary part for % the bulk phases.. sldProfileIm = makeSLDProfiles(0,0,thisSldLaysIm,ssubs,repeatLayers); end + + sldProfile = makeSLDProfiles(bulkIn,bulkOut,thisSldLays,ssubs,repeatLayers); + end % If required, then resample the SLD @@ -102,15 +71,12 @@ resamLayers = [0 0 0]; end -% Apply scale factors and q shifts to the data -shiftedData = shiftData(scalefactor,qzshift,dataPresent,data,dataLimits,simLimits); - % Calculate the reflectivity reflectivityType = 'standardAbeles'; [reflect,simulation] = callReflectivity(bulkIn,bulkOut,simLimits,repeatLayers,shiftedData,layerSld,ssubs,resolution,parallelPoints,reflectivityType,useImaginary); % Apply background correction -[reflect,simulation,shiftedData] = applyBackgroundCorrection(reflect,simulation,shiftedData,background,contrastBackgroundActions); +[reflect,simulation,shiftedData] = applyBackgroundCorrection(reflect,simulation,shiftedData,background,backgroundAction); % Calculate chi squared. chiSq = chiSquared(shiftedData,reflect,params); diff --git a/targetFunctions/+nonPolarisedTF/customLayers.m b/targetFunctions/+nonPolarisedTF/customLayers.m index e727e826c..287316681 100644 --- a/targetFunctions/+nonPolarisedTF/customLayers.m +++ b/targetFunctions/+nonPolarisedTF/customLayers.m @@ -1,11 +1,11 @@ -function [backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,... - resolutionParams,chis,reflectivity,simulation,shiftedData,layerSlds,... +function [qzshifts,scalefactors,bulkIns,bulkOuts,... + resolutionParams,chis,reflectivity,simulation,shiftedData,backgrounds,layerSlds,... sldProfiles,resampledLayers,subRoughs] = customLayers(problemStruct,problemCells,controls) % The custom layers, nonPolarisedTF reflectivity calculation. % The function extracts the relevant parameters from the input arrays, - % allocates these on a pre-contrast basis, then calls the 'core' - % calculation (the core layers nonPolarisedTF calc is shared between - % multiple calculation types). + % allocates these on a pre-contrast basis, then calls the + % 'coreLayersCalculation' (the core layers nonPolarisedTF calc is + % shared between multiple calculation types). % Extract individual cell arrays [repeatLayers,... @@ -19,7 +19,8 @@ contrastScalefactorIndices, contrastBulkInIndices, contrastBulkOutIndices,... contrastResolutionParamIndices, ~, backgroundParamArray, qzshiftArray,... scalefactorArray, bulkInArray, bulkOutArray, resolutionParamArray, ~,... - dataPresent, nParams, params, ~, resample, contrastBackgroundActions, cCustFiles,... + dataPresent, nParams, params, ~, resample, contrastBackgroundTypes,... + contrastBackgroundActions, cCustFiles,... useImaginary] = extractProblemParams(problemStruct); calcSld = controls.calcSldDuringFit; @@ -28,34 +29,19 @@ resampleNPoints = controls.resampleNPoints; % Pre-Allocation of output arrays... - backgroundParams = zeros(numberOfContrasts,1); qzshifts = zeros(numberOfContrasts,1); scalefactors = zeros(numberOfContrasts,1); bulkIns = zeros(numberOfContrasts,1); bulkOuts = zeros(numberOfContrasts,1); resolutionParams = zeros(numberOfContrasts,1); - subRoughs = zeros(numberOfContrasts,1); - chis = zeros(numberOfContrasts,1); - layerSlds = cell(numberOfContrasts,1); - sldProfiles = cell(numberOfContrasts,1); - shiftedData = cell(numberOfContrasts,1); - + chis = zeros(numberOfContrasts,1); + reflectivity = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - reflectivity{i} = [1 1; 1 1]; - end - simulation = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - simulation{i} = [1 1; 1 1]; - end - - resampledLayers = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - resampledLayers{i} = [1; 1]; - end - - % --- End Memory Allocation --- + shiftedData = cell(numberOfContrasts,1); + backgrounds = cell(numberOfContrasts,1); + layerSlds = cell(numberOfContrasts,1); + sldProfiles = cell(numberOfContrasts,1); % Process the custom models [resampledLayers,subRoughs] = nonPolarisedTF.customLayers.processCustomFunction(contrastBulkInIndices,contrastBulkOutIndices,... @@ -66,17 +52,18 @@ % Multi cored over all contrasts parfor i = 1:numberOfContrasts - [backgroundParams(i),qzshifts(i),scalefactors(i),bulkIns(i),... + [qzshifts(i),scalefactors(i),bulkIns(i),... bulkOuts(i),resolutionParams(i),chis(i),reflectivity{i},... - simulation{i},shiftedData{i},layerSlds{i},sldProfiles{i},... + simulation{i},shiftedData{i},backgrounds{i},layerSlds{i},sldProfiles{i},... resampledLayers{i}... - ] = contrastCalculation(contrastBackgroundIndices(i),... + ] = contrastCalculation(contrastBackgroundIndices{i},... contrastQzshiftIndices(i),contrastScalefactorIndices(i),... contrastBulkInIndices(i),contrastBulkOutIndices(i),... contrastResolutionParamIndices(i),backgroundParamArray,qzshiftArray,... scalefactorArray,bulkInArray,bulkOutArray,resolutionParamArray,... dataPresent(i),data{i},dataLimits{i},simLimits{i},repeatLayers{i},... - contrastBackgroundActions(i),nParams,parallel,resampleMinAngle,resampleNPoints,... + contrastBackgroundTypes{i},contrastBackgroundActions{i}, ... + customFiles,nParams,parallel,resampleMinAngle,resampleNPoints,... useImaginary,resample(i),geometry,subRoughs(i),calcSld,... resampledLayers{i}); @@ -87,17 +74,18 @@ % Single cored over all contrasts for i = 1:numberOfContrasts - [backgroundParams(i),qzshifts(i),scalefactors(i),bulkIns(i),... + [qzshifts(i),scalefactors(i),bulkIns(i),... bulkOuts(i),resolutionParams(i),chis(i),reflectivity{i},... - simulation{i},shiftedData{i},layerSlds{i},sldProfiles{i},... + simulation{i},shiftedData{i},backgrounds{i},layerSlds{i},sldProfiles{i},... resampledLayers{i}... - ] = contrastCalculation(contrastBackgroundIndices(i),... + ] = contrastCalculation(contrastBackgroundIndices{i},... contrastQzshiftIndices(i),contrastScalefactorIndices(i),... contrastBulkInIndices(i),contrastBulkOutIndices(i),... contrastResolutionParamIndices(i),backgroundParamArray,qzshiftArray,... scalefactorArray,bulkInArray,bulkOutArray,resolutionParamArray,... dataPresent(i),data{i},dataLimits{i},simLimits{i},repeatLayers{i},... - contrastBackgroundActions(i),nParams,parallel,resampleMinAngle,resampleNPoints,... + contrastBackgroundTypes{i},contrastBackgroundActions{i}, ... + customFiles,nParams,parallel,resampleMinAngle,resampleNPoints,... useImaginary,resample(i),geometry,subRoughs(i),calcSld,... resampledLayers{i}); @@ -108,29 +96,32 @@ end -function [backgroundParamValue,qzshiftValue,scalefactorValue,bulkInValue,... - bulkOutValue,resolutionParamValue,chi,reflectivity,simulation,shiftedData,... +function [qzshiftValue,scalefactorValue,bulkInValue,... + bulkOutValue,resolutionParamValue,chi,reflectivity,simulation,shiftedData,background,... layerSld,sldProfile,resampledLayer] = contrastCalculation(backgroundParamIndex,... qzshiftIndex,scalefactorIndex,bulkInIndex,bulkOutIndex,resolutionParamIndex,... backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,resolutionParams,... - dataPresent,data,dataLimits,simLimits,repeatLayers,contrastBackgroundActions,... - nParams,parallel,resampleMinAngle,resampleNPoints,useImaginary,resample,geometry,roughness,... + dataPresent,data,dataLimits,simLimits,repeatLayers,backgroundType,backgroundAction,... + customFiles,nParams,parallel,resampleMinAngle,resampleNPoints,useImaginary,resample,geometry,roughness,... calcSld,layer) % Extract the relevant parameter values for this contrast % from the input arrays. % First need to decide which values of the backgrounds, scalefactors % data shifts and bulk contrasts are associated with this contrast - [backgroundParamValue,qzshiftValue,scalefactorValue,bulkInValue,bulkOutValue,... - resolutionParamValue] = backSort(backgroundParamIndex,qzshiftIndex,... + [qzshiftValue,scalefactorValue,bulkInValue,bulkOutValue,... + resolutionParamValue] = backSort(qzshiftIndex,... scalefactorIndex,bulkInIndex,bulkOutIndex,resolutionParamIndex,... - backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,resolutionParams); + qzshifts,scalefactors,bulkIns,bulkOuts,resolutionParams); + % Apply scale factors and q shifts to the data + shiftedData = shiftData(scalefactorValue,qzshiftValue,dataPresent,data,dataLimits,simLimits); + background = constructBackground(backgroundType,backgroundParamIndex,shiftedData,customFiles,backgroundParams,simLimits); + % Call the core layers calculation [sldProfile,reflectivity,simulation,shiftedData,layerSld,resampledLayer,... chi] = nonPolarisedTF.coreLayersCalculation(layer,roughness,... - geometry,bulkInValue,bulkOutValue,resample,calcSld,scalefactorValue,qzshiftValue,... - dataPresent,data,dataLimits,simLimits,repeatLayers,backgroundParamValue,... - resolutionParamValue,contrastBackgroundActions,nParams,parallel,resampleMinAngle,resampleNPoints,useImaginary); + geometry,bulkInValue,bulkOutValue,resample,calcSld,shiftedData,simLimits,repeatLayers,... + resolutionParamValue,background,backgroundAction,nParams,parallel,resampleMinAngle,resampleNPoints,useImaginary); end diff --git a/targetFunctions/+nonPolarisedTF/customXY.m b/targetFunctions/+nonPolarisedTF/customXY.m index 6fc210103..2ebf6517d 100644 --- a/targetFunctions/+nonPolarisedTF/customXY.m +++ b/targetFunctions/+nonPolarisedTF/customXY.m @@ -1,5 +1,5 @@ -function [backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,... - resolutionParams,chis,reflectivity,simulation,shiftedData,layerSlds,... +function [qzshifts,scalefactors,bulkIns,bulkOuts,... + resolutionParams,chis,reflectivity,simulation,shiftedData,backgrounds,layerSlds,... sldProfiles,resampledLayers,subRoughs] = customXY(problemStruct,problemCells,controls) % Extract individual cell arrays @@ -15,7 +15,8 @@ contrastScalefactorIndices, contrastBulkInIndices, contrastBulkOutIndices,... contrastResolutionParamIndices, ~, backgroundParamArray, qzshiftArray,... scalefactorArray, bulkInArray, bulkOutArray, resolutionParamArray, ~,... - dataPresent, nParams, params, ~, ~, contrastBackgroundActions, cCustFiles,... + dataPresent, nParams, params, ~, ~, contrastBackgroundTypes,... + contrastBackgroundActions, cCustFiles,... useImaginary] = extractProblemParams(problemStruct); parallel = controls.parallel; @@ -23,36 +24,19 @@ resampleNPoints = controls.resampleNPoints; %Pre-Allocation... - backgroundParams = zeros(numberOfContrasts,1); qzshifts = zeros(numberOfContrasts,1); scalefactors = zeros(numberOfContrasts,1); bulkIns = zeros(numberOfContrasts,1); bulkOuts = zeros(numberOfContrasts,1); resolutionParams = zeros(numberOfContrasts,1); - subRoughs = zeros(numberOfContrasts,1); chis = zeros(numberOfContrasts,1); - layerSlds = cell(numberOfContrasts,1); - shiftedData = cell(numberOfContrasts,1); - - reflectivity = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - reflectivity{i} = [1 1; 1 1]; - end - + + reflectivity = cell(numberOfContrasts,1); simulation = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - simulation{i} = [1 1; 1 1]; - end - + shiftedData = cell(numberOfContrasts,1); + backgrounds = cell(numberOfContrasts,1); + layerSlds = cell(numberOfContrasts,1); resampledLayers = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - resampledLayers{i} = [1; 1]; - end - - sldProfiles = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - sldProfiles{i} = [1; 1]; - end % Process the custom models [sldProfiles,subRoughs] = nonPolarisedTF.customXY.processCustomFunction(contrastBulkInIndices,contrastBulkOutIndices,... @@ -62,17 +46,18 @@ parfor i = 1:numberOfContrasts - [backgroundParams(i),qzshifts(i),scalefactors(i),bulkIns(i),... + [qzshifts(i),scalefactors(i),bulkIns(i),... bulkOuts(i),resolutionParams(i),chis(i),reflectivity{i},... - simulation{i},shiftedData{i},layerSlds{i},sldProfiles{i},... + simulation{i},shiftedData{i},backgrounds{i},layerSlds{i},sldProfiles{i},... resampledLayers{i}... - ] = contrastCalculation(contrastBackgroundIndices(i),... + ] = contrastCalculation(contrastBackgroundIndices{i},... contrastQzshiftIndices(i),contrastScalefactorIndices(i),... contrastBulkInIndices(i),contrastBulkOutIndices(i),... contrastResolutionParamIndices(i),backgroundParamArray,qzshiftArray,... scalefactorArray,bulkInArray,bulkOutArray,resolutionParamArray,... dataPresent(i),data{i},dataLimits{i},simLimits{i},... - repeatLayers{i},contrastBackgroundActions(i),nParams,parallel,... + repeatLayers{i},contrastBackgroundTypes{i}, ... + contrastBackgroundActions{i},customFiles,nParams,parallel,... resampleMinAngle,resampleNPoints,useImaginary,subRoughs(i),sldProfiles{i}); end @@ -80,17 +65,18 @@ for i = 1:numberOfContrasts - [backgroundParams(i),qzshifts(i),scalefactors(i),bulkIns(i),... + [qzshifts(i),scalefactors(i),bulkIns(i),... bulkOuts(i),resolutionParams(i),chis(i),reflectivity{i},... - simulation{i},shiftedData{i},layerSlds{i},sldProfiles{i},... + simulation{i},shiftedData{i},backgrounds{i},layerSlds{i},sldProfiles{i},... resampledLayers{i}... - ] = contrastCalculation(contrastBackgroundIndices(i),... + ] = contrastCalculation(contrastBackgroundIndices{i},... contrastQzshiftIndices(i),contrastScalefactorIndices(i),... contrastBulkInIndices(i),contrastBulkOutIndices(i),... contrastResolutionParamIndices(i),backgroundParamArray,qzshiftArray,... scalefactorArray,bulkInArray,bulkOutArray,resolutionParamArray,... dataPresent(i),data{i},dataLimits{i},simLimits{i},... - repeatLayers{i},contrastBackgroundActions(i),nParams,parallel,... + repeatLayers{i},contrastBackgroundTypes{i}, ... + contrastBackgroundActions{i},customFiles,nParams,parallel,... resampleMinAngle,resampleNPoints,useImaginary,subRoughs(i),sldProfiles{i}); end @@ -100,22 +86,22 @@ end -function [backgroundParamValue,qzshiftValue,scalefactorValue,bulkInValue,... - bulkOutValue,resolutionParamValue,chi,reflectivity,simulation,shiftedData,... +function [qzshiftValue,scalefactorValue,bulkInValue,... + bulkOutValue,resolutionParamValue,chi,reflectivity,simulation,shiftedData,background,... layerSld,sldProfile,resampledLayer] = contrastCalculation(backgroundParamIndex,... qzshiftIndex,scalefactorIndex,bulkInIndex,bulkOutIndex,resolutionParamIndex,... backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,resolutionParams,... - dataPresent,data,dataLimits,simLimits,repeatLayers,contrastBackgroundActions,... - nParams,parallel,resampleMinAngle,resampleNPoints,useImaginary,roughness,sldProfile) + dataPresent,data,dataLimits,simLimits,repeatLayers,backgroundType,... + backgroundAction,customFiles,nParams,parallel,resampleMinAngle,resampleNPoints,useImaginary,roughness,sldProfile) % Extract the relevant parameter values for this contrast % from the input arrays. % First need to decide which values of the backgrounds, scalefactors % data shifts and bulk contrasts are associated with this contrast - [backgroundParamValue,qzshiftValue,scalefactorValue,bulkInValue,bulkOutValue,... - resolutionParamValue] = backSort(backgroundParamIndex,qzshiftIndex,... + [qzshiftValue,scalefactorValue,bulkInValue,bulkOutValue,... + resolutionParamValue] = backSort(qzshiftIndex,... scalefactorIndex,bulkInIndex,bulkOutIndex,resolutionParamIndex,... - backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,resolutionParams); + qzshifts,scalefactors,bulkIns,bulkOuts,resolutionParams); % Resample the layers if ~useImaginary @@ -128,16 +114,16 @@ resampledLayer = layerSld; - shiftedDat = shiftData(scalefactorValue,qzshiftValue,dataPresent,data,dataLimits,simLimits); - shiftedData = shiftedDat; + shiftedData = shiftData(scalefactorValue,qzshiftValue,dataPresent,data,dataLimits,simLimits); + background = constructBackground(backgroundType,backgroundParamIndex,shiftedData,customFiles,backgroundParams,simLimits); reflectivityType = 'standardAbeles'; - [reflect,simul] = callReflectivity(bulkInValue,bulkOutValue,simLimits,repeatLayers,shiftedDat,layerSld,roughness,resolutionParamValue,parallel,reflectivityType,useImaginary); - - [reflectivity,simulation,shiftedDat] = applyBackgroundCorrection(reflect,simul,shiftedDat,backgroundParamValue,contrastBackgroundActions); + [reflect,simul] = callReflectivity(bulkInValue,bulkOutValue,simLimits,repeatLayers,shiftedData,layerSld,roughness,resolutionParamValue,parallel,reflectivityType,useImaginary); + + [reflectivity,simulation,shiftedData] = applyBackgroundCorrection(reflect,simul,shiftedData,background,backgroundAction); if dataPresent - chi = chiSquared(shiftedDat,reflectivity,nParams); + chi = chiSquared(shiftedData,reflectivity,nParams); else chi = 0; end diff --git a/targetFunctions/+nonPolarisedTF/reflectivityCalculation.m b/targetFunctions/+nonPolarisedTF/reflectivityCalculation.m deleted file mode 100644 index abd3e20dc..000000000 --- a/targetFunctions/+nonPolarisedTF/reflectivityCalculation.m +++ /dev/null @@ -1,111 +0,0 @@ -function [contrastParams,calculationResults,reflectivity,simulation,shiftedData,layerSlds,sldProfiles,resampledLayers] = reflectivityCalculation(problemStruct,problemCells,controls) - -% Main function for the nonPolarisedTF reflectivity calculation. -% This function decides what type of model is being analysed and branches -% to the correct one. The main options are: -% -% Standard Layers - This is the equivalent of Standard Layers in RasCAL. -% Custom Layers - This is also a layers calculation, but the -% specification of the layers is done using a user -% defined function. -% Custom XY - This also has a model described by a user supplied -% function, but in this case the function generates an -% SLD profile (i.e. XY function) rather than a list of -% layers. -% -% We then decide on parallelisation options before calling the relevant -% version of the main custom layers calculation. It is more efficient to -% have multiple versions of the core calculation, each dealing with a -% different scheme for parallelisation. These are: -% -% single - single threaded reflectivity calculation. -% points - parallelise over points. -% contrasts - parallelise over contrasts. -% - -% Find out the model type from the input structs -type = problemStruct.modelType; -numberOfContrasts = problemStruct.numberOfContrasts; - -% Pre-allocation - It's necessary to pre-define the types for all the -% arrays for compilation, so do this in this block. -backgroundParams = zeros(numberOfContrasts,1); -qzshifts = zeros(numberOfContrasts,1); -scalefactors = zeros(numberOfContrasts,1); -bulkIns = zeros(numberOfContrasts,1); -bulkOuts = zeros(numberOfContrasts,1); -chis = zeros(numberOfContrasts,1); -resolutionParams = zeros(numberOfContrasts,1); -subRoughs = zeros(numberOfContrasts,1); - -% Pre-allocate the output arrays. This is necessary because otherwise the -% compiler complains with 'Output argument <....> is not assigned on some -% execution paths' error. -reflectivity = cell(numberOfContrasts,1); -for i = 1:numberOfContrasts - reflectivity{i} = [1 1; 1 1]; -end - -simulation = cell(numberOfContrasts,1); -for i = 1:numberOfContrasts - simulation{i} = [1 1; 1 1]; -end - -shiftedData = cell(numberOfContrasts,1); -for i = 1:numberOfContrasts - shiftedData{i} = [1 1 1; 1 1 1]; -end - -layerSlds = cell(numberOfContrasts,1); -for i = 1:numberOfContrasts - layerSlds{i} = [1 1 1; 1 1 1]; -end - -sldProfiles = cell(numberOfContrasts,1); -for i = 1:numberOfContrasts - sldProfiles{i} = [1 1; 1 1]; -end - -resampledLayers = cell(numberOfContrasts,1); -for i = 1:numberOfContrasts - resampledLayers{i} = [1 1 1; 1 1 1]; -end - -switch lower(type) - case coderEnums.modelTypes.StandardLayers - - [backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,... - resolutionParams,chis,reflectivity,simulation,shiftedData,... - layerSlds,sldProfiles,resampledLayers,... - subRoughs] = nonPolarisedTF.standardLayers(problemStruct,problemCells,controls); - - case coderEnums.modelTypes.CustomLayers - - [backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,... - resolutionParams,chis,reflectivity,simulation,shiftedData,... - layerSlds,sldProfiles,resampledLayers,... - subRoughs] = nonPolarisedTF.customLayers(problemStruct,problemCells,controls); - - case coderEnums.modelTypes.CustomXY - - [backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,... - resolutionParams,chis,reflectivity,simulation,shiftedData,... - layerSlds,sldProfiles,resampledLayers,... - subRoughs] = nonPolarisedTF.customXY(problemStruct,problemCells,controls); - otherwise - error('The model type "%s" is not supported', type); -end - -% Package everything into structs for tidy output -contrastParams.backgroundParams = backgroundParams; -contrastParams.scalefactors = scalefactors; -contrastParams.bulkIn = bulkIns; -contrastParams.bulkOut = bulkOuts; -contrastParams.resolutionParams = resolutionParams; -contrastParams.subRoughs = subRoughs; -contrastParams.resample = problemStruct.resample; - -calculationResults.chiValues = chis; -calculationResults.sumChi = sum(chis); - -end diff --git a/targetFunctions/+nonPolarisedTF/standardLayers.m b/targetFunctions/+nonPolarisedTF/standardLayers.m index e8abc56ca..11e3916c9 100644 --- a/targetFunctions/+nonPolarisedTF/standardLayers.m +++ b/targetFunctions/+nonPolarisedTF/standardLayers.m @@ -1,10 +1,10 @@ -function [backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,... - resolutionParams,chis,reflectivity,simulation,shiftedData,layerSlds,... - sldProfiles,resampledLayers,subRoughs] = standardLayers(problemStruct,problemCells,controls) +function [qzshifts,scalefactors,bulkIns,bulkOuts,... + resolutionParams,chis,reflectivity,simulation,shiftedData,backgrounds,... + layerSlds,sldProfiles,resampledLayers,subRoughs] = standardLayers(problemStruct,problemCells,controls) % This is the main reflectivity calculation of the standard layers % calculation type. It extracts the required parameters for the contrasts % from the input arrays, then passes the main calculation to - % 'standardLayersCore', which carries out the calculation iteself. + % 'coreLayersCalculation', which carries out the calculation itself. % The core calculation is common for both standard and custom layers. % Extract individual cell arrays @@ -13,14 +13,16 @@ dataLimits,... simLimits,... contrastLayers,... - layersDetails,~] = parseCells(problemCells); + layersDetails,... + customFiles] = parseCells(problemCells); % Extract individual parameters from problemStruct [numberOfContrasts, geometry, contrastBackgroundIndices, contrastQzshiftIndices,... contrastScalefactorIndices, contrastBulkInIndices, contrastBulkOutIndices,... contrastResolutionParamIndices, ~, backgroundParamArray, qzshiftArray,... scalefactorArray, bulkInArray, bulkOutArray, resolutionParamArray, ~,... - dataPresent, nParams, params, ~, resample, contrastBackgroundActions, ~,... + dataPresent, nParams, params, ~, resample, contrastBackgroundTypes,... + contrastBackgroundActions, ~,... useImaginary] = extractProblemParams(problemStruct); calcSld = controls.calcSldDuringFit; @@ -29,33 +31,21 @@ resampleNPoints = controls.resampleNPoints; % Allocate the memory for the output arrays before the main loop - backgroundParams = zeros(numberOfContrasts,1); qzshifts = zeros(numberOfContrasts,1); scalefactors = zeros(numberOfContrasts,1); bulkIns = zeros(numberOfContrasts,1); bulkOuts = zeros(numberOfContrasts,1); resolutionParams = zeros(numberOfContrasts,1); - subRoughs = zeros(numberOfContrasts,1); chis = zeros(numberOfContrasts,1); - layerSlds = cell(numberOfContrasts,1); - sldProfiles = cell(numberOfContrasts,1); - shiftedData = cell(numberOfContrasts,1); - - reflectivity = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - reflectivity{i} = [1 1; 1 1]; - end + subRoughs = zeros(numberOfContrasts,1); + reflectivity = cell(numberOfContrasts,1); simulation = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - simulation{i} = [1 1; 1 1]; - end - + shiftedData = cell(numberOfContrasts,1); + backgrounds = cell(numberOfContrasts,1); + layerSlds = cell(numberOfContrasts,1); + sldProfiles = cell(numberOfContrasts,1); resampledLayers = cell(numberOfContrasts,1); - for i = 1:numberOfContrasts - resampledLayers{i} = [1 1 1; 1 1 1]; - end - % end memory allocation % First we need to allocate the absolute values of the input % parameters to all the layers in the layers list. This only needs @@ -72,17 +62,18 @@ % Loop over all the contrasts parfor i = 1:numberOfContrasts - [backgroundParams(i),qzshifts(i),scalefactors(i),bulkIns(i),... + [qzshifts(i),scalefactors(i),bulkIns(i),... bulkOuts(i),resolutionParams(i),chis(i),reflectivity{i},... - simulation{i},shiftedData{i},layerSlds{i},sldProfiles{i},... - resampledLayers{i}... - ] = contrastCalculation(contrastBackgroundIndices(i),... + simulation{i},shiftedData{i},backgrounds{i},layerSlds{i},... + sldProfiles{i},resampledLayers{i}... + ] = contrastCalculation(contrastBackgroundIndices{i},... contrastQzshiftIndices(i),contrastScalefactorIndices(i),... - contrastBulkInIndices(i),contrastBulkOutIndices(i), ... + contrastBulkInIndices(i),contrastBulkOutIndices(i),... contrastResolutionParamIndices(i),backgroundParamArray,qzshiftArray,... scalefactorArray,bulkInArray,bulkOutArray,resolutionParamArray,... dataPresent(i),data{i},dataLimits{i},simLimits{i},repeatLayers{i},... - contrastBackgroundActions(i),nParams,parallel,resampleMinAngle,resampleNPoints,... + contrastBackgroundTypes{i},contrastBackgroundActions{i},... + customFiles,nParams,parallel,resampleMinAngle,resampleNPoints,... useImaginary,resample(i),geometry,subRoughs(i),calcSld,... contrastLayers{i},outParameterisedLayers); @@ -93,55 +84,57 @@ % Loop over all the contrasts for i = 1:numberOfContrasts - [backgroundParams(i),qzshifts(i),scalefactors(i),bulkIns(i),... + [qzshifts(i),scalefactors(i),bulkIns(i),... bulkOuts(i),resolutionParams(i),chis(i),reflectivity{i},... - simulation{i},shiftedData{i},layerSlds{i},sldProfiles{i},... - resampledLayers{i}... - ] = contrastCalculation(contrastBackgroundIndices(i),... + simulation{i},shiftedData{i},backgrounds{i},layerSlds{i},... + sldProfiles{i},resampledLayers{i}... + ] = contrastCalculation(contrastBackgroundIndices{i},... contrastQzshiftIndices(i),contrastScalefactorIndices(i),... - contrastBulkInIndices(i),contrastBulkOutIndices(i), ... - contrastResolutionParamIndices(i),backgroundParamArray,qzshiftArray,... + contrastBulkInIndices(i),contrastBulkOutIndices(i),... + contrastResolutionParamIndices(i),backgroundParamArray,qzshiftArray, ... scalefactorArray,bulkInArray,bulkOutArray,resolutionParamArray,... dataPresent(i),data{i},dataLimits{i},simLimits{i},repeatLayers{i},... - contrastBackgroundActions(i),nParams,parallel,resampleMinAngle,resampleNPoints,... + contrastBackgroundTypes{i},contrastBackgroundActions{i},... + customFiles,nParams,parallel,resampleMinAngle,resampleNPoints,... useImaginary,resample(i),geometry,subRoughs(i),calcSld,... contrastLayers{i},outParameterisedLayers); end - end - end -function [backgroundParamValue,qzshiftValue,scalefactorValue,bulkInValue,... - bulkOutValue,resolutionParamValue,chi,reflectivity,simulation,shiftedData,... +function [qzshiftValue,scalefactorValue,bulkInValue,... + bulkOutValue,resolutionParamValue,chi,reflectivity,simulation,shiftedData,background,... layerSld,sldProfile,resampledLayer] = contrastCalculation(backgroundParamIndex,... qzshiftIndex,scalefactorIndex,bulkInIndex,bulkOutIndex,resolutionParamIndex,... backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,resolutionParams,... - dataPresent,data,dataLimits,simLimits,repeatLayers,contrastBackgroundActions,... - nParams,parallel,resampleMinAngle,resampleNPoints,useImaginary,resample,geometry,roughness,... + dataPresent,data,dataLimits,simLimits,repeatLayers,backgroundType,backgroundAction,... + customFiles,nParams,parallel,resampleMinAngle,resampleNPoints,useImaginary,resample,geometry,roughness,... calcSld,contrastLayers,outParameterisedLayers) % Extract the relevant parameter values for this contrast % from the input arrays. % First need to decide which values of the backgrounds, scalefactors % data shifts and bulk contrasts are associated with this contrast - [backgroundParamValue,qzshiftValue,scalefactorValue,bulkInValue,bulkOutValue,... - resolutionParamValue] = backSort(backgroundParamIndex,qzshiftIndex,... + [qzshiftValue,scalefactorValue,bulkInValue,bulkOutValue,... + resolutionParamValue] = backSort(qzshiftIndex,... scalefactorIndex,bulkInIndex,bulkOutIndex,resolutionParamIndex,... - backgroundParams,qzshifts,scalefactors,bulkIns,bulkOuts,resolutionParams); + qzshifts,scalefactors,bulkIns,bulkOuts,resolutionParams); % Also need to determine which layers from the overall layers list % are required for this contrast, and put them in the correct order % according to geometry thisContrastLayers = allocateLayersForContrast(contrastLayers,outParameterisedLayers,useImaginary); - + + % Apply scale factors and q shifts to the data + shiftedData = shiftData(scalefactorValue,qzshiftValue,dataPresent,data,dataLimits,simLimits); + background = constructBackground(backgroundType,backgroundParamIndex,shiftedData,customFiles,backgroundParams,simLimits); + % Call the core layers calculation [sldProfile,reflectivity,simulation,shiftedData,layerSld,resampledLayer,... chi] = nonPolarisedTF.coreLayersCalculation(thisContrastLayers,roughness,... - geometry,bulkInValue,bulkOutValue,resample,calcSld,scalefactorValue,qzshiftValue,... - dataPresent,data,dataLimits,simLimits,repeatLayers,backgroundParamValue,... - resolutionParamValue,contrastBackgroundActions,nParams,parallel,resampleMinAngle,resampleNPoints,useImaginary); + geometry,bulkInValue,bulkOutValue,resample,calcSld,shiftedData,simLimits,repeatLayers,... + resolutionParamValue,background,backgroundAction,nParams,parallel,resampleMinAngle,resampleNPoints,useImaginary); end diff --git a/targetFunctions/common/backSort.m b/targetFunctions/common/backSort.m index e86320970..08adc689a 100644 --- a/targetFunctions/common/backSort.m +++ b/targetFunctions/common/backSort.m @@ -1,18 +1,12 @@ -function [outBackgroundParam,outQzshift,outScalefactor,outBulkIn,outBulkOut,outResolutionParam] = backSort(contrastBackgroundParams,contrastQzshifts,contrastScalefactors,contrastBulkIns,contrastBulkOuts,contrastResolutionParams,backgroundParams,qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams) +function [outQzshift,outScalefactor,outBulkIn,outBulkOut,outResolutionParam] = backSort(contrastQzshifts,contrastScalefactors,contrastBulkIns,contrastBulkOuts,contrastResolutionParams,qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams) % Distributes the background and shift values among the different contrasts % - % USAGE:: - % - % [backgroundParams,qzshift,scalefactor,bulkIn,bulkOut,resolutionParams] = backsort(contrastBackgrounds,contrastQzshifts,contrastScalefactors,contrastBulkIns,contrastBulkOuts,contrastResolutions,backs,qzshifts,scalefactor,bulkIn,bulkOut,res) - % % INPUTS: - % * contrastBackgroundParams: Which background value is associated with each contrast % * contrastQzshifts: Which qz_shift value is associated with each contrast % * contrastScalefactors: Which scalefactor value is associated with each contrast % * contrastBulkIns: Which BulkIn value is associated with each contrast % * contrastBulkOuts: Which BulkOut value is associated with each contrast % * contrastResolutionParams: Which resolution value is associated with each contrast - % * backgroundParams: List of all background parameter values. % * qzshifts: List of all qzshift values % * scalefactors: List of all scalefactor values % * bulkIn: List of all bulkIn values @@ -20,19 +14,12 @@ % * resolutionParams: List of all resolution parameter values % % OUTPUTS: - % * outBackground: list of actual background parameter values for each contrast % * outQzshift: list of actual qzshift values for each contrast % * outScalefactor: list of actual scalefactor values for each contrast % * outBulkIn: list of actual bulkIn values for each contrast % * outBulkOut: list of actual bulkOut values for each contrast % * outResolution: list of actual resolution parameter for each contrast - if contrastBackgroundParams ~= -1 - outBackgroundParam = backgroundParams(contrastBackgroundParams); - else - outBackgroundParam = -1; % Negative value means we have a data background. - end - outQzshift = qzshifts(contrastQzshifts); outScalefactor = scalefactors(contrastScalefactors); diff --git a/targetFunctions/common/callReflectivity/applyBackgroundCorrection.m b/targetFunctions/common/callReflectivity/applyBackgroundCorrection.m index dda94da14..a00a58017 100644 --- a/targetFunctions/common/callReflectivity/applyBackgroundCorrection.m +++ b/targetFunctions/common/callReflectivity/applyBackgroundCorrection.m @@ -1,16 +1,30 @@ -function [reflect,simul,shiftedData] = applyBackgroundCorrection(reflect,simul,shiftedData,backgroundParams,contrastBackgroundActions) +function [reflectivity,simulation,outputData] = applyBackgroundCorrection(reflectivity,simulation,shiftedData,background,backgroundAction) -switch contrastBackgroundActions - case 1 - %Add background to the simulation - reflect(:,2) = reflect(:,2) + backgroundParams; - simul(:,2) = simul(:,2) + backgroundParams; - case 2 - %Subtract the background from the data.. - shiftedData(:,2) = shiftedData(:,2) - backgroundParams; - %shiftedData(:,3) = shiftedData(:,3) - backgroundParams; +% Find where the data range lies within the simulation range +lowXVals = find(simulation(:,1) == shiftedData(1,1)); +highXVals = find(simulation(:,1) == shiftedData(end,1)); + +lowIndex = lowXVals(1); +highIndex = highXVals(end); + +% Reduce ranges here - background is defined over the simulation range +backData = background(lowIndex:highIndex,2); +backError = background(lowIndex:highIndex,3); + +switch backgroundAction + case coderEnums.actions.Add + % Add the data to the simulation + reflectivity(:,2) = reflectivity(:,2) + backData; + simulation(:,2) = simulation(:,2) + background(:,2); + case coderEnums.actions.Subtract + % Subtract the background data from the shiftedData + shiftedData(:,2) = shiftedData(:,2) - backData; + shiftedData(:,3) = sqrt(shiftedData(:,3).^2 + backError.^2); % Propagate the errors otherwise - error('The index "%d" does not represent a valid contrast background action.', contrastBackgroundActions); + error('"%s" does not represent a valid contrast background action.', backgroundAction); end - + +% Reduce data to original three columns +outputData = shiftedData(:,1:3); + end diff --git a/targetFunctions/common/callReflectivity/callReflectivity.m b/targetFunctions/common/callReflectivity/callReflectivity.m index de549fdf0..4353eb234 100644 --- a/targetFunctions/common/callReflectivity/callReflectivity.m +++ b/targetFunctions/common/callReflectivity/callReflectivity.m @@ -1,7 +1,4 @@ -function [reflectivity, simulation] = callReflectivity(bulkIn,bulkOut,simLimits,repeatLayers,thisData,layers,ssubs,resolution,parallel,refType,useImaginary) - -xdata = thisData(:,1); - +function [reflectivity, simulation] = callReflectivity(bulkIn,bulkOut,simLimits,repeatLayers,data,layers,ssubs,resolution,parallel,refType,useImaginary) repeatFlag = repeatLayers(1); if repeatFlag @@ -10,9 +7,8 @@ nRepeats = 1; end - % Build the input arrays for thick, sld and rough..... - + if isempty(layers) % No layers defined. Make a zeros dummy zero layer layers = [0 bulkIn 0]; @@ -51,41 +47,21 @@ slds(end) = complex(bulkOut, eps); roughs(end) = ssubs; -simXLo = simLimits(1); -simXHi = simLimits(2); -middleSection = thisData(:,1); -split = [0 0]; - -if simXLo < xdata(1) - step = (xdata(2)-xdata(1)); - firstSection = simXLo:step:(xdata(1)-step); -else - firstSection = ones(1,0); -end - -if simXHi > xdata(end) - step = (xdata(end)-xdata(end-1,1)); - lastSection = xdata(end,1)+step:step:simXHi; -else - lastSection = ones(1,0); -end - -simXdata = [firstSection(:) ; middleSection(:) ; lastSection(:)]; -splits = [(length(firstSection)+1) ((length(firstSection))+length(middleSection))]; +[simulationXData, dataIndices] = makeSimulationRange(data, simLimits); -simulation = zeros(length(simXdata),2); -simulation(:,1) = simXdata; +simulation = zeros(length(simulationXData),2); +simulation(:,1) = simulationXData; % If we are using data resolutions, then we also need to adjust the length % of the resolution column. We do this by just extending with the resolution % values at the ends of the curve. simResolData = 0; if resolution == -1 - thisDataResol = thisData(:,4); + thisDataResol = data(:,4); minVal = thisDataResol(1); maxVal = thisDataResol(end); - startResol = ones((length(firstSection)),1) .* minVal; - endResol = ones((length(lastSection)),1) .* maxVal; + startResol = ones((dataIndices(1)-1),1) .* minVal; + endResol = ones((length(simulationXData)-dataIndices(2)),1) .* maxVal; simResolData = [startResol(:) ; thisDataResol(:) ; endResol(:)]; end @@ -96,30 +72,30 @@ % Parallelise over points % Calculate reflectivity.... - simRef = abelesParallelPoints(simXdata,nLayersTot,thicks,slds,roughs); + simRef = abelesParallelPoints(simulationXData,nLayersTot,thicks,slds,roughs); % Apply resolution % Note: paraPoints gives an error during validation, so use % single cored resolution as a workaround for now. if resolution == -1 %simRef = dataResolutionPollyParallelPoints(simXdata,simRef,simResolData,length(simXdata)); - simRef = dataResolutionPolly(simXdata,simRef,simResolData,length(simXdata)); + simRef = dataResolutionPolly(simulationXData,simRef,simResolData,length(simulationXData)); else %simRef = resolutionPollyParallelPoints(simXdata,simRef,res,length(simXdata)); - simRef = resolutionPolly(simXdata,simRef,resolution,length(simXdata)); + simRef = resolutionPolly(simulationXData,simRef,resolution,length(simulationXData)); end otherwise % Single cored over points % Calculate reflectivity..... - simRef = abelesSingle(simXdata,nLayersTot,thicks,slds,roughs); + simRef = abelesSingle(simulationXData,nLayersTot,thicks,slds,roughs); % Apply resolution correction... if resolution == -1 - simRef = dataResolutionPolly(simXdata,simRef,simResolData,length(simXdata)); + simRef = dataResolutionPolly(simulationXData,simRef,simResolData,length(simulationXData)); else - simRef = resolutionPolly(simXdata,simRef,resolution,length(simXdata)); + simRef = resolutionPolly(simulationXData,simRef,resolution,length(simulationXData)); end end otherwise @@ -127,6 +103,6 @@ end simulation(:,2) = simRef(:); -reflectivity = simulation(splits(1):splits(2),:); +reflectivity = simulation(dataIndices(1):dataIndices(2),:); end diff --git a/targetFunctions/common/constructBackground.m b/targetFunctions/common/constructBackground.m new file mode 100644 index 000000000..b13c6466f --- /dev/null +++ b/targetFunctions/common/constructBackground.m @@ -0,0 +1,64 @@ +function background = constructBackground(backgroundType,backgroundParamIndices,shiftedData,customFiles,backgroundParamArray,simLimits) + +% Apply background parameters to the background. +% +% For function backgrounds, this means running the function using the +% defined parameters. For data and constant backgrounds, this means taking +% any predefined background data and adding any supplied poarameters. + +% Define the background over the simulation range, making sure to include +% any predefined data. +[simulationXData, dataIndices] = makeSimulationRange(shiftedData, simLimits); + +background = zeros(length(simulationXData),3); +background(:,1) = simulationXData; +background(dataIndices(1):dataIndices(2),2) = shiftedData(:,5); +background(dataIndices(1):dataIndices(2),3) = shiftedData(:,6); + +if strcmpi(backgroundType, coderEnums.allowedTypes.Function) + + % For a function background, the first index is actually that of the + % custom function + funcName = customFiles{backgroundParamIndices(1)}; + + % The rest of the backgroundParamIndices are indicies to + % backgroundParams + funcBackParams = backgroundParamIndices(2:end); + + % Make an array of real params + paramsArray = zeros(1,length(funcBackParams)); + for i = 1:length(funcBackParams) + paramsArray(i) = backgroundParamArray(funcBackParams(i)); + end + + % Evaluate the background function with these params... + thisBackground = zeros(length(background(:,2)), 1); % This is the correct type - for compilation + + if isnan(str2double(funcName)) + if coder.target('MATLAB') + fileHandle = str2func(funcName); + thisBackground = fileHandle(background(:,1), paramsArray); + elseif coder.target('MEX') + % 'feval' generates an automatic coder.extrinsic call. + thisBackground = feval(funcName, background(:,1), paramsArray); + end + else + error('Background functions in languages other than MATLAB are not supported.'); + end + + background(:,2) = background(:,2) + thisBackground; + +else + + % We have either a constant background, or a data background with an + % optional offset. In either case we add the parameter to column 5 of + % the data. Hence we expect to run either zero or one iterations + % of this loop. + for i = 1:length(backgroundParamIndices) + backgroundParameter = backgroundParamArray(backgroundParamIndices(i)); + background(:,2) = background(:,2) + backgroundParameter; + end + +end + +end diff --git a/targetFunctions/common/customModelFunctions/callCppFunction.m b/targetFunctions/common/customModelFunctions/callCppFunction.m index 329d7b468..3bd1abe34 100644 --- a/targetFunctions/common/customModelFunctions/callCppFunction.m +++ b/targetFunctions/common/customModelFunctions/callCppFunction.m @@ -35,7 +35,6 @@ coder.wref(outputSize), coder.wref(subRough)); end - size = int32(outputSize(1) * outputSize(2)); tempOutput = zeros(1, size); actualSize = 0; diff --git a/targetFunctions/common/customModelFunctions/callMatlabFunction.m b/targetFunctions/common/customModelFunctions/callMatlabFunction.m index 474ef7102..15e1d935f 100644 --- a/targetFunctions/common/customModelFunctions/callMatlabFunction.m +++ b/targetFunctions/common/customModelFunctions/callMatlabFunction.m @@ -21,4 +21,4 @@ sRough = 0; output = zeros([0 0]); error("This is not supported!"); -end \ No newline at end of file +end diff --git a/targetFunctions/common/extractProblemParams.m b/targetFunctions/common/extractProblemParams.m index 6cb2e1be3..b6846135a 100644 --- a/targetFunctions/common/extractProblemParams.m +++ b/targetFunctions/common/extractProblemParams.m @@ -1,12 +1,13 @@ function [numberOfContrasts, geometry, contrastBackgroundParams, contrastQzshifts, contrastScalefactors, contrastBulkIns, contrastBulkOuts,... contrastResolutionParams, contrastDomainRatios, backgroundParams, qzshifts, scalefactors, bulkIn, bulkOut, resolutionParams, domainRatio,... -dataPresent, nParams, params, numberOfLayers, resample, contrastBackgroundActions, contrastCustomFiles, useImaginary] = extractProblemParams(problemStruct) +dataPresent, nParams, params, numberOfLayers, resample, contrastBackgroundTypes, contrastBackgroundActions, contrastCustomFiles, useImaginary] = extractProblemParams(problemStruct) %Extract individual parameters from problem numberOfContrasts = problemStruct.numberOfContrasts; geometry = problemStruct.geometry; contrastBackgroundParams = problemStruct.contrastBackgroundParams; +contrastBackgroundTypes = problemStruct.contrastBackgroundTypes; contrastBackgroundActions = problemStruct.contrastBackgroundActions; contrastQzshifts = problemStruct.contrastQzshifts; contrastScalefactors = problemStruct.contrastScalefactors; diff --git a/targetFunctions/common/makeSimulationRange.m b/targetFunctions/common/makeSimulationRange.m new file mode 100644 index 000000000..bb4a97d4f --- /dev/null +++ b/targetFunctions/common/makeSimulationRange.m @@ -0,0 +1,27 @@ +function [simXdata, splits] = makeSimulationRange(data, simulationLimits) +% Construct the x data for the simulation. This consists of the x data from +% the supplied data, plus additional points above and below the data range +% as necessary. + +lowSimLimit = simulationLimits(1); +highSimLimit = simulationLimits(2); +xData = data(:,1); + +if lowSimLimit < xData(1) + step = (xData(2)-xData(1)); + firstSection = lowSimLimit:step:(xData(1)-step); +else + firstSection = ones(1,0); +end + +if highSimLimit > xData(end) + step = (xData(end)-xData(end-1,1)); + lastSection = xData(end,1)+step:step:highSimLimit; +else + lastSection = ones(1,0); +end + +simXdata = [firstSection(:); xData(:); lastSection(:)]; +splits = [(length(firstSection)+1) ((length(firstSection))+length(xData))]; + +end diff --git a/targetFunctions/common/shiftData.m b/targetFunctions/common/shiftData.m index 7300038ce..02cc0a943 100644 --- a/targetFunctions/common/shiftData.m +++ b/targetFunctions/common/shiftData.m @@ -49,8 +49,9 @@ simLo = simLimits(1); simHi = simLimits(2); simXData = linspace(simLo,simHi,simPoints); - simYData = zeros(length(simXData),1); - shiftedData = [simXData(:) simYData(:) simYData(:)]; + shiftedData = zeros(length(simXData),6); + shiftedData(:, 1) = linspace(simLo,simHi,simPoints); + +end end - \ No newline at end of file diff --git a/targetFunctions/reflectivityCalculation.m b/targetFunctions/reflectivityCalculation.m index 944356f25..02e4ad14c 100644 --- a/targetFunctions/reflectivityCalculation.m +++ b/targetFunctions/reflectivityCalculation.m @@ -16,121 +16,103 @@ % * magnetic - Target function for cases for polarised neutrons with polarisation analysis. % -% For compilation, we have to preallocate memory for the output structs -numberOfContrasts = problemStruct.numberOfContrasts; -preAlloc = zeros(numberOfContrasts,1); - -contrastParams = struct('backgroundParams',preAlloc,... - 'scalefactors',preAlloc,... - 'bulkIn',preAlloc,... - 'bulkOut',preAlloc,... - 'resolutionParams',preAlloc,... - 'subRoughs',preAlloc,... - 'resample',preAlloc); - -calculationResults = struct('chiValues',preAlloc,'sumChi',0); - -% We also fill the results arrays to define their type and size. -reflectivity = cell(numberOfContrasts,1); -for i = 1:numberOfContrasts - reflectivity{i} = [1 1; 1 1]; -end -coder.varsize('reflectivity{:}',[10000 2],[1 0]); - -simulation = cell(numberOfContrasts,1); -for i = 1:numberOfContrasts - simulation{i} = [1 1; 1 1]; -end -coder.varsize('simulation{:}',[10000 2],[1 0]); - -shiftedData = cell(numberOfContrasts,1); -for i = 1:numberOfContrasts - shiftedData{i} = [1 1 1; 1 1 1]; -end -coder.varsize('shiftedData{:}',[10000 3],[1 0]); - -layerSlds = cell(numberOfContrasts,1); -for i = 1:numberOfContrasts - layerSlds{i} = [1 1 1; 1 1 1]; -end -coder.varsize('layerSlds{:}',[10000 6],[1 1]); - -domainLayerSlds = cell(numberOfContrasts,2); -for i = 1:numberOfContrasts - domainLayerSlds{i,1} = [1 1 1; 1 1 1]; - domainLayerSlds{i,2} = [1 1 1; 1 1 1]; -end -coder.varsize('domainLayerSlds{:}',[10000 6],[1 1]); - -sldProfiles = cell(numberOfContrasts,1); -for i = 1:numberOfContrasts - sldProfiles{i,1} = [1 1; 1 1]; -end -coder.varsize('sldProfiles{:}',[10000 2],[1 0]); - -domainSldProfiles = cell(numberOfContrasts,2); -for i = 1:numberOfContrasts - domainSldProfiles{i,1} = [1 1; 1 1]; - domainSldProfiles{i,2} = [1 1; 1 1]; -end -coder.varsize('domainSldProfiles{:}',[10000 2],[1 0]); - -resampledLayers = cell(numberOfContrasts,1); -for i = 1:numberOfContrasts - resampledLayers{i} = [1 1 1; 1 1 1]; -end -coder.varsize('resampledLayers{:}',[10000 3],[1 0]); - -domainResampledLayers = cell(numberOfContrasts,2); -for i = 1:numberOfContrasts - domainResampledLayers{i,1} = [1 1 1; 1 1 1]; - domainResampledLayers{i,2} = [1 1 1; 1 1 1]; -end -coder.varsize('domainResampledLayers{:}',[10000 3],[1 0]); - % Decide which target function we are calling and call the relevant routines -whichTF = problemStruct.TF; -switch whichTF - case coderEnums.calculationTypes.NonPolarised - [contrastParams,calculationResults,reflectivity,simulation,shiftedData,layerSlds,sldProfiles,resampledLayers] = nonPolarisedTF.reflectivityCalculation(problemStruct,problemCells,controls); +targetFunction = problemStruct.TF; +modelType = problemStruct.modelType; + +switch targetFunction + case coderEnums.calculationTypes.NonPolarised + + switch lower(modelType) + + case coderEnums.modelTypes.StandardLayers + + [qzshifts,scalefactors,bulkIns,bulkOuts,... + resolutionParams,chis,reflectivity,simulation,shiftedData,... + backgrounds,layerSlds,sldProfiles,resampledLayers,... + subRoughs] = nonPolarisedTF.standardLayers(problemStruct,problemCells,controls); + + case coderEnums.modelTypes.CustomLayers + + [qzshifts,scalefactors,bulkIns,bulkOuts,... + resolutionParams,chis,reflectivity,simulation,shiftedData,... + backgrounds,layerSlds,sldProfiles,resampledLayers,... + subRoughs] = nonPolarisedTF.customLayers(problemStruct,problemCells,controls); + + case coderEnums.modelTypes.CustomXY + + [qzshifts,scalefactors,bulkIns,bulkOuts,... + resolutionParams,chis,reflectivity,simulation,shiftedData,... + backgrounds,layerSlds,sldProfiles,resampledLayers,... + subRoughs] = nonPolarisedTF.customXY(problemStruct,problemCells,controls); + + otherwise + error('The model type "%s" is not supported', modelType); + end + %case coderEnums.calculationTypes.OilWater %contrastParams = oilWaterTFReflectivityCalculation(problemStruct,problemCells,controls); %case coderEnums.calculationTypes.Magnetic %contrastParams = polarisedTFReflectivityCalculation(problemStruct,problemCells,controls); - case coderEnums.calculationTypes.Domains - [contrastParams,calculationResults,reflectivity,simulation,shiftedData,domainLayerSlds,domainSldProfiles,domainResampledLayers] = domainsTF.reflectivityCalculation(problemStruct,problemCells,controls); - otherwise - error('The calculation type "%s" is not supported', whichTF); - -end - -% Make the result struct -result.reflectivity = reflectivity; -result.simulation = simulation; -result.shiftedData = shiftedData; -% The size of this array now varies depending on TF -switch whichTF case coderEnums.calculationTypes.Domains - result.layerSlds = domainLayerSlds; - result.sldProfiles = domainSldProfiles; - result.resampledLayers = domainResampledLayers; + switch lower(modelType) + + case coderEnums.modelTypes.StandardLayers + + [qzshifts,scalefactors,bulkIns,bulkOuts,... + resolutionParams,chis,reflectivity,simulation,shiftedData,... + backgrounds,layerSlds,sldProfiles,resampledLayers,... + subRoughs] = domainsTF.standardLayers(problemStruct,problemCells,controls); + + case coderEnums.modelTypes.CustomLayers + + [qzshifts,scalefactors,bulkIns,bulkOuts,... + resolutionParams,chis,reflectivity,simulation,shiftedData,... + backgrounds,layerSlds,sldProfiles,resampledLayers,... + subRoughs] = domainsTF.customLayers(problemStruct,problemCells,controls); + + case coderEnums.modelTypes.CustomXY + + [qzshifts,scalefactors,bulkIns,bulkOuts,... + resolutionParams,chis,reflectivity,simulation,shiftedData,... + backgrounds,layerSlds,sldProfiles,resampledLayers,... + subRoughs] = domainsTF.customXY(problemStruct,problemCells,controls); + + otherwise + error('The model type "%s" is not supported', modelType); + end otherwise + error('The calculation type "%s" is not supported', targetFunction); +end - result.layerSlds = layerSlds; - result.sldProfiles = sldProfiles; - result.resampledLayers = resampledLayers; +% Make the result struct +calculationResults.chiValues = chis; +calculationResults.sumChi = sum(chis); -end +contrastParams.scalefactors = scalefactors; +contrastParams.bulkIn = bulkIns; +contrastParams.bulkOut = bulkOuts; +contrastParams.resolutionParams = resolutionParams; +contrastParams.subRoughs = subRoughs; +contrastParams.resample = problemStruct.resample; -% Complete the result struct -[~,fitNames] = packParams(problemStruct,problemCells,problemLimits,controls.checks); +result.reflectivity = reflectivity; +result.simulation = simulation; +result.shiftedData = shiftedData; +result.backgrounds = backgrounds; +result.layerSlds = layerSlds; +result.sldProfiles = sldProfiles; +result.resampledLayers = resampledLayers; result.calculationResults = calculationResults; result.contrastParams = contrastParams; + result.fitParams = problemStruct.fitParams; + +[~,fitNames] = packParams(problemStruct,problemCells,problemLimits,controls.checks); result.fitNames = fitNames; end diff --git a/tests/domainsTFReflectivityCalculation/domainsCustomLayers.m b/tests/domainsTFReflectivityCalculation/domainsCustomLayers.m index 3f438c3cc..adb4dd849 100644 --- a/tests/domainsTFReflectivityCalculation/domainsCustomLayers.m +++ b/tests/domainsTFReflectivityCalculation/domainsCustomLayers.m @@ -25,6 +25,7 @@ project.addContrast('name', 'D2O Conrast', ... 'Data', 'Simulation',... 'Background', 'Background 1',... + 'backgroundAction', actions.Add,... 'bulkIn', 'Silicon',... 'bulkOut', 'SLD D2O',... 'Scalefactor','Scalefactor 1', ... diff --git a/tests/domainsTFReflectivityCalculation/domainsCustomLayersInputs.mat b/tests/domainsTFReflectivityCalculation/domainsCustomLayersInputs.mat index fbe0a93f9..cb5d3df4e 100644 Binary files a/tests/domainsTFReflectivityCalculation/domainsCustomLayersInputs.mat and b/tests/domainsTFReflectivityCalculation/domainsCustomLayersInputs.mat differ diff --git a/tests/domainsTFReflectivityCalculation/domainsCustomLayersOutputs.mat b/tests/domainsTFReflectivityCalculation/domainsCustomLayersOutputs.mat index 278a9ee90..b6c3e3d77 100644 Binary files a/tests/domainsTFReflectivityCalculation/domainsCustomLayersOutputs.mat and b/tests/domainsTFReflectivityCalculation/domainsCustomLayersOutputs.mat differ diff --git a/tests/domainsTFReflectivityCalculation/domainsCustomLayersTFParams.mat b/tests/domainsTFReflectivityCalculation/domainsCustomLayersTFParams.mat index b853b90d4..6a762519c 100644 Binary files a/tests/domainsTFReflectivityCalculation/domainsCustomLayersTFParams.mat and b/tests/domainsTFReflectivityCalculation/domainsCustomLayersTFParams.mat differ diff --git a/tests/domainsTFReflectivityCalculation/domainsCustomXY.m b/tests/domainsTFReflectivityCalculation/domainsCustomXY.m index db8bf694e..e35351a7d 100644 --- a/tests/domainsTFReflectivityCalculation/domainsCustomXY.m +++ b/tests/domainsTFReflectivityCalculation/domainsCustomXY.m @@ -22,7 +22,7 @@ project.addBackground('Background SMW','constant','Backs par SMW'); project.addBackground('Background H2O','constant','Backs par H2O'); - project.setBackground(1,'name','Background D2O', 'value1','Backs par D2O'); + project.setBackground(1,'name','Background D2O', 'source','Backs par D2O'); % Finally modify some of the other parameters to be more suitable values % for a solid / liquid experiment. @@ -39,6 +39,7 @@ project.addContrast('name','Test',... 'background','Background D2O',... + 'backgroundAction', actions.Add,... 'resolution','Resolution 1',... 'scalefactor', 'Scalefactor 1',... 'bulkIn', 'Air',.... diff --git a/tests/domainsTFReflectivityCalculation/domainsCustomXYInputs.mat b/tests/domainsTFReflectivityCalculation/domainsCustomXYInputs.mat index bba3db928..575751edc 100644 Binary files a/tests/domainsTFReflectivityCalculation/domainsCustomXYInputs.mat and b/tests/domainsTFReflectivityCalculation/domainsCustomXYInputs.mat differ diff --git a/tests/domainsTFReflectivityCalculation/domainsCustomXYOutputs.mat b/tests/domainsTFReflectivityCalculation/domainsCustomXYOutputs.mat index f3a99f1e4..efb937718 100644 Binary files a/tests/domainsTFReflectivityCalculation/domainsCustomXYOutputs.mat and b/tests/domainsTFReflectivityCalculation/domainsCustomXYOutputs.mat differ diff --git a/tests/domainsTFReflectivityCalculation/domainsCustomXYTFParams.mat b/tests/domainsTFReflectivityCalculation/domainsCustomXYTFParams.mat index d96e0cb98..b08c9df4f 100644 Binary files a/tests/domainsTFReflectivityCalculation/domainsCustomXYTFParams.mat and b/tests/domainsTFReflectivityCalculation/domainsCustomXYTFParams.mat differ diff --git a/tests/domainsTFReflectivityCalculation/domainsStandardLayers.m b/tests/domainsTFReflectivityCalculation/domainsStandardLayers.m index 65b7b00f6..34fb7674d 100644 --- a/tests/domainsTFReflectivityCalculation/domainsStandardLayers.m +++ b/tests/domainsTFReflectivityCalculation/domainsStandardLayers.m @@ -41,6 +41,7 @@ project.addContrast('name','Domain Test',... 'background','Background 1',... + 'backgroundAction', actions.Add,... 'resolution','Resolution 1',... 'scalefactor', 'Scalefactor 1',... 'resample',false,... diff --git a/tests/domainsTFReflectivityCalculation/domainsStandardLayersInputs.mat b/tests/domainsTFReflectivityCalculation/domainsStandardLayersInputs.mat index de8a7bad6..b8fb6da8a 100644 Binary files a/tests/domainsTFReflectivityCalculation/domainsStandardLayersInputs.mat and b/tests/domainsTFReflectivityCalculation/domainsStandardLayersInputs.mat differ diff --git a/tests/domainsTFReflectivityCalculation/domainsStandardLayersOutputs.mat b/tests/domainsTFReflectivityCalculation/domainsStandardLayersOutputs.mat index 5635ba233..293f6485e 100644 Binary files a/tests/domainsTFReflectivityCalculation/domainsStandardLayersOutputs.mat and b/tests/domainsTFReflectivityCalculation/domainsStandardLayersOutputs.mat differ diff --git a/tests/domainsTFReflectivityCalculation/domainsStandardLayersTFParams.mat b/tests/domainsTFReflectivityCalculation/domainsStandardLayersTFParams.mat index 94a77386b..9fa63c9bd 100644 Binary files a/tests/domainsTFReflectivityCalculation/domainsStandardLayersTFParams.mat and b/tests/domainsTFReflectivityCalculation/domainsStandardLayersTFParams.mat differ diff --git a/tests/domainsTFReflectivityCalculation/makeDomainsInputsAndOutputs.m b/tests/domainsTFReflectivityCalculation/makeDomainsInputsAndOutputs.m index ecc230c70..6f82e506e 100644 --- a/tests/domainsTFReflectivityCalculation/makeDomainsInputsAndOutputs.m +++ b/tests/domainsTFReflectivityCalculation/makeDomainsInputsAndOutputs.m @@ -43,22 +43,10 @@ save([root filesep 'tests/domainsTFReflectivityCalculation/domainsStandardLayersOutputs'],'outputs'); % (c) TF Parameters -[contrastParams,calculationResults,reflectivity,simulation,shiftedData,layerSlds,sldProfiles,resampledLayers] = domainsTF.reflectivityCalculation(problemStruct,problemCells,controls); - -TFParams.contrastParams = contrastParams; -TFParams.calculationResults = calculationResults; -TFParams.reflectivity = reflectivity; -TFParams.simulation = simulation; -TFParams.shiftedData = shiftedData; -TFParams.layerSlds = layerSlds; -TFParams.sldProfiles = sldProfiles; -TFParams.resampledLayers = resampledLayers; - -[backgroundParams,qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,... - chis,reflectivity,simulation,shiftedData,layerSlds,sldProfiles,... +[qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,... + chis,reflectivity,simulation,shiftedData,backgrounds,layerSlds,sldProfiles,... resampledLayers,subRoughs] = domainsTF.standardLayers(problemStruct,problemCells,controls); -TFParams.backgroundParams = backgroundParams; TFParams.qzshifts = qzshifts; TFParams.scalefactors = scalefactors; TFParams.bulkIn = bulkIn; @@ -67,6 +55,14 @@ TFParams.chis = chis; TFParams.subRoughs = subRoughs; +TFParams.reflectivity = reflectivity; +TFParams.simulation = simulation; +TFParams.shiftedData = shiftedData; +TFParams.backgrounds = backgrounds; +TFParams.layerSlds = layerSlds; +TFParams.sldProfiles = sldProfiles; +TFParams.resampledLayers = resampledLayers; + save([root filesep 'tests/domainsTFReflectivityCalculation/domainsStandardLayersTFParams'],'TFParams'); %% 2. Custom XY. @@ -108,22 +104,10 @@ save([root filesep 'tests/domainsTFReflectivityCalculation/domainsCustomXYOutputs'],'outputs'); % (c) TF Parameters -[contrastParams,calculationResults,reflectivity,simulation,shiftedData,layerSlds,sldProfiles,resampledLayers] = domainsTF.reflectivityCalculation(problemStruct,problemCells,controls); - -TFParams.contrastParams = contrastParams; -TFParams.calculationResults = calculationResults; -TFParams.reflectivity = reflectivity; -TFParams.simulation = simulation; -TFParams.shiftedData = shiftedData; -TFParams.layerSlds = layerSlds; -TFParams.sldProfiles = sldProfiles; -TFParams.resampledLayers = resampledLayers; - -[backgroundParams,qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,... - chis,reflectivity,simulation,shiftedData,layerSlds,sldProfiles,... +[qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,... + chis,reflectivity,simulation,shiftedData,backgrounds,layerSlds,sldProfiles,... resampledLayers,subRoughs] = domainsTF.customXY(problemStruct,problemCells,controls); -TFParams.backgroundParams = backgroundParams; TFParams.qzshifts = qzshifts; TFParams.scalefactors = scalefactors; TFParams.bulkIn = bulkIn; @@ -132,6 +116,14 @@ TFParams.chis = chis; TFParams.subRoughs = subRoughs; +TFParams.reflectivity = reflectivity; +TFParams.simulation = simulation; +TFParams.shiftedData = shiftedData; +TFParams.backgrounds = backgrounds; +TFParams.layerSlds = layerSlds; +TFParams.sldProfiles = sldProfiles; +TFParams.resampledLayers = resampledLayers; + save([root filesep 'tests/domainsTFReflectivityCalculation/domainsCustomXYTFParams'],'TFParams'); %% 3. Custom Layers. @@ -172,22 +164,10 @@ save([root filesep 'tests/domainsTFReflectivityCalculation/domainsCustomLayersOutputs'],'outputs'); % (c) TF Parameters -[contrastParams,calculationResults,reflectivity,simulation,shiftedData,layerSlds,sldProfiles,resampledLayers] = domainsTF.reflectivityCalculation(problemStruct,problemCells,controls); - -TFParams.contrastParams = contrastParams; -TFParams.calculationResults = calculationResults; -TFParams.reflectivity = reflectivity; -TFParams.simulation = simulation; -TFParams.shiftedData = shiftedData; -TFParams.layerSlds = layerSlds; -TFParams.sldProfiles = sldProfiles; -TFParams.resampledLayers = resampledLayers; - -[backgroundParams,qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,... - chis,reflectivity,simulation,shiftedData,layerSlds,sldProfiles,... +[qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,... + chis,reflectivity,simulation,shiftedData,backgrounds,layerSlds,sldProfiles,... resampledLayers,subRoughs] = domainsTF.customLayers(problemStruct,problemCells,controls); -TFParams.backgrounds = backgroundParams; TFParams.qzshifts = qzshifts; TFParams.scalefactors = scalefactors; TFParams.bulkIn = bulkIn; @@ -196,4 +176,12 @@ TFParams.chis = chis; TFParams.subRoughs = subRoughs; +TFParams.reflectivity = reflectivity; +TFParams.simulation = simulation; +TFParams.shiftedData = shiftedData; +TFParams.backgrounds = backgrounds; +TFParams.layerSlds = layerSlds; +TFParams.sldProfiles = sldProfiles; +TFParams.resampledLayers = resampledLayers; + save([root filesep 'tests/domainsTFReflectivityCalculation/domainsCustomLayersTFParams'],'TFParams'); diff --git a/tests/domainsTFReflectivityCalculation/testDomainsReflectivityCalculations.m b/tests/domainsTFReflectivityCalculation/testDomainsReflectivityCalculations.m index 66dba4584..d3b597fe0 100644 --- a/tests/domainsTFReflectivityCalculation/testDomainsReflectivityCalculations.m +++ b/tests/domainsTFReflectivityCalculation/testDomainsReflectivityCalculations.m @@ -39,15 +39,13 @@ expectedResultStruct % Expected output value of the initial results struct expectedResult % Expected output value of the final results struct expectedBayesResults % Expected output value of the bayes results struct - TFContrastParams - TFCalculationResults TFReflectivity TFSimulation TFShiftedData + TFBackgrounds TFLayerSLDs TFSLDProfiles TFResampledLayers - TFBackgroundParams TFQzshifts TFScalefactors TFBulkIn @@ -94,16 +92,14 @@ function loadTestDataOutputs(testCase, outputsFile) function loadTFParams(testCase, TFFile) testCase.TFParams = load(TFFile); - testCase.TFContrastParams = testCase.TFParams.TFParams.contrastParams; - testCase.TFCalculationResults = testCase.TFParams.TFParams.calculationResults; testCase.TFReflectivity = testCase.TFParams.TFParams.reflectivity; testCase.TFSimulation = testCase.TFParams.TFParams.simulation; testCase.TFShiftedData = testCase.TFParams.TFParams.shiftedData; + testCase.TFBackgrounds = testCase.TFParams.TFParams.backgrounds; testCase.TFLayerSLDs = testCase.TFParams.TFParams.layerSlds; testCase.TFSLDProfiles = testCase.TFParams.TFParams.sldProfiles; testCase.TFResampledLayers = testCase.TFParams.TFParams.resampledLayers; - testCase.TFBackgroundParams = testCase.TFParams.TFParams.backgroundParams; testCase.TFQzshifts = testCase.TFParams.TFParams.qzshifts; testCase.TFScalefactors = testCase.TFParams.TFParams.scalefactors; testCase.TFBulkIn = testCase.TFParams.TFParams.bulkIn; @@ -160,43 +156,29 @@ function testReflectivityCalculation(testCase, whichParallel, useCompiled) testCase.verifyEqual(result, testCase.expectedResultStruct, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); end - function testDomainsTFReflectivityCalculation(testCase) - [contrastParams, calculationResults, reflectivity, simulation, shiftedData, layerSLDs, SLDProfiles, resampledLayers] = domainsTF.reflectivityCalculation(testCase.problemStruct, testCase.problemCells, testCase.controls); - - testCase.verifyEqual(contrastParams, testCase.TFContrastParams, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); - testCase.verifyEqual(calculationResults, testCase.TFCalculationResults, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); - testCase.verifyEqual(reflectivity, testCase.TFReflectivity, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); - testCase.verifyEqual(simulation, testCase.TFSimulation, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); - testCase.verifyEqual(shiftedData, testCase.TFShiftedData, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); - testCase.verifyEqual(layerSLDs, testCase.TFLayerSLDs, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); - testCase.verifyEqual(SLDProfiles, testCase.TFSLDProfiles, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); - testCase.verifyEqual(resampledLayers, testCase.TFResampledLayers, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); - end - - function testDomainsTFLayersReflectivityCalculation(testCase, whichParallel, TFFile) + function testDomainsTFReflectivityCalculation(testCase, whichParallel, TFFile) testCase.controls.parallel = whichParallel; % Choose the appropriate routine for each test case switch TFFile case 'domainsStandardLayersTFParams.mat' - [backgroundParams,qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,chis,reflectivity,... - simulation,shiftedData,layerSLDs,SLDProfiles,resampledLayers,... + [qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,chis,reflectivity,... + simulation,shiftedData,backgrounds,layerSLDs,SLDProfiles,resampledLayers,... subRoughs] = domainsTF.standardLayers(testCase.problemStruct,testCase.problemCells,... testCase.controls); case 'domainsCustomLayersTFParams.mat' - [backgroundParams,qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,chis,reflectivity,... - simulation,shiftedData,layerSLDs,SLDProfiles,resampledLayers,... + [qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,chis,reflectivity,... + simulation,shiftedData,backgrounds,layerSLDs,SLDProfiles,resampledLayers,... subRoughs] = domainsTF.customLayers(testCase.problemStruct,testCase.problemCells,... testCase.controls); case 'domainsCustomXYTFParams.mat' - [backgroundParams,qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,chis,reflectivity,... - simulation,shiftedData,layerSLDs,SLDProfiles,resampledLayers,... + [qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,chis,reflectivity,... + simulation,shiftedData,backgrounds,layerSLDs,SLDProfiles,resampledLayers,... subRoughs] = domainsTF.customXY(testCase.problemStruct,testCase.problemCells,... testCase.controls); end - testCase.verifyEqual(backgroundParams, testCase.TFBackgroundParams, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(qzshifts, testCase.TFQzshifts, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(scalefactors, testCase.TFScalefactors, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(bulkIn, testCase.TFBulkIn, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); @@ -206,6 +188,7 @@ function testDomainsTFLayersReflectivityCalculation(testCase, whichParallel, TFF testCase.verifyEqual(reflectivity, testCase.TFReflectivity, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(simulation, testCase.TFSimulation, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(shiftedData, testCase.TFShiftedData, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); + testCase.verifyEqual(backgrounds, testCase.TFBackgrounds, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(layerSLDs, testCase.TFLayerSLDs, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(SLDProfiles, testCase.TFSLDProfiles, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(resampledLayers, testCase.TFResampledLayers, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); @@ -228,63 +211,70 @@ function testCheckIndices(testCase) % Test standard input passes testInput = testCase.problemStruct; - checkIndices(testInput); + customFiles = testCase.problemCells{14}; + checkIndices(testInput, customFiles); - % Test Background Param Error + % Test Background Param Error - commented out at present testInput = testCase.problemStruct; - testInput.contrastBackgroundParams(1) = 0; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testInput.contrastBackgroundParams{1} = 0; + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); + testInput = testCase.problemStruct; + testInput.contrastBackgroundParams{1} = 4; + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); + + testInput.contrastBackgroundParams{1} = [0 1 2 3]; + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); testInput = testCase.problemStruct; - testInput.contrastBackgroundParams(1) = 4; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testInput.contrastBackgroundParams{1} = [4 1 2 3]; + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); % Test Qzshift Error testInput = testCase.problemStruct; testInput.contrastQzshifts(1) = 0; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); testInput = testCase.problemStruct; testInput.contrastQzshifts(1) = 4; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); % Test Scalefactor Error testInput = testCase.problemStruct; testInput.contrastScalefactors(1) = 0; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); testInput = testCase.problemStruct; testInput.contrastScalefactors(1) = 4; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); % Test Bulk In Error testInput = testCase.problemStruct; testInput.contrastBulkIns(1) = 0; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); testInput = testCase.problemStruct; testInput.contrastBulkIns(1) = 4; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); % Test Bulk Out Error testInput = testCase.problemStruct; testInput.contrastBulkOuts(1) = 0; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); testInput = testCase.problemStruct; testInput.contrastBulkOuts(1) = 4; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); % Test Resolution Param Error testInput = testCase.problemStruct; testInput.contrastResolutionParams(1) = 0; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); testInput = testCase.problemStruct; testInput.contrastResolutionParams(1) = 4; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); % Test Domain Ratio Error testInput = testCase.problemStruct; testInput.contrastDomainRatios(1) = 0; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); testInput = testCase.problemStruct; testInput.contrastDomainRatios(1) = 4; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); end @@ -303,7 +293,7 @@ function testParseCells(testCase) function testExtractProblemParams(testCase) [numberOfContrasts, geometry, contrastBackgroundParams, contrastQzshifts, contrastScalefactors, contrastBulkIns, contrastBulkOuts,... contrastResolutionParams, contrastDomainRatios, backgroundParams, qzshifts, scalefactors, bulkIn, bulkOut, resolutionParams, domainRatio,... - dataPresent, nParams, params, numberOfLayers, resample, backgroundParamsType, contrastCustomFiles, useImaginary] = extractProblemParams(testCase.problemStruct); + dataPresent, nParams, params, numberOfLayers, resample, backgroundTypes, backgroundActions, contrastCustomFiles, useImaginary] = extractProblemParams(testCase.problemStruct); testCase.verifyEqual(numberOfContrasts, testCase.problemStruct.numberOfContrasts, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(geometry, testCase.problemStruct.geometry, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); @@ -326,7 +316,8 @@ function testExtractProblemParams(testCase) testCase.verifyEqual(params, testCase.problemStruct.params, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(numberOfLayers, testCase.problemStruct.numberOfLayers, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(resample, testCase.problemStruct.resample, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); - testCase.verifyEqual(backgroundParamsType, testCase.problemStruct.contrastBackgroundActions, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); + testCase.verifyEqual(backgroundTypes, testCase.problemStruct.contrastBackgroundTypes, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); + testCase.verifyEqual(backgroundActions, testCase.problemStruct.contrastBackgroundActions, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(contrastCustomFiles, testCase.problemStruct.contrastCustomFiles, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(useImaginary, testCase.problemStruct.useImaginary, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); end diff --git a/tests/nonPolarisedTFReflectivityCalculation/DPPCCustomXYScript.m b/tests/nonPolarisedTFReflectivityCalculation/DPPCCustomXYScript.m index b0d499c4d..0c11267a9 100644 --- a/tests/nonPolarisedTFReflectivityCalculation/DPPCCustomXYScript.m +++ b/tests/nonPolarisedTFReflectivityCalculation/DPPCCustomXYScript.m @@ -52,7 +52,7 @@ project.addBackground('Background H2O','constant','Backs par H2O'); % And edit the other one.... -project.setBackground(1,'name','Background D2O','Value1','Backs par D2O'); +project.setBackground(1,'name','Background D2O','source','Backs par D2O'); % Set the scalefactor... project.setScalefactor(1,'Value',1,'min',0.5,'max',2,'fit',true); @@ -63,6 +63,7 @@ % D2O contrast.. project.addContrast('name','Bilayer / D2O',... 'background','Background D2O',... + 'backgroundAction', actions.Add,... 'resolution','Resolution 1',... 'scalefactor', 'Scalefactor 1',... 'bulkIn', 'Silicon',... @@ -72,6 +73,7 @@ % SMW contrast.. project.addContrast('name','Bilayer / SMW',... 'background','Background SMW',... + 'backgroundAction', actions.Add,... 'resolution','Resolution 1',... 'scalefactor', 'Scalefactor 1',... 'bulkIn', 'Silicon',... @@ -81,6 +83,7 @@ % SMW contrast.. project.addContrast('name','Bilayer / H2O',... 'background','Background H2O',... + 'backgroundAction', actions.Add,... 'resolution','Resolution 1',... 'scalefactor', 'Scalefactor 1',... 'bulkIn', 'Silicon',... diff --git a/tests/nonPolarisedTFReflectivityCalculation/DPPCStandardLayers.m b/tests/nonPolarisedTFReflectivityCalculation/DPPCStandardLayers.m index 9345a3603..b99922da3 100644 --- a/tests/nonPolarisedTFReflectivityCalculation/DPPCStandardLayers.m +++ b/tests/nonPolarisedTFReflectivityCalculation/DPPCStandardLayers.m @@ -176,7 +176,7 @@ project.addBackground('Background H2O','constant','Backs par H2O'); % And edit the other one.... -project.setBackground(1,'name','Background D2O','Value1','Backs par D2O'); +project.setBackground(1,'name','Background D2O','source','Backs par D2O'); % Finally modify some of the other parameters to be more suitable values % for a solid / liquid experiment. @@ -193,6 +193,7 @@ % D2O contrast.. project.addContrast('name','Bilayer / D2O',... 'background','Background D2O',... + 'backgroundAction', actions.Add,... 'resolution','Resolution 1',... 'scalefactor', 'Scalefactor 1',... 'resample',false,.... @@ -203,6 +204,7 @@ % SMW contrast.. project.addContrast('name','Bilayer / SMW',... 'background','Background SMW',... + 'backgroundAction', actions.Add,... 'resolution','Resolution 1',... 'scalefactor', 'Scalefactor 1',... 'resample',false,.... @@ -213,6 +215,7 @@ % SMW contrast.. project.addContrast('name','Bilayer / H2O',... 'background','Background H2O',... + 'backgroundAction', actions.Add,... 'resolution','Resolution 1',... 'scalefactor', 'Scalefactor 1',... 'resample',false,... diff --git a/tests/nonPolarisedTFReflectivityCalculation/customLayersInputs.mat b/tests/nonPolarisedTFReflectivityCalculation/customLayersInputs.mat index 72559b4ef..4f84b8782 100644 Binary files a/tests/nonPolarisedTFReflectivityCalculation/customLayersInputs.mat and b/tests/nonPolarisedTFReflectivityCalculation/customLayersInputs.mat differ diff --git a/tests/nonPolarisedTFReflectivityCalculation/customLayersOutputs.mat b/tests/nonPolarisedTFReflectivityCalculation/customLayersOutputs.mat index ef3aefc27..f28ce6e5f 100644 Binary files a/tests/nonPolarisedTFReflectivityCalculation/customLayersOutputs.mat and b/tests/nonPolarisedTFReflectivityCalculation/customLayersOutputs.mat differ diff --git a/tests/nonPolarisedTFReflectivityCalculation/customLayersTFParams.mat b/tests/nonPolarisedTFReflectivityCalculation/customLayersTFParams.mat index 391b8b8ff..d25dd4a58 100644 Binary files a/tests/nonPolarisedTFReflectivityCalculation/customLayersTFParams.mat and b/tests/nonPolarisedTFReflectivityCalculation/customLayersTFParams.mat differ diff --git a/tests/nonPolarisedTFReflectivityCalculation/customXYInputs.mat b/tests/nonPolarisedTFReflectivityCalculation/customXYInputs.mat index 46d8da057..d4a13ae29 100644 Binary files a/tests/nonPolarisedTFReflectivityCalculation/customXYInputs.mat and b/tests/nonPolarisedTFReflectivityCalculation/customXYInputs.mat differ diff --git a/tests/nonPolarisedTFReflectivityCalculation/customXYOutputs.mat b/tests/nonPolarisedTFReflectivityCalculation/customXYOutputs.mat index d685dabd8..a04df36c2 100644 Binary files a/tests/nonPolarisedTFReflectivityCalculation/customXYOutputs.mat and b/tests/nonPolarisedTFReflectivityCalculation/customXYOutputs.mat differ diff --git a/tests/nonPolarisedTFReflectivityCalculation/customXYTFParams.mat b/tests/nonPolarisedTFReflectivityCalculation/customXYTFParams.mat index 47d70af09..def2634b7 100644 Binary files a/tests/nonPolarisedTFReflectivityCalculation/customXYTFParams.mat and b/tests/nonPolarisedTFReflectivityCalculation/customXYTFParams.mat differ diff --git a/tests/nonPolarisedTFReflectivityCalculation/makeInputsAndOutputs.m b/tests/nonPolarisedTFReflectivityCalculation/makeInputsAndOutputs.m index de273eafb..148462d44 100644 --- a/tests/nonPolarisedTFReflectivityCalculation/makeInputsAndOutputs.m +++ b/tests/nonPolarisedTFReflectivityCalculation/makeInputsAndOutputs.m @@ -42,22 +42,10 @@ save([root filesep 'tests/nonPolarisedTFReflectivityCalculation/customLayersOutputs'],'outputs'); % (c) TF Parameters -[contrastParams,calculationResults,reflectivity,simulation,shiftedData,layerSlds,sldProfiles,resampledLayers] = nonPolarisedTF.reflectivityCalculation(problemStruct,problemCells,controls); - -TFParams.contrastParams = contrastParams; -TFParams.calculationResults = calculationResults; -TFParams.reflectivity = reflectivity; -TFParams.simulation = simulation; -TFParams.shiftedData = shiftedData; -TFParams.layerSlds = layerSlds; -TFParams.sldProfiles = sldProfiles; -TFParams.resampledLayers = resampledLayers; - -[backgroundParams,qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,... - chis,reflectivity,simulation,shiftedData,layerSlds,sldProfiles,... +[qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,... + chis,reflectivity,simulation,shiftedData,backgrounds,layerSlds,sldProfiles,... resampledLayers,subRoughs] = nonPolarisedTF.customLayers(problemStruct,problemCells,controls); -TFParams.backgroundParams = backgroundParams; TFParams.qzshifts = qzshifts; TFParams.scalefactors = scalefactors; TFParams.bulkIn = bulkIn; @@ -66,6 +54,14 @@ TFParams.chis = chis; TFParams.subRoughs = subRoughs; +TFParams.reflectivity = reflectivity; +TFParams.simulation = simulation; +TFParams.shiftedData = shiftedData; +TFParams.backgrounds = backgrounds; +TFParams.layerSlds = layerSlds; +TFParams.sldProfiles = sldProfiles; +TFParams.resampledLayers = resampledLayers; + save([root filesep 'tests/nonPolarisedTFReflectivityCalculation/customLayersTFParams'],'TFParams'); %% 2. Custom XY. @@ -107,22 +103,10 @@ save([root filesep 'tests/nonPolarisedTFReflectivityCalculation/customXYOutputs'],'outputs'); % (c) TF Parameters -[contrastParams,calculationResults,reflectivity,simulation,shiftedData,layerSlds,sldProfiles,resampledLayers] = nonPolarisedTF.reflectivityCalculation(problemStruct,problemCells,controls); - -TFParams.contrastParams = contrastParams; -TFParams.calculationResults = calculationResults; -TFParams.reflectivity = reflectivity; -TFParams.simulation = simulation; -TFParams.shiftedData = shiftedData; -TFParams.layerSlds = layerSlds; -TFParams.sldProfiles = sldProfiles; -TFParams.resampledLayers = resampledLayers; - -[backgroundParams,qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,... - chis,reflectivity,simulation,shiftedData,layerSlds,sldProfiles,... +[qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,... + chis,reflectivity,simulation,shiftedData,backgrounds,layerSlds,sldProfiles,... resampledLayers, subRoughs] = nonPolarisedTF.customXY(problemStruct,problemCells,controls); -TFParams.backgroundParams = backgroundParams; TFParams.qzshifts = qzshifts; TFParams.scalefactors = scalefactors; TFParams.bulkIn = bulkIn; @@ -131,6 +115,14 @@ TFParams.chis = chis; TFParams.subRoughs = subRoughs; +TFParams.reflectivity = reflectivity; +TFParams.simulation = simulation; +TFParams.shiftedData = shiftedData; +TFParams.backgrounds = backgrounds; +TFParams.layerSlds = layerSlds; +TFParams.sldProfiles = sldProfiles; +TFParams.resampledLayers = resampledLayers; + save([root filesep 'tests/nonPolarisedTFReflectivityCalculation/customXYTFParams'],'TFParams'); %% 3. Standard Layers @@ -173,22 +165,10 @@ save([root filesep 'tests/nonPolarisedTFReflectivityCalculation/standardLayersOutputs'],'outputs'); % (c) TF Parameters -[contrastParams,calculationResults,reflectivity,simulation,shiftedData,layerSlds,sldProfiles,resampledLayers] = nonPolarisedTF.reflectivityCalculation(problemStruct,problemCells,controls); - -TFParams.contrastParams = contrastParams; -TFParams.calculationResults = calculationResults; -TFParams.reflectivity = reflectivity; -TFParams.simulation = simulation; -TFParams.shiftedData = shiftedData; -TFParams.layerSlds = layerSlds; -TFParams.sldProfiles = sldProfiles; -TFParams.resampledLayers = resampledLayers; - -[backgroundParams,qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,... - chis,reflectivity,simulation,shiftedData,layerSlds,sldProfiles,... +[qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,... + chis,reflectivity,simulation,shiftedData,backgrounds,layerSlds,sldProfiles,... resampledLayers,subRoughs] = nonPolarisedTF.standardLayers(problemStruct,problemCells,controls); -TFParams.backgroundParams = backgroundParams; TFParams.qzshifts = qzshifts; TFParams.scalefactors = scalefactors; TFParams.bulkIn = bulkIn; @@ -197,6 +177,14 @@ TFParams.chis = chis; TFParams.subRoughs = subRoughs; +TFParams.reflectivity = reflectivity; +TFParams.simulation = simulation; +TFParams.shiftedData = shiftedData; +TFParams.backgrounds = backgrounds; +TFParams.layerSlds = layerSlds; +TFParams.sldProfiles = sldProfiles; +TFParams.resampledLayers = resampledLayers; + save([root filesep 'tests/nonPolarisedTFReflectivityCalculation/standardLayersTFParams'],'TFParams'); %% 4. Converting between RAT and RASCAL diff --git a/tests/nonPolarisedTFReflectivityCalculation/orsoDSPCCustomLayers.m b/tests/nonPolarisedTFReflectivityCalculation/orsoDSPCCustomLayers.m index dc71d1c3a..6def13bdb 100644 --- a/tests/nonPolarisedTFReflectivityCalculation/orsoDSPCCustomLayers.m +++ b/tests/nonPolarisedTFReflectivityCalculation/orsoDSPCCustomLayers.m @@ -89,7 +89,7 @@ project.addBackground('Background H2O','constant','Backs par H2O'); % And edit the other one.... -project.setBackground(1,'name','Background D2O', 'Value1','Backs par D2O'); +project.setBackground(1,'name','Background D2O', 'source','Backs par D2O'); % Finally modify some of the other parameters to be more suitable values % for a solid / liquid experiment. @@ -105,6 +105,7 @@ % D2O contrast.. project.addContrast('name','Bilayer / D2O',... 'background','Background D2O',... + 'backgroundAction', actions.Add,... 'resolution','Resolution 1',... 'scalefactor', 'Scalefactor 1',... 'bulkIn', 'Silicon',... @@ -114,6 +115,7 @@ % SMW contrast.. project.addContrast('name','Bilayer / SMW',... 'background','Background SMW',... + 'backgroundAction', actions.Add,... 'resolution','Resolution 1',... 'scalefactor', 'Scalefactor 1',... 'bulkIn', 'Silicon',... @@ -123,6 +125,7 @@ % SMW contrast.. project.addContrast('name','Bilayer / H2O',... 'background','Background H2O',... + 'backgroundAction', actions.Add,... 'resolution','Resolution 1',... 'scalefactor', 'Scalefactor 1',... 'bulkIn', 'Silicon',... diff --git a/tests/nonPolarisedTFReflectivityCalculation/standardLayersInputs.mat b/tests/nonPolarisedTFReflectivityCalculation/standardLayersInputs.mat index fa077d8ec..868cc5a6e 100644 Binary files a/tests/nonPolarisedTFReflectivityCalculation/standardLayersInputs.mat and b/tests/nonPolarisedTFReflectivityCalculation/standardLayersInputs.mat differ diff --git a/tests/nonPolarisedTFReflectivityCalculation/standardLayersOutputs.mat b/tests/nonPolarisedTFReflectivityCalculation/standardLayersOutputs.mat index 70966b1a9..54d8b9e47 100644 Binary files a/tests/nonPolarisedTFReflectivityCalculation/standardLayersOutputs.mat and b/tests/nonPolarisedTFReflectivityCalculation/standardLayersOutputs.mat differ diff --git a/tests/nonPolarisedTFReflectivityCalculation/standardLayersTFParams.mat b/tests/nonPolarisedTFReflectivityCalculation/standardLayersTFParams.mat index 42072a514..623fa133a 100644 Binary files a/tests/nonPolarisedTFReflectivityCalculation/standardLayersTFParams.mat and b/tests/nonPolarisedTFReflectivityCalculation/standardLayersTFParams.mat differ diff --git a/tests/nonPolarisedTFReflectivityCalculation/testReflectivityCalculations.m b/tests/nonPolarisedTFReflectivityCalculation/testReflectivityCalculations.m index a5f370793..b7bc98013 100644 --- a/tests/nonPolarisedTFReflectivityCalculation/testReflectivityCalculations.m +++ b/tests/nonPolarisedTFReflectivityCalculation/testReflectivityCalculations.m @@ -39,15 +39,13 @@ expectedResultStruct % Expected output value of the initial results struct expectedResult % Expected output value of the final results struct expectedBayesResults % Expected output value of the bayes results struct - TFContrastParams - TFCalculationResults TFReflectivity TFSimulation TFShiftedData + TFBackgrounds TFLayerSLDs TFSLDProfiles TFResampledLayers - TFBackgroundParams TFQzshifts TFScalefactors TFBulkIn @@ -94,16 +92,14 @@ function loadTestDataOutputs(testCase, outputsFile) function loadTFParams(testCase, TFFile) testCase.TFParams = load(TFFile); - testCase.TFContrastParams = testCase.TFParams.TFParams.contrastParams; - testCase.TFCalculationResults = testCase.TFParams.TFParams.calculationResults; testCase.TFReflectivity = testCase.TFParams.TFParams.reflectivity; testCase.TFSimulation = testCase.TFParams.TFParams.simulation; testCase.TFShiftedData = testCase.TFParams.TFParams.shiftedData; + testCase.TFBackgrounds = testCase.TFParams.TFParams.backgrounds; testCase.TFLayerSLDs = testCase.TFParams.TFParams.layerSlds; testCase.TFSLDProfiles = testCase.TFParams.TFParams.sldProfiles; testCase.TFResampledLayers = testCase.TFParams.TFParams.resampledLayers; - testCase.TFBackgroundParams = testCase.TFParams.TFParams.backgroundParams; testCase.TFQzshifts = testCase.TFParams.TFParams.qzshifts; testCase.TFScalefactors = testCase.TFParams.TFParams.scalefactors; testCase.TFBulkIn = testCase.TFParams.TFParams.bulkIn; @@ -170,46 +166,33 @@ function testReflectivityCalculation(testCase, whichParallel, useCompiled) else result = reflectivityCalculation(testCase.problemStruct, testCase.problemCells, testCase.problemLimits, testCase.controls); end - testCase.verifyEqual(result, testCase.expectedResultStruct, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); - end - - function testNonPolarisedTFReflectivityCalculation(testCase) - [contrastParams, calculationResults, reflectivity, simulation, shiftedData, layerSLDs, SLDProfiles, resampledLayers] = nonPolarisedTF.reflectivityCalculation(testCase.problemStruct, testCase.problemCells, testCase.controls); - testCase.verifyEqual(contrastParams, testCase.TFContrastParams, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); - testCase.verifyEqual(calculationResults, testCase.TFCalculationResults, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); - testCase.verifyEqual(reflectivity, testCase.TFReflectivity, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); - testCase.verifyEqual(simulation, testCase.TFSimulation, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); - testCase.verifyEqual(shiftedData, testCase.TFShiftedData, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); - testCase.verifyEqual(layerSLDs, testCase.TFLayerSLDs, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); - testCase.verifyEqual(SLDProfiles, testCase.TFSLDProfiles, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); - testCase.verifyEqual(resampledLayers, testCase.TFResampledLayers, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); + testCase.verifyEqual(result, testCase.expectedResultStruct, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); end - function testNonPolarisedTFLayersReflectivityCalc(testCase, whichParallel, TFFile) + function testNonPolarisedTFReflectivityCalculation(testCase, whichParallel, TFFile) testCase.controls.parallel = whichParallel; % Choose the appropriate routine for each test case switch TFFile case 'standardLayersTFParams.mat' - [backgroundParams,qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,chis,reflectivity,... - simulation,shiftedData,layerSLDs,SLDProfiles,resampledLayers,... + [qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,chis,reflectivity,... + simulation,shiftedData,backgrounds,layerSLDs,SLDProfiles,resampledLayers,... subRoughs] = nonPolarisedTF.standardLayers(testCase.problemStruct,testCase.problemCells,... testCase.controls); case 'customLayersTFParams.mat' - [backgroundParams,qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,chis,reflectivity,... - simulation,shiftedData,layerSLDs,SLDProfiles,resampledLayers,... + [qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,chis,reflectivity,... + simulation,shiftedData,backgrounds,layerSLDs,SLDProfiles,resampledLayers,... subRoughs] = nonPolarisedTF.customLayers(testCase.problemStruct,testCase.problemCells,... testCase.controls); case 'customXYTFParams.mat' - [backgroundParams,qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,chis,reflectivity,... - simulation,shiftedData,layerSLDs,SLDProfiles,resampledLayers,... + [qzshifts,scalefactors,bulkIn,bulkOut,resolutionParams,chis,reflectivity,... + simulation,shiftedData,backgrounds,layerSLDs,SLDProfiles,resampledLayers,... subRoughs] = nonPolarisedTF.customXY(testCase.problemStruct,testCase.problemCells,... testCase.controls); end - testCase.verifyEqual(backgroundParams, testCase.TFBackgroundParams, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(qzshifts, testCase.TFQzshifts, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(scalefactors, testCase.TFScalefactors, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(bulkIn, testCase.TFBulkIn, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); @@ -219,6 +202,7 @@ function testNonPolarisedTFLayersReflectivityCalc(testCase, whichParallel, TFFil testCase.verifyEqual(reflectivity, testCase.TFReflectivity, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(simulation, testCase.TFSimulation, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(shiftedData, testCase.TFShiftedData, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); + testCase.verifyEqual(backgrounds, testCase.TFBackgrounds, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(layerSLDs, testCase.TFLayerSLDs, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(SLDProfiles, testCase.TFSLDProfiles, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(resampledLayers, testCase.TFResampledLayers, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); @@ -241,63 +225,70 @@ function testCheckIndices(testCase) % Test standard input passes testInput = testCase.problemStruct; - checkIndices(testInput); + customFiles = testCase.problemCells{14}; + checkIndices(testInput, customFiles); % Test Background Param Error testInput = testCase.problemStruct; - testInput.contrastBackgroundParams(1) = 0; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testInput.contrastBackgroundParams{1} = 0; + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); + testInput = testCase.problemStruct; + testInput.contrastBackgroundParams{1} = 4; + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); + + testInput.contrastBackgroundParams{1} = [0 1 2 3]; + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); testInput = testCase.problemStruct; - testInput.contrastBackgroundParams(1) = 4; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testInput.contrastBackgroundParams{1} = [4 1 2 3]; + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); % Test Qzshift Error testInput = testCase.problemStruct; testInput.contrastQzshifts(1) = 0; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); testInput = testCase.problemStruct; testInput.contrastQzshifts(1) = 4; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); % Test Scalefactor Error testInput = testCase.problemStruct; testInput.contrastScalefactors(1) = 0; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); testInput = testCase.problemStruct; testInput.contrastScalefactors(1) = 4; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); % Test Bulk In Error testInput = testCase.problemStruct; testInput.contrastBulkIns(1) = 0; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); testInput = testCase.problemStruct; testInput.contrastBulkIns(1) = 4; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); % Test Bulk Out Error testInput = testCase.problemStruct; testInput.contrastBulkOuts(1) = 0; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); testInput = testCase.problemStruct; testInput.contrastBulkOuts(1) = 4; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); % Test Resolution Param Error testInput = testCase.problemStruct; testInput.contrastResolutionParams(1) = 0; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); testInput = testCase.problemStruct; testInput.contrastResolutionParams(1) = 4; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); % Test Domain Ratio Error testInput = testCase.problemStruct; testInput.contrastDomainRatios(1) = 0; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); testInput = testCase.problemStruct; testInput.contrastDomainRatios(1) = 4; - testCase.verifyError(@() checkIndices(testInput), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() checkIndices(testInput, customFiles), exceptions.indexOutOfRange.errorID); end @@ -316,7 +307,7 @@ function testParseCells(testCase) function testExtractProblemParams(testCase) [numberOfContrasts, geometry, contrastBackgroundParams, contrastQzshifts, contrastScalefactors, contrastBulkIns, contrastBulkOuts,... contrastResolutionParams, contrastDomainRatios, backgroundParams, qzshifts, scalefactors, bulkIn, bulkOut, resolutionParams, domainRatio,... - dataPresent, nParams, params, numberOfLayers, resample, backgroundParamsType, contrastCustomFiles, useImaginary] = extractProblemParams(testCase.problemStruct); + dataPresent, nParams, params, numberOfLayers, resample, backgroundTypes, backgroundActions, contrastCustomFiles, useImaginary] = extractProblemParams(testCase.problemStruct); testCase.verifyEqual(numberOfContrasts, testCase.problemStruct.numberOfContrasts, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(geometry, testCase.problemStruct.geometry, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); @@ -339,7 +330,8 @@ function testExtractProblemParams(testCase) testCase.verifyEqual(params, testCase.problemStruct.params, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(numberOfLayers, testCase.problemStruct.numberOfLayers, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(resample, testCase.problemStruct.resample, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); - testCase.verifyEqual(backgroundParamsType, testCase.problemStruct.contrastBackgroundActions, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); + testCase.verifyEqual(backgroundTypes, testCase.problemStruct.contrastBackgroundTypes, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); + testCase.verifyEqual(backgroundActions, testCase.problemStruct.contrastBackgroundActions, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(contrastCustomFiles, testCase.problemStruct.contrastCustomFiles, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); testCase.verifyEqual(useImaginary, testCase.problemStruct.useImaginary, 'RelTol', testCase.tolerance, 'AbsTol', testCase.absTolerance); end diff --git a/tests/testBackgroundsClass.m b/tests/testBackgroundsClass.m index 16095733c..73f7972c9 100644 --- a/tests/testBackgroundsClass.m +++ b/tests/testBackgroundsClass.m @@ -4,12 +4,13 @@ parameters backgrounds background + names end methods(TestMethodSetup) function createBackground(testCase) params = parametersClass(testCase.parameters{1, :}); - testCase.background = backgroundsClass(params, testCase.backgrounds(1, :)); + testCase.background = backgroundsClass(params, testCase.backgrounds(1, :), testCase.names); end end @@ -22,15 +23,17 @@ function createBackgrounds(testCase) 'background param 3', 0.2, 0.17, 1.1, false, priorTypes.Uniform.value, 0, Inf; }; testCase.backgrounds = { - 'background 1', allowedTypes.Constant.value, 'background param 1', '', '', '', ''; - 'background 2', allowedTypes.Constant.value, 'background param 2', '', '', '', ''; - 'background 3', allowedTypes.Constant.value, 'background param 3', '', '', '', ''; - 'background 4', allowedTypes.Constant.value, 'background param 3', '', '', '', ''; - % once data and function backgrounds are implemented, replace 3 and 4 with these - %'background 3', allowedTypes.Function.value, 'function_name', 'background param 1', 'background param 2', '', ''; - %'background 4', allowedTypes.Data.value, '', '', '', '', ''; + 'background 1', allowedTypes.Constant.value, 'background param 1', '', '', '', '', ''; + 'background 2', allowedTypes.Constant.value, 'background param 2', '', '', '', '', ''; + 'background 3', allowedTypes.Function.value, 'function_name', 'background param 1', 'background param 2', '', '', ''; + 'background 4', allowedTypes.Data.value, 'data_name', '', '', '', '', ''; }; end + + function createTestNames(testCase) + testCase.names.customFileNames = 'function_name'; + testCase.names.dataNames = 'data_name'; + end end methods (Test) @@ -39,7 +42,7 @@ function testCreation(testCase) params = parametersClass(testCase.parameters{1, :}); params.varTable = [params.varTable; vertcat(testCase.parameters(2:end, :))]; - testBackground = backgroundsClass(params, testCase.backgrounds(1, :)); + testBackground = backgroundsClass(params, testCase.backgrounds(1, :), testCase.names); testCase.verifyEqual(string(testBackground.backgroundParams.varTable{1, :}), ... string(testCase.parameters(1, :)), 'Start background parameter not set correctly'); @@ -47,44 +50,46 @@ function testCreation(testCase) testCase.verifyEqual(string(testBackground.backgrounds.varTable{1, :}), ... string(testCase.backgrounds(1, :)), 'Start background parameter not set correctly'); - testCase.verifySize(testBackground.backgrounds.varTable, [1, 7], 'backgrounds has wrong dimension'); + testCase.verifySize(testBackground.backgrounds.varTable, [1, 8], 'backgrounds has wrong dimension'); end function testGetNames(testCase) % Tests getNames returns correctly - names = testCase.background.getNames(); - testCase.verifyEqual(names, string(testCase.backgrounds(1, 1)), 'getNames method not working'); - testCase.verifySize(names, [1, 1], 'background names has wrong dimension'); + backgroundNames = testCase.background.getNames(); + testCase.verifyEqual(backgroundNames, string(testCase.backgrounds(1, 1)), 'getNames method not working'); + testCase.verifySize(backgroundNames, [1, 1], 'background names has wrong dimension'); testCase.background.backgrounds.varTable = [testCase.background.backgrounds.varTable; vertcat(testCase.backgrounds(2:end, :))]; - names = testCase.background.getNames(); - testCase.verifyEqual(names, convertCharsToStrings(testCase.backgrounds(:, 1)), 'getNames method not working'); - testCase.verifySize(names, [size(testCase.backgrounds, 1), 1], 'background names has wrong dimension'); + backgroundNames = testCase.background.getNames(); + testCase.verifyEqual(backgroundNames, convertCharsToStrings(testCase.backgrounds(:, 1)), 'getNames method not working'); + testCase.verifySize(backgroundNames, [size(testCase.backgrounds, 1), 1], 'background names has wrong dimension'); end function testAddBackground(testCase) % Checks that background can be added testCase.background.backgroundParams.varTable = [testCase.background.backgroundParams.varTable; vertcat(testCase.parameters(2:end, :))]; - testCase.background.addBackground(); + testCase.background.addBackground(testCase.names); testCase.verifyEqual(string(testCase.background.backgrounds.varTable{end, :}),... - string({'New background 2', allowedTypes.Constant.value, '', '', '', '', ''}), 'addBackground method not working'); - testCase.background.addBackground('New Back'); + string({'New background 2', allowedTypes.Constant.value, '', '', '', '', '', ''}), 'addBackground method not working'); + testCase.background.addBackground(testCase.names, 'New Back'); testCase.verifyEqual(string(testCase.background.backgrounds.varTable{end, :}),... - string({'New Back', allowedTypes.Constant.value, '', '', '', '', ''}), 'addBackground method not working'); - testCase.background.addBackground(testCase.backgrounds{3, 1:5}); + string({'New Back', allowedTypes.Constant.value, '', '', '', '', '', ''}), 'addBackground method not working'); + testCase.background.addBackground(testCase.names, testCase.backgrounds{3, 1:5}); testCase.verifyEqual(string(testCase.background.backgrounds.varTable{end, :}),... string(testCase.backgrounds(3, :)), 'addBackground method not working'); - testCase.background.addBackground(testCase.backgrounds{4, :}); + testCase.background.addBackground(testCase.names, testCase.backgrounds{4, 1:3}); testCase.verifyEqual(string(testCase.background.backgrounds.varTable{end, :}),... string(testCase.backgrounds(4, :)), 'addBackground method not working'); - %testCase.background.addBackground('background 5', allowedTypes.Function, 'function_name', 1, 3); - %testCase.verifyEqual(string(testCase.background.backgrounds.varTable{end, :}),... - % ["background 5", string(allowedTypes.Function.value), "function_name", "background param 1", "background param 3", "", ""], ... - % 'addBackground method not working'); - testCase.verifyError(@() testCase.background.addBackground('New', 'fixed'), exceptions.invalidOption.errorID); - testCase.verifyError(@() testCase.background.addBackground('New', allowedTypes.Constant), exceptions.invalidNumberOfInputs.errorID); - testCase.verifyError(@() testCase.background.addBackground('New', allowedTypes.Constant.value, 6), exceptions.indexOutOfRange.errorID); + testCase.background.addBackground(testCase.names, 'background 5', allowedTypes.Function, 'function_name', 1, 3); + testCase.verifyEqual(string(testCase.background.backgrounds.varTable{end, :}),... + ["background 5", string(allowedTypes.Function.value), "function_name", "background param 1", "background param 3", "", "", ""], ... + 'addBackground method not working'); + testCase.verifyWarning(@() testCase.background.addBackground(testCase.names, "New background 6", allowedTypes.Constant.value, "background param 1", "extra_value", '', '', '', ''), 'warnings:invalidNumberOfInputs'); + testCase.verifyWarning(@() testCase.background.addBackground(testCase.names, "New background 7", allowedTypes.Data.value, "data_name", "background param 1", "extra_value", '', '', ''), 'warnings:invalidNumberOfInputs'); + testCase.verifyError(@() testCase.background.addBackground(testCase.names, 'New', 'fixed'), exceptions.invalidOption.errorID); + testCase.verifyError(@() testCase.background.addBackground(testCase.names, 'New', allowedTypes.Constant), exceptions.invalidNumberOfInputs.errorID); + testCase.verifyError(@() testCase.background.addBackground(testCase.names, 'New', allowedTypes.Constant.value, 6), exceptions.indexOutOfRange.errorID); end function testRemoveBackground(testCase) @@ -111,39 +116,59 @@ function testSetBackgroundName(testCase) end function testSetBackground(testCase) + import matlab.unittest.fixtures.SuppressedWarningsFixture + testCase.applyFixture(SuppressedWarningsFixture('warnings:invalidNumberOfInputs')) + testCase.applyFixture(SuppressedWarningsFixture('warnings:fieldsCleared')) + + % Checks that background can be modified testCase.background.backgrounds.varTable = [testCase.background.backgrounds.varTable; vertcat(testCase.backgrounds(2:end, :))]; testCase.background.backgroundParams.varTable = [testCase.background.backgroundParams.varTable; vertcat(testCase.parameters(2:end, :))]; + + - testCase.background.setBackground('Background 1', 'name', 'Back 1'); + testCase.background.setBackground('Background 1',testCase.names, 'name', 'Back 1'); testCase.verifyEqual(testCase.background.backgrounds.varTable{1, 1}, "Back 1", 'setBackground method not working'); - testCase.background.setBackground(1, 'name', 'Background 1'); + testCase.background.setBackground(1, testCase.names, 'name', 'Background 1'); testCase.verifyEqual(testCase.background.backgrounds.varTable{1, 1}, "Background 1", 'setBackground method not working'); - testCase.background.setBackground(1, 'type', allowedTypes.Constant.value); + testCase.background.setBackground(1, testCase.names, 'type', allowedTypes.Constant.value); testCase.verifyEqual(testCase.background.backgrounds.varTable{1, 2}, string(allowedTypes.Constant.value), 'setBackground method not working'); - %testCase.background.setBackground('Background 1', 'type', allowedTypes.Function); - %testCase.verifyEqual(testCase.background.backgrounds.varTable{1, 2}, string(allowedTypes.Function.value), 'setBackground method not working'); - testCase.verifyError(@() testCase.background.setBackground(2, 'type', 'random'), exceptions.invalidOption.errorID); + testCase.background.setBackground('Background 1', testCase.names, 'type', allowedTypes.Function.value); + + + + + testCase.verifyEqual(testCase.background.backgrounds.varTable{1, 2}, string(allowedTypes.Function.value), 'setBackground method not working'); + testCase.verifyError(@() testCase.background.setBackground(2, testCase.names, 'type', 'random'), exceptions.invalidOption.errorID); - %testCase.background.setBackground(3, 'Value1', 'random'); - %testCase.verifyEqual(testCase.background.backgrounds.varTable{3, 3}, "random", 'setBackground method not working'); - testCase.background.setBackground('Background 3', 'Value1', 'Background param 1'); - testCase.verifyEqual(testCase.background.backgrounds.varTable{3, 3}, "Background param 1", 'setBackground method not working'); + testCase.background.setBackground('Background 2', testCase.names, 'Source', 'Background param 1'); + testCase.verifyEqual(testCase.background.backgrounds.varTable{2, 3}, "Background param 1", 'setBackground method not working'); - testCase.background.setBackground(2, 'Value2', 'Background param 1'); - testCase.verifyEqual(testCase.background.backgrounds.varTable{2, 4}, "Background param 1", 'setBackground method not working'); - testCase.verifyError(@() testCase.background.setBackground(2, 'Value2', 'random'), exceptions.nameNotRecognised.errorID); - testCase.verifyError(@() testCase.background.setBackground(5, 'Value2', 'random'), exceptions.indexOutOfRange.errorID); - testCase.verifyError(@() testCase.background.setBackground(true, 'Value2', 'random'), exceptions.invalidType.errorID); + testCase.background.setBackground(2, testCase.names, 'Value2', 'Background param 1'); + testCase.verifyEqual(testCase.background.backgrounds.varTable{2, 5}, "Background param 1", 'setBackground method not working'); + testCase.verifyError(@() testCase.background.setBackground(2, testCase.names, 'Value2', 'random'), exceptions.nameNotRecognised.errorID); + testCase.verifyError(@() testCase.background.setBackground(5, testCase.names, 'Value2', 'random'), exceptions.indexOutOfRange.errorID); + testCase.verifyError(@() testCase.background.setBackground(true, testCase.names, 'Value2', 'random'), exceptions.invalidType.errorID); - testCase.background.setBackground(3, 'name', 'New Name', 'type', allowedTypes.Constant, 'value1', 'Background param 3', 'value2', ''); + testCase.background.setBackground(3, testCase.names, 'name', 'New Name', 'type', allowedTypes.Constant.value, 'source', 'Background param 3', 'value1', ''); + + + testCase.verifyEqual(testCase.background.backgrounds.varTable{3, 1}, "New Name", 'setBackground method not working'); testCase.verifyEqual(testCase.background.backgrounds.varTable{3, 2}, string(allowedTypes.Constant.value), 'setBackground method not working'); testCase.verifyEqual(testCase.background.backgrounds.varTable{3, 3}, "Background param 3", 'setBackground method not working'); testCase.verifyEqual(testCase.background.backgrounds.varTable{3, 4}, "", 'setBackground method not working'); end + function testSetBackgroundWarnings(testCase) + testCase.background.backgrounds.varTable = [testCase.background.backgrounds.varTable; vertcat(testCase.backgrounds(2:end, :))]; + testCase.background.backgroundParams.varTable = [testCase.background.backgroundParams.varTable; vertcat(testCase.parameters(2:end, :))]; + + testCase.verifyWarning(@() testCase.background.setBackground(1, testCase.names, "Value1", "Background param 1"), 'warnings:invalidNumberOfInputs'); + testCase.verifyWarning(@() testCase.background.setBackground(4, testCase.names, "Value2", "Background param 1"), 'warnings:invalidNumberOfInputs'); + end + function testDisplayBackgroundsObject(testCase) % Check that the contents of the background are printed paramHeader = {'p', 'Name', 'Min', 'Value', 'Max', 'Fit?'}; @@ -166,7 +191,7 @@ function testDisplayBackgroundsObject(testCase) testCase.verifyLength(row, length(paramHeader)); testCase.verifyEqual(row, string({1, testCase.parameters{1, 1:5}}), 'displayBackgroundsObject method not working') - paramHeader = {'p', 'Name', 'Type', 'Value 1', 'Value 2', 'Value 3', 'Value 4', 'Value 5'}; + paramHeader = {'p', 'Name', 'Type', 'Source', 'Value 1', 'Value 2', 'Value 3', 'Value 4', 'Value 5'}; displayArray = textscan(display{3},'%s','Delimiter','\r','TextType','string'); displayArray = strip(displayArray{1}); % display table should be height of background table plus header and divider row @@ -202,7 +227,7 @@ function testToStruct(testCase) expected.backgroundParamPriors = {{'background param 1', priorTypes.Uniform.value, 0, Inf}}; expected.backgroundNames = "background 1"; expected.backgroundTypes = string(allowedTypes.Constant.value); - expected.backgroundValues = {"background param 1", "", "", "", ""}; + expected.backgroundValues = {"background param 1", "", "", "", "", ""}; testCase.verifyEqual(testCase.background.toStruct(), expected, 'toStruct method not working'); testCase.background.backgrounds.varTable = [testCase.background.backgrounds.varTable; vertcat(testCase.backgrounds(2:3, :))]; @@ -217,10 +242,9 @@ function testToStruct(testCase) {'background param 3', priorTypes.Uniform.value, 0, Inf}}; expected.backgroundNames = ["background 1"; "background 2"; "background 3"]; expected.backgroundTypes = [string(allowedTypes.Constant.value); string(allowedTypes.Constant.value); - string(allowedTypes.Constant.value)]; % FIXME: change to function when function backgrounds added - expected.backgroundValues = {"background param 1", "", "", "", ""; "background param 2", "", "", "", "";... - "background param 3", "", "", "", ""}; - % "function_name", "background param 1", "background param 2", "", ""}; FIXME - replace prev line with this when function backs added + string(allowedTypes.Function.value)]; + expected.backgroundValues = {"background param 1", "", "", "", "", ""; "background param 2", "", "", "", "", "";... + "function_name", "background param 1", "background param 2", "", "", ""}; testCase.verifyEqual(testCase.background.toStruct(), expected, 'toStruct method not working'); end end diff --git a/tests/testCommonFunctions/D2OBackgroundData.mat b/tests/testCommonFunctions/D2OBackgroundData.mat new file mode 100644 index 000000000..ea292d92e Binary files /dev/null and b/tests/testCommonFunctions/D2OBackgroundData.mat differ diff --git a/tests/testCommonFunctions/D2OContrastData.mat b/tests/testCommonFunctions/D2OContrastData.mat new file mode 100644 index 000000000..4231a18d0 Binary files /dev/null and b/tests/testCommonFunctions/D2OContrastData.mat differ diff --git a/tests/testCommonFunctions/D2OOutputData.mat b/tests/testCommonFunctions/D2OOutputData.mat new file mode 100644 index 000000000..af71e582a Binary files /dev/null and b/tests/testCommonFunctions/D2OOutputData.mat differ diff --git a/tests/testCommonFunctions/applyBackgroundCorrectionInputs.mat b/tests/testCommonFunctions/applyBackgroundCorrectionInputs.mat index 6cc169173..2d0698b81 100644 Binary files a/tests/testCommonFunctions/applyBackgroundCorrectionInputs.mat and b/tests/testCommonFunctions/applyBackgroundCorrectionInputs.mat differ diff --git a/tests/testCommonFunctions/applyBackgroundCorrectionOutputs.mat b/tests/testCommonFunctions/applyBackgroundCorrectionOutputs.mat index eef32038e..94149e06d 100644 Binary files a/tests/testCommonFunctions/applyBackgroundCorrectionOutputs.mat and b/tests/testCommonFunctions/applyBackgroundCorrectionOutputs.mat differ diff --git a/tests/testCommonFunctions/testCommonFunctions.m b/tests/testCommonFunctions/testCommonFunctions.m index 28a737b4c..92d017af1 100644 --- a/tests/testCommonFunctions/testCommonFunctions.m +++ b/tests/testCommonFunctions/testCommonFunctions.m @@ -13,6 +13,9 @@ callMatlabCustomLayersInputs; callMatlabCustomLayersOutputs; + insertDataBackgroundBackgroundData + insertDataBackgroundContrastData + insertDataBackgroundOutputData applyBackgroundCorrectionInputs; applyBackgroundCorrectionOutputs; callReflectivityInputs; @@ -81,7 +84,7 @@ function loadBackSort(testCase) testCase.backSortOutputs = outputs.outputs; % field end - function loadChiSquared(testCase) + function loadChiSquared(testCase) inputs = load('chiSquaredInputs.mat'); outputs = load('chiSquaredOutputs.mat'); testCase.chiSquaredInputs = inputs.inputs; @@ -102,6 +105,12 @@ function loadCallMatlabCustomLayers(testCase) testCase.callMatlabCustomLayersOutputs = outputs.outputs; end + function loadInsertDataBackgroundIntoContrastData(testCase) + testCase.insertDataBackgroundBackgroundData = load('D2OBackgroundData.mat').d2obackgrounddata; + testCase.insertDataBackgroundContrastData = load('D2OContrastData.mat').d2ocontrastdata; + testCase.insertDataBackgroundOutputData = load('D2OOutputData.mat').d2ooutputdata; + end + function loadApplyBackgroundCorrection(testCase) inputs = load('applyBackgroundCorrectionInputs.mat'); outputs = load('applyBackgroundCorrectionOutputs.mat'); @@ -109,7 +118,7 @@ function loadApplyBackgroundCorrection(testCase) % we can pass multiple values instead of one struct into testCase.applyB s = inputs.ans(1:end); - inputs = {s.reflect,s.Simul,s.shifted_dat,s.backg,s.backsType}; + inputs = {s.reflect,s.Simul,s.shifted_dat,s.backg,s.action}; s = outputs.applyBackgroundCorrectionOutputs.ans; outputs = {s.reflect,s.Simul,s.shifted_dat}; @@ -237,6 +246,15 @@ function testShiftData(testCase) testCase.verifyEqual(testCase.shiftDataOutputs,outputs, 'RelTol', testCase.tolerance, 'AbsTol', testCase.abs_tolerance); end + function testInsertDataBackgroundIntoContrastData(testCase) + % testInsertDataBackgroundIntoContrastData + contrastData = testCase.insertDataBackgroundContrastData; + backgroundData = testCase.insertDataBackgroundBackgroundData; + + outputData = insertDataBackgroundIntoContrastData(contrastData, backgroundData); + testCase.verifyEqual(testCase.insertDataBackgroundOutputData,outputData, 'RelTol', testCase.tolerance, 'AbsTol', testCase.abs_tolerance); + end + function testApplyBackgroundCorrection(testCase) % testApplyBackgroundCorrection diff --git a/tests/testContrastsClass.m b/tests/testContrastsClass.m index 3fcb4955b..1974b6ffc 100644 --- a/tests/testContrastsClass.m +++ b/tests/testContrastsClass.m @@ -243,7 +243,7 @@ function initialiseContrastsStruct(testCase) testCase.exampleStruct.contrastRepeatSLDs = {[0 1] [0 1] [0 1]}; testCase.exampleStruct.dataLimits = {[0.0130 0.3500] [0.0130 0.3500] [0.0130 0.3500]}; testCase.exampleStruct.simLimits = {[0.0057 0.3961] [0.0076 0.3300] [0.0063 0.3305]}; - testCase.exampleStruct.data = {testCase.D2OData(:,1:3) testCase.SMWData(:,1:3) testCase.H2OData(:,1:3)}; + testCase.exampleStruct.contrastData = {testCase.D2OData(:,1:3) testCase.SMWData(:,1:3) testCase.H2OData(:,1:3)}; testCase.exampleStruct.oilChiData = {testCase.D2OData(:,1:3) testCase.SMWData(:,1:3) testCase.H2OData(:,1:3)}; end @@ -518,7 +518,7 @@ function testToStructDisallowedData(testCase) testCase.exampleStruct.dataPresent(contrastIndex) = 0; testCase.exampleStruct.dataLimits{contrastIndex} = [0 0]; testCase.exampleStruct.simLimits{contrastIndex} = [0 0]; - testCase.exampleStruct.data{contrastIndex} = [0 0 0]; + testCase.exampleStruct.contrastData{contrastIndex} = [0 0 0]; testCase.verifyEqual(testCase.exampleClass.toStruct(testCase.allowedNames, 'standard layers', testCase.varTable), testCase.exampleStruct); end diff --git a/tests/testCreateProject.m b/tests/testCreateProject.m index ebc24ea5c..02ea9d3a6 100644 --- a/tests/testCreateProject.m +++ b/tests/testCreateProject.m @@ -3,8 +3,6 @@ % testProjects Class based unit tests for the project routine used to set % up calculations in RAT. % -% Paul Sharp 19/05/23 -% %% Declare properties and parameters properties (TestParameter) diff --git a/tests/testExamples.m b/tests/testExamples.m index 7514510ba..ac68f75f7 100644 --- a/tests/testExamples.m +++ b/tests/testExamples.m @@ -13,6 +13,7 @@ ['domains' filesep 'customLayers'],... ['domains' filesep 'customXY'],... ['miscellaneous' filesep 'absorption'],... + ['miscellaneous' filesep 'backgroundTypes'],... ['miscellaneous' filesep 'bayesBenchmark'],... ['miscellaneous' filesep 'roundRobin'],... ['miscellaneous' filesep 'convertRasCAL1Project']}; @@ -22,31 +23,38 @@ % 'customLayersDSPCSheet', 'standardLayersDSPCSheet', 'customXYDSPCSheet',... % 'roundRobin', 'bayesBenchmark', 'convertRascal'} exampleScriptFile = {'standardLayersDSPCScript',... + 'DSPCScriptWithDataBackground',... + 'DSPCScriptWithFunctionBackground',... 'customLayersDSPCScript',... 'orsoCustomXYDSPC',... 'domainsStandardLayersScript', ... 'domainsCustomLayerTest',... 'domainsCustomXYMain',... 'absorptionDPPC50'}; - exampleName = {'original_dspc_bilayer', 'Orso lipid example - custom layers', 'Orso lipid example - custom XY', '', '', '', 'DPPC_50_3pcBins'}; - exampleModel = {modelTypes.StandardLayers.value, modelTypes.CustomLayers.value,... + exampleName = {'original_dspc_bilayer', 'original_dspc_bilayer', 'original_dspc_bilayer',... + 'Orso lipid example - custom layers', 'Orso lipid example - custom XY',... + '', '', '', 'DPPC_50_3pcBins'}; + exampleModel = {modelTypes.StandardLayers.value, modelTypes.StandardLayers.value,... + modelTypes.StandardLayers.value,modelTypes.CustomLayers.value,... modelTypes.CustomXY.value, modelTypes.StandardLayers.value,... modelTypes.CustomLayers.value, modelTypes.CustomXY.value,... modelTypes.CustomLayers.value}; - exampleContrastCount = {2, 3, 3, 1, 1, 3, 4}; - exampleLayerCount = {6, 0, 0, 3, 0, 0, 0}; + exampleContrastCount = {2, 2, 2, 3, 3, 1, 1, 3, 4}; + exampleLayerCount = {6, 6, 6, 0, 0, 3, 0, 0, 0}; exampleGeometry = {geometryOptions.SubstrateLiquid.value,... + geometryOptions.SubstrateLiquid.value,... + geometryOptions.SubstrateLiquid.value,... geometryOptions.SubstrateLiquid.value,... geometryOptions.SubstrateLiquid.value,... geometryOptions.AirSubstrate.value,... geometryOptions.SubstrateLiquid.value,... geometryOptions.SubstrateLiquid.value,... geometryOptions.SubstrateLiquid.value}; - exampleParameterRowCount = {21, 8, 7, 13, 8, 6, 19}; - exampleBulkOutRowCount = {2, 3, 3, 1, 1, 3, 2}; - exampleBackgroundsTypesCount = {2, 3, 3, 1, 1, 1, 4}; - exampleDataCount = {3, 4, 4, 1, 1, 1, 5}; - exampleScalefactorRowCount = {2, 1, 1, 1, 1, 1, 4}; + exampleParameterRowCount = {21, 21, 21, 8, 7, 13, 8, 6, 19}; + exampleBulkOutRowCount = {2, 2, 2, 3, 3, 1, 1, 3, 2}; + exampleBackgroundsTypesCount = {2, 2, 2, 3, 3, 1, 1, 1, 4}; + exampleDataCount = {3, 4, 3, 4, 4, 1, 1, 1, 5}; + exampleScalefactorRowCount = {2, 2, 2, 1, 1, 1, 1, 1, 4}; end methods(TestClassSetup) @@ -82,14 +90,14 @@ function testScriptExamples(testCase, ... exampleBackgroundsTypesCount, ... exampleDataCount, ... exampleScalefactorRowCount) - + % verifies example exists with .m extension testCase.verifyEqual(exist(exampleScriptFile,'file'), 2); import matlab.unittest.fixtures.CurrentFolderFixture [pwdPath, ~, ~] = fileparts(which(exampleScriptFile)); testCase.applyFixture(CurrentFolderFixture(pwdPath)) - + % runs the example file evalc(exampleScriptFile); diff --git a/tests/testMultiTypeTable.m b/tests/testMultiTypeTable.m index ddc1634de..504198ac6 100644 --- a/tests/testMultiTypeTable.m +++ b/tests/testMultiTypeTable.m @@ -6,8 +6,6 @@ % We use an example multi-type table from the backgrounds class for the % example calculation "DPPCStandardLayers.m" % -% Paul Sharp 01/02/23 -% %% Declare properties and parameters properties (TestParameter) @@ -20,18 +18,20 @@ {'Four params', allowedTypes.Constant, 'Back Par 1', 'Back Par 2'},... {'Five params', allowedTypes.Data.value, 'Back Par 1', 'Back Par 2', 'Back Par 3'},... {'Six params', allowedTypes.Function.value, 'Back Par 1', 'Back Par 2', 'Back Par 3', 'Back Par 4'},... - {'Full background', allowedTypes.Data.value, 'Back Par 1', 'Back Par 2', 'Back Par 3', 'Back Par 4', 'Back Par 5'},... - {'Overfilled background', allowedTypes.Constant.value, 'Back Par 1', 'Back Par 2', 'Back Par 3', 'Back Par 4', 'Back Par 5', 'Back Par 6'}} % Inputs for "addRow" - - addedRow = {{'New background 1',allowedTypes.Constant.value,'','','','',''},... - {'Added background',allowedTypes.Constant.value,'','','','',''},... - {'Name and Type',allowedTypes.Data.value,'','','','',''},... - {'Three params',allowedTypes.Function.value,'Back Par 1','','','',''},... - {'Four params',allowedTypes.Constant.value,'Back Par 1','Back Par 2','','',''},... - {'Five params',allowedTypes.Data.value,'Back Par 1','Back Par 2','Back Par 3','',''},... - {'Six params',allowedTypes.Function.value,'Back Par 1','Back Par 2','Back Par 3','Back Par 4',''},... - {'Full background', allowedTypes.Data.value, 'Back Par 1', 'Back Par 2','Back Par 3', 'Back Par 4', 'Back Par 5'},... - {'Overfilled background', allowedTypes.Constant.value, 'Back Par 1', 'Back Par 2','Back Par 3', 'Back Par 4', 'Back Par 5'}} % Resulting additional rows from "addRow" + {'Seven params', allowedTypes.Constant.value, 'Back Par 1', 'Back Par 2', 'Back Par 3', 'Back Par 4', 'Back Par 5'},... + {'Full background', allowedTypes.Data.value, 'Back Par 1', 'Back Par 2', 'Back Par 3', 'Back Par 4', 'Back Par 5', 'Back Par 6'},... + {'Overfilled background', allowedTypes.Function.value, 'Back Par 1', 'Back Par 2', 'Back Par 3', 'Back Par 4', 'Back Par 5', 'Back Par 6', 'Back Par 7'}} % Inputs for "addRow" + + addedRow = {{'New background 1',allowedTypes.Constant.value,'','','','','',''},... + {'Added background',allowedTypes.Constant.value,'','','','','',''},... + {'Name and Type',allowedTypes.Data.value,'','','','','',''},... + {'Three params',allowedTypes.Function.value,'Back Par 1','','','','',''},... + {'Four params',allowedTypes.Constant.value,'Back Par 1','Back Par 2','','','',''},... + {'Five params',allowedTypes.Data.value,'Back Par 1','Back Par 2','Back Par 3','','',''},... + {'Six params',allowedTypes.Function.value,'Back Par 1','Back Par 2','Back Par 3','Back Par 4','',''},... + {'Seven params',allowedTypes.Constant.value,'Back Par 1','Back Par 2','Back Par 3','Back Par 4','Back Par 5',''},... + {'Full background', allowedTypes.Data.value, 'Back Par 1', 'Back Par 2','Back Par 3', 'Back Par 4', 'Back Par 5', 'Back Par 6'},... + {'Overfilled background', allowedTypes.Function.value, 'Back Par 1', 'Back Par 2','Back Par 3', 'Back Par 4', 'Back Par 5', 'Back Par 6'}} % Resulting additional rows from "addRow" end properties @@ -48,9 +48,9 @@ function initialiseTable(testCase) % Set up a types table with a single row of empty strings - sz = [0 7]; - tableTypes = {'string','string','string','string','string','string','string'}; - tableNames = {'Name','Type','Value 1','Value 2','Value 3','Value 4','Value 5'}; + sz = [0 8]; + tableTypes = {'string','string','string','string','string','string','string','string'}; + tableNames = {'Name','Type','Source','Value 1','Value 2','Value 3','Value 4','Value 5'}; testCase.initialTable = table('Size',sz,'VariableTypes',tableTypes,'VariableNames',tableNames); end @@ -64,9 +64,9 @@ function initialiseMultiTypeTable(testCase) % This example is used in the backgrounds class for the % example calculation "DPPCStandardLayers.m" testCase.exampleTable = multiTypeTable(); - testCase.exampleTable.varTable(1,:) = {'Background D2O', allowedTypes.Constant.value, 'Backs par 1','','','',''}; - testCase.exampleTable.varTable(2,:) = {'Background SMW',allowedTypes.Constant.value,'Backs par SMW','','','',''}; - testCase.exampleTable.varTable(3,:) = {'Background H2O',allowedTypes.Constant.value,'Backs par H2O','','','',''}; + testCase.exampleTable.varTable(1,:) = {'Background D2O',allowedTypes.Constant.value,'Backs par 1','','','','',''}; + testCase.exampleTable.varTable(2,:) = {'Background SMW',allowedTypes.Constant.value,'Backs par SMW','','','','',''}; + testCase.exampleTable.varTable(3,:) = {'Background H2O',allowedTypes.Constant.value,'Backs par H2O','','','','',''}; testCase.exampleTable.typesAutoNameString = 'New background'; testCase.numRows = height(testCase.exampleTable.varTable); @@ -83,7 +83,7 @@ function testInitialiseMultiTypeTable(testCase) % Tests Multi-Type Table object can be created testTable = multiTypeTable(); - testCase.verifySize(testTable.varTable, [0 7], 'multiTypeTable does not initialise correctly'); + testCase.verifySize(testTable.varTable, [0 8], 'multiTypeTable does not initialise correctly'); testCase.verifyEqual(testTable.varTable, testCase.initialTable, 'multiTypeTable does not initialise correctly'); testCase.verifyEqual(testTable.typesAutoNameString, testCase.initialTypesAutoNameString, 'multiTypeTable does not initialise correctly'); @@ -120,28 +120,28 @@ function testSetValue(testCase) % than a variable number of arguments. % Row and column indices - testCase.exampleTable.setValue(1, 7, 'Added'); - expectedRow = ["Background D2O" "constant" "Backs par 1" "" "" "" "Added"]; + testCase.exampleTable.setValue(1, 8, 'Added'); + expectedRow = ["Background D2O" "constant" "Backs par 1" "" "" "" "" "Added"]; testCase.verifyEqual(testCase.exampleTable.varTable{1, :}, expectedRow, 'setValue does not work correctly'); % Row name and column index - testCase.exampleTable.setValue('Background SMW', 7, 'Added'); - expectedRow = ["Background SMW" "constant" "Backs par SMW" "" "" "" "Added"]; + testCase.exampleTable.setValue('Background SMW', 8, 'Added'); + expectedRow = ["Background SMW" "constant" "Backs par SMW" "" "" "" "" "Added"]; testCase.verifyEqual(testCase.exampleTable.varTable{2, :}, expectedRow, 'setValue does not work correctly'); % Row index and column name - testCase.exampleTable.setValue(3, 'Value 1', 'Changed'); - expectedRow = ["Background H2O" "constant" "Changed" "" "" "" ""]; + testCase.exampleTable.setValue(3, 'Source', 'Changed'); + expectedRow = ["Background H2O" "constant" "Changed" "" "" "" "" ""]; testCase.verifyEqual(testCase.exampleTable.varTable{3, :}, expectedRow, 'setValue does not work correctly'); % Row and column names testCase.exampleTable.setValue('Background D2O', 'Value 5', 'Changed'); - expectedRow = ["Background D2O" "constant" "Backs par 1" "" "" "" "Changed"]; + expectedRow = ["Background D2O" "constant" "Backs par 1" "" "" "" "" "Changed"]; testCase.verifyEqual(testCase.exampleTable.varTable{1, :}, expectedRow, 'setValue does not work correctly'); % Use name to change name testCase.exampleTable.setValue('Background D2O', 'Name', 'New Name'); - expectedRow = ["New Name" "constant" "Backs par 1" "" "" "" "Changed"]; + expectedRow = ["New Name" "constant" "Backs par 1" "" "" "" "" "Changed"]; testCase.verifyEqual(testCase.exampleTable.varTable{1, :}, expectedRow, 'setValue does not work correctly'); end @@ -224,7 +224,7 @@ function testFindRowIndex(testCase) tableCols = testCase.exampleTable.varTable.Properties.VariableNames; testCase.verifyEqual(multiTypeTable.findRowIndex('Background SMW', tableRows), 2); - testCase.verifyEqual(multiTypeTable.findRowIndex('Value 3', tableCols), 5); + testCase.verifyEqual(multiTypeTable.findRowIndex('Value 3', tableCols), 6); % Check whitespace still matches testCase.verifyEqual(multiTypeTable.findRowIndex(' Background D2O', tableRows), 1); diff --git a/tests/testProjectClass.m b/tests/testProjectClass.m index 955c54f43..dcbccb2c4 100644 --- a/tests/testProjectClass.m +++ b/tests/testProjectClass.m @@ -15,9 +15,7 @@ function setWorkingFolder(testCase) import matlab.unittest.fixtures.WorkingFolderFixture; testCase.applyFixture(WorkingFolderFixture); end - end - methods(TestMethodSetup) function initialiseProject(testCase) testCase.project = projectClass('example'); testCase.parameters = { @@ -420,16 +418,16 @@ function testResolution(testCase) testCase.verifyEqual(testCase.project.resolution.resolutionParams.varTable{1, 2}, 0, 'setResolutionParamLimits method not working'); testCase.verifyEqual(testCase.project.resolution.resolutionParams.varTable{1, 4}, 1, 'setResolutionParamLimits method not working'); % Checks the default resolution parameter - testCase.verifySize(testCase.project.resolution.resolutions.varTable, [1, 7], 'resolution has wrong dimension'); + testCase.verifySize(testCase.project.resolution.resolutions.varTable, [1, 8], 'resolution has wrong dimension'); testCase.verifyEqual(string(testCase.project.resolution.resolutions.varTable{1, :}),... - string({'Resolution 1', allowedTypes.Constant.value, 'Resolution par 1', '', '', '', ''}), 'resolution default'); + string({'Resolution 1', allowedTypes.Constant.value, 'Resolution par 1', '', '', '', '', ''}), 'resolution default'); % Checks that resolution can be added - testCase.project.addResolution('Resolution 2', allowedTypes.Constant,'Resolution par 1','','','',''); - testCase.verifySize(testCase.project.resolution.resolutions.varTable, [2, 7], 'resolution has wrong dimension'); + testCase.project.addResolution('Resolution 2', allowedTypes.Constant,'Resolution par 1','','','','',''); + testCase.verifySize(testCase.project.resolution.resolutions.varTable, [2, 8], 'resolution has wrong dimension'); testCase.verifyEqual(testCase.project.resolution.resolutions.varTable{:, 1}, ["Resolution 1"; "Resolution 2"], 'addResolution method not working'); % Checks that resolution can be removed testCase.project.removeResolution(1); - testCase.verifySize(testCase.project.resolution.resolutions.varTable, [1, 7], 'resolution has wrong dimension'); + testCase.verifySize(testCase.project.resolution.resolutions.varTable, [1, 8], 'resolution has wrong dimension'); testCase.verifyEqual(testCase.project.resolution.resolutions.varTable{:, 1}, "Resolution 2", 'addResolution method not working'); % Checks that resolution value can be modified testCase.project.setResolution(1, 'name', 'New Resolution Name'); @@ -466,16 +464,16 @@ function testBackground(testCase) testCase.verifyEqual(testCase.project.background.backgroundParams.varTable{1, 2}, 0, 'setBackgroundParamLimits method not working'); testCase.verifyEqual(testCase.project.background.backgroundParams.varTable{1, 4}, 1, 'setBackgroundParamLimits method not working'); % Checks the default background parameter - testCase.verifySize(testCase.project.background.backgrounds.varTable, [1, 7], 'background has wrong dimension'); + testCase.verifySize(testCase.project.background.backgrounds.varTable, [1, 8], 'background has wrong dimension'); testCase.verifyEqual(string(testCase.project.background.backgrounds.varTable{1, :}),... - string({'Background 1', allowedTypes.Constant.value, 'Background Param 1', '', '', '', ''}), 'background default'); + string({'Background 1', allowedTypes.Constant.value, 'Background Param 1', '', '', '', '', ''}), 'background default'); % Checks that background can be added testCase.project.addBackground('Background D2O',allowedTypes.Constant.value,'Backs Value D2O'); - testCase.verifySize(testCase.project.background.backgrounds.varTable, [2, 7], 'background has wrong dimension'); + testCase.verifySize(testCase.project.background.backgrounds.varTable, [2, 8], 'background has wrong dimension'); testCase.verifyEqual(testCase.project.background.backgrounds.varTable{:, 1}, ["Background 1"; "Background D2O"], 'addBackground method not working'); % Checks that background can be removed testCase.project.removeBackground(1); - testCase.verifySize(testCase.project.background.backgrounds.varTable, [1, 7], 'background has wrong dimension'); + testCase.verifySize(testCase.project.background.backgrounds.varTable, [1, 8], 'background has wrong dimension'); testCase.verifyEqual(testCase.project.background.backgrounds.varTable{:, 1}, "Background D2O", 'addBackground method not working'); % Checks that background value can be modified testCase.project.setBackground(1, 'name', 'Background ACMW'); diff --git a/tests/testProjectConversion/DSPCBilayerProjectClass.mat b/tests/testProjectConversion/DSPCBilayerProjectClass.mat index e8a6139e5..4d0112a96 100644 Binary files a/tests/testProjectConversion/DSPCBilayerProjectClass.mat and b/tests/testProjectConversion/DSPCBilayerProjectClass.mat differ diff --git a/tests/testProjectConversion/monolayerVolumeModelProjectClass.mat b/tests/testProjectConversion/monolayerVolumeModelProjectClass.mat index 7a1e42985..6fc398a81 100644 Binary files a/tests/testProjectConversion/monolayerVolumeModelProjectClass.mat and b/tests/testProjectConversion/monolayerVolumeModelProjectClass.mat differ diff --git a/tests/testResolutionsClass.m b/tests/testResolutionsClass.m index eec8da0ef..0d378b5ef 100644 --- a/tests/testResolutionsClass.m +++ b/tests/testResolutionsClass.m @@ -4,6 +4,7 @@ parameters resolutions resolution + names end methods(TestMethodSetup) @@ -17,17 +18,23 @@ function createResolution(testCase) function createResolutions(testCase) testCase.parameters = { % Name min val max fit? 'Prior Type','mu','sigma' - 'Resolution par 1', 0.01, 0.03, 0.05, false, priorTypes.Uniform.value, 0, Inf; - 'Resolution par 2', 0.1, 0.19, 1.0, true, priorTypes.Gaussian.value, -1, 1; - 'Resolution par 3', 0.2, 0.17, 1.1, false, priorTypes.Uniform.value, 0, Inf; + 'Resolution param 1', 0.01, 0.03, 0.05, false, priorTypes.Uniform.value, 0, Inf; + 'Resolution param 2', 0.1, 0.19, 1.0, true, priorTypes.Gaussian.value, -1, 1; + 'Resolution param 3', 0.2, 0.17, 1.1, false, priorTypes.Uniform.value, 0, Inf; }; testCase.resolutions = { - 'Resolution 1', allowedTypes.Constant.value, 'Resolution par 1', '', '', '', ''; - 'Resolution 2', allowedTypes.Constant.value, 'Resolution par 2', '', '', '', ''; - 'Resolution 3', allowedTypes.Function.value, 'function_name', 'Resolution par 1', 'Resolution par 2', '', ''; - 'Resolution 4', allowedTypes.Data.value, '', '', '', '', ''; + 'Resolution 1', allowedTypes.Constant.value, 'Resolution param 1', '', '', '', '', ''; + 'Resolution 2', allowedTypes.Constant.value, 'Resolution param 2', '', '', '', '', ''; + % Restore this when function resolutions are implemented + %'Resolution 3', allowedTypes.Function.value, 'function_name', 'Resolution param 1', 'Resolution param 2', '', '', ''; + 'Resolution 3', allowedTypes.Data.value, '', '', '', '', '', ''; }; end + + function createTestNames(testCase) + testCase.names.customFileNames = 'function_name'; + testCase.names.dataNames = ''; + end end methods (Test) @@ -43,19 +50,19 @@ function testCreation(testCase) testCase.verifyEqual(string(testResolution.resolutions.varTable{1, :}), ... string(testCase.resolutions(1, :)), 'Start resolution parameter not set correctly'); - testCase.verifySize(testResolution.resolutions.varTable, [1, 7], 'Resolutions has wrong dimension'); + testCase.verifySize(testResolution.resolutions.varTable, [1, 8], 'Resolutions has wrong dimension'); end function testGetNames(testCase) % Tests getNames returns correctly - names = testCase.resolution.getNames(); - testCase.verifyEqual(names, string(testCase.resolutions(1, 1)), 'getNames method not working'); - testCase.verifySize(names, [1, 1], 'Resolution names has wrong dimension'); + resolutionNames = testCase.resolution.getNames(); + testCase.verifyEqual(resolutionNames, string(testCase.resolutions(1, 1)), 'getNames method not working'); + testCase.verifySize(resolutionNames, [1, 1], 'Resolution names has wrong dimension'); testCase.resolution.resolutions.varTable = [testCase.resolution.resolutions.varTable; vertcat(testCase.resolutions(2:end, :))]; - names = testCase.resolution.getNames(); - testCase.verifyEqual(names, convertCharsToStrings(testCase.resolutions(:, 1)), 'getNames method not working'); - testCase.verifySize(names, [size(testCase.resolutions, 1), 1], 'Resolution names has wrong dimension'); + resolutionNames = testCase.resolution.getNames(); + testCase.verifyEqual(resolutionNames, convertCharsToStrings(testCase.resolutions(:, 1)), 'getNames method not working'); + testCase.verifySize(resolutionNames, [size(testCase.resolutions, 1), 1], 'Resolution names has wrong dimension'); end function testAddResolution(testCase) @@ -64,20 +71,22 @@ function testAddResolution(testCase) testCase.resolution.addResolution(); testCase.verifyEqual(string(testCase.resolution.resolutions.varTable{end, :}),... - string({'New Resolution 2', allowedTypes.Constant.value, '', '', '', '', ''}), 'addResolution method not working'); + string({'New Resolution 2', allowedTypes.Constant.value, '', '', '', '', '', ''}), 'addResolution method not working'); testCase.resolution.addResolution('New Resolution'); testCase.verifyEqual(string(testCase.resolution.resolutions.varTable{end, :}),... - string({'New Resolution', allowedTypes.Constant.value, '', '', '', '', ''}), 'addResolution method not working'); + string({'New Resolution', allowedTypes.Constant.value, '', '', '', '', '', ''}), 'addResolution method not working'); testCase.resolution.addResolution(testCase.resolutions{3, 1:5}); testCase.verifyEqual(string(testCase.resolution.resolutions.varTable{end, :}),... string(testCase.resolutions(3, :)), 'addResolution method not working'); - testCase.resolution.addResolution(testCase.resolutions{4, :}); - testCase.verifyEqual(string(testCase.resolution.resolutions.varTable{end, :}),... - string(testCase.resolutions(4, :)), 'addResolution method not working'); - testCase.resolution.addResolution('Resolution 5', allowedTypes.Function, 'function_name', 1, 3); - testCase.verifyEqual(string(testCase.resolution.resolutions.varTable{end, :}),... - ["Resolution 5", string(allowedTypes.Function.value), "function_name", "Resolution par 1", "Resolution par 3", "", ""], ... - 'addResolution method not working'); + % testCase.resolution.addResolution(testCase.resolutions{4, :}); + % testCase.verifyEqual(string(testCase.resolution.resolutions.varTable{end, :}),... + % string(testCase.resolutions(4, :)), 'addResolution method not working'); + % testCase.resolution.addResolution('Resolution 5', allowedTypes.Function, 'function_name', 1, 3); + % testCase.verifyEqual(string(testCase.resolution.resolutions.varTable{end, :}),... + % ["Resolution 5", string(allowedTypes.Function.value), "function_name", "Resolution param 1", "Resolution param 3", "", "", ""], ... + % 'addResolution method not working'); + testCase.verifyWarning(@() testCase.resolution.addResolution("New Resolution 6", allowedTypes.Constant.value, "Resolution param 1", "extra_value", '', '', '', ''), 'warnings:invalidNumberOfInputs'); + testCase.verifyWarning(@() testCase.resolution.addResolution("New Resolution 7", allowedTypes.Data.value, "Resolution param 1", "Resolution param 2", "extra_value", '', '', ''), 'warnings:invalidNumberOfInputs'); testCase.verifyError(@() testCase.resolution.addResolution('New', 'fixed'), exceptions.invalidOption.errorID); testCase.verifyError(@() testCase.resolution.addResolution('New', allowedTypes.Constant), exceptions.invalidNumberOfInputs.errorID); testCase.verifyError(@() testCase.resolution.addResolution('New', allowedTypes.Constant.value, 6), exceptions.indexOutOfRange.errorID); @@ -89,9 +98,11 @@ function testRemoveResolution(testCase) testCase.resolution.removeResolution(3); testCase.verifyEqual(testCase.resolution.resolutions.varTable{:, 1}, ... - ["Resolution 1"; "Resolution 2"; "Resolution 4"], 'removeResolutionParam method not working'); + ["Resolution 1"; "Resolution 2"], 'removeResolution method not working'); + + testCase.resolution.resolutions.varTable = [testCase.resolution.resolutions.varTable; vertcat(testCase.resolutions(end, :))]; testCase.resolution.removeResolution([1, 3]); - testCase.verifyEqual(testCase.resolution.resolutions.varTable{:, 1}, "Resolution 2", 'removeResolutionParam method not working'); + testCase.verifyEqual(testCase.resolution.resolutions.varTable{:, 1}, "Resolution 2", 'removeResolution method not working'); end function testSetResolutionName(testCase) @@ -107,6 +118,10 @@ function testSetResolutionName(testCase) end function testSetResolution(testCase) + import matlab.unittest.fixtures.SuppressedWarningsFixture + testCase.applyFixture(SuppressedWarningsFixture('warnings:invalidNumberOfInputs')) + testCase.applyFixture(SuppressedWarningsFixture('warnings:fieldsCleared')) + % Checks that resolution can be modified testCase.resolution.resolutions.varTable = [testCase.resolution.resolutions.varTable; vertcat(testCase.resolutions(2:end, :))]; testCase.resolution.resolutionParams.varTable = [testCase.resolution.resolutionParams.varTable; vertcat(testCase.parameters(2:end, :))]; @@ -118,28 +133,34 @@ function testSetResolution(testCase) testCase.resolution.setResolution(1, 'type', allowedTypes.Constant.value); testCase.verifyEqual(testCase.resolution.resolutions.varTable{1, 2}, string(allowedTypes.Constant.value), 'setResolutionValue method not working'); - testCase.resolution.setResolution('Resolution 1', 'type', allowedTypes.Function); + testCase.resolution.setResolution('Resolution 1', 'type', allowedTypes.Function.value); testCase.verifyEqual(testCase.resolution.resolutions.varTable{1, 2}, string(allowedTypes.Function.value), 'setResolutionValue method not working'); testCase.verifyError(@() testCase.resolution.setResolution(2, 'type', 'random'), exceptions.invalidOption.errorID); - testCase.resolution.setResolution(3, 'Value1', 'random'); - testCase.verifyEqual(testCase.resolution.resolutions.varTable{3, 3}, "random", 'setResolutionValue method not working'); - testCase.resolution.setResolution('Resolution 3', 'Value1', 'Resolution par 1'); - testCase.verifyEqual(testCase.resolution.resolutions.varTable{3, 3}, "Resolution par 1", 'setResolutionValue method not working'); + testCase.resolution.setResolution('Resolution 2', 'Source', 'Resolution param 1'); + testCase.verifyEqual(testCase.resolution.resolutions.varTable{2, 3}, "Resolution param 1", 'setResolutionValue method not working'); - testCase.resolution.setResolution(2, 'Value2', 'Resolution par 1'); - testCase.verifyEqual(testCase.resolution.resolutions.varTable{2, 4}, "Resolution par 1", 'setResolutionValue method not working'); + testCase.resolution.setResolution(2, 'Value2', 'Resolution param 1'); + testCase.verifyEqual(testCase.resolution.resolutions.varTable{2, 5}, "Resolution param 1", 'setResolutionValue method not working'); testCase.verifyError(@() testCase.resolution.setResolution(2, 'Value2', 'random'), exceptions.nameNotRecognised.errorID); testCase.verifyError(@() testCase.resolution.setResolution(5, 'Value2', 'random'), exceptions.indexOutOfRange.errorID); testCase.verifyError(@() testCase.resolution.setResolution(true, 'Value2', 'random'), exceptions.invalidType.errorID); - testCase.resolution.setResolution(3, 'name', 'New Name', 'type', allowedTypes.Constant, 'value1', 'Resolution par 3', 'value2', ''); + testCase.resolution.setResolution(3, 'name', 'New Name', 'type', allowedTypes.Constant.value, 'source', 'Resolution param 3', 'value1', ''); testCase.verifyEqual(testCase.resolution.resolutions.varTable{3, 1}, "New Name", 'setResolutionValue method not working'); testCase.verifyEqual(testCase.resolution.resolutions.varTable{3, 2}, string(allowedTypes.Constant.value), 'setResolutionValue method not working'); - testCase.verifyEqual(testCase.resolution.resolutions.varTable{3, 3}, "Resolution par 3", 'setResolutionValue method not working'); + testCase.verifyEqual(testCase.resolution.resolutions.varTable{3, 3}, "Resolution param 3", 'setResolutionValue method not working'); testCase.verifyEqual(testCase.resolution.resolutions.varTable{3, 4}, "", 'setResolutionValue method not working'); end + function testSetResolutionWarnings(testCase) + testCase.resolution.resolutions.varTable = [testCase.resolution.resolutions.varTable; vertcat(testCase.resolutions(2:end, :))]; + testCase.resolution.resolutionParams.varTable = [testCase.resolution.resolutionParams.varTable; vertcat(testCase.parameters(2:end, :))]; + + testCase.verifyWarning(@() testCase.resolution.setResolution(1, "Value1", "Resolution param 1"), 'warnings:invalidNumberOfInputs'); + testCase.verifyWarning(@() testCase.resolution.setResolution(3, "Value2", "Resolution param 1"), 'warnings:invalidNumberOfInputs'); + end + function testDisplayResolutionsObject(testCase) % Check that the contents of the resolution are printed paramHeader = {'p', 'Name', 'Min', 'Value', 'Max', 'Fit?'}; @@ -162,7 +183,7 @@ function testDisplayResolutionsObject(testCase) testCase.verifyLength(row, length(paramHeader)); testCase.verifyEqual(row, string({1, testCase.parameters{1, 1:5}}), 'displayResolutionsObject method not working') - paramHeader = {'p', 'Name', 'Type', 'Value 1', 'Value 2', 'Value 3', 'Value 4', 'Value 5'}; + paramHeader = {'p', 'Name', 'Type', 'Source', 'Value 1', 'Value 2', 'Value 3', 'Value 4', 'Value 5'}; displayArray = textscan(display{3},'%s','Delimiter','\r','TextType','string'); displayArray = strip(displayArray{1}); % display table should be height of resolution table plus header and divider row @@ -191,31 +212,31 @@ function testDisplayResolutionsObject(testCase) function testToStruct(testCase) % Checks that class to struct works correctly - expected.resolutionParamNames = {'Resolution par 1'}; + expected.resolutionParamNames = {'Resolution param 1'}; expected.resolutionParamLimits = {[0.0100 0.0500]}; expected.resolutionParamValues = 0.0300; expected.fitResolutionParam = 0; - expected.resolutionParamPriors = {{'Resolution par 1', priorTypes.Uniform.value, 0, Inf}}; + expected.resolutionParamPriors = {{'Resolution param 1', priorTypes.Uniform.value, 0, Inf}}; expected.resolutionNames = "Resolution 1"; expected.resolutionTypes = string(allowedTypes.Constant.value); - expected.resolutionValues = {"Resolution par 1", "", "", "", ""}; + expected.resolutionValues = {"Resolution param 1", "", "", "", "", ""}; testCase.verifyEqual(testCase.resolution.toStruct(), expected, 'toStruct method not working'); testCase.resolution.resolutions.varTable = [testCase.resolution.resolutions.varTable; vertcat(testCase.resolutions(2:3, :))]; testCase.resolution.resolutionParams.varTable = [testCase.resolution.resolutionParams.varTable; vertcat(testCase.parameters(2:3, :))]; - expected.resolutionParamNames = {'Resolution par 1', 'Resolution par 2', 'Resolution par 3'}; + expected.resolutionParamNames = {'Resolution param 1', 'Resolution param 2', 'Resolution param 3'}; expected.resolutionParamLimits = {[0.0100 0.0500], [0.1000 1], [0.2000 1.1000]}; expected.resolutionParamValues = [0.0300, 0.1900, 0.1700]; expected.fitResolutionParam = [0, 1, 0]; - expected.resolutionParamPriors = {{'Resolution par 1', priorTypes.Uniform.value, 0, Inf};... - {'Resolution par 2', priorTypes.Gaussian.value, -1, 1};... - {'Resolution par 3', priorTypes.Uniform.value, 0, Inf}}; + expected.resolutionParamPriors = {{'Resolution param 1', priorTypes.Uniform.value, 0, Inf};... + {'Resolution param 2', priorTypes.Gaussian.value, -1, 1};... + {'Resolution param 3', priorTypes.Uniform.value, 0, Inf}}; expected.resolutionNames = ["Resolution 1"; "Resolution 2"; "Resolution 3"]; expected.resolutionTypes = [string(allowedTypes.Constant.value); string(allowedTypes.Constant.value); - string(allowedTypes.Function.value)]; - expected.resolutionValues = {"Resolution par 1", "", "", "", ""; "Resolution par 2", "", "", "", "";... - "function_name", "Resolution par 1", "Resolution par 2", "", ""}; + string(allowedTypes.Data.value)]; + expected.resolutionValues = {"Resolution param 1", "", "", "", "", ""; "Resolution param 2", "", "", "", "", "";... + "", "", "", "", "", ""}; testCase.verifyEqual(testCase.resolution.toStruct(), expected, 'toStruct method not working'); end end diff --git a/tests/testTableUtilities.m b/tests/testTableUtilities.m index 971e4c0df..0ec3350fe 100644 --- a/tests/testTableUtilities.m +++ b/tests/testTableUtilities.m @@ -20,18 +20,20 @@ {'Four params', allowedTypes.Constant, 'Back Par 1', 'Back Par 2'},... {'Five params', allowedTypes.Data.value, 'Back Par 1', 'Back Par 2', 'Back Par 3'},... {'Six params', allowedTypes.Function.value, 'Back Par 1', 'Back Par 2', 'Back Par 3', 'Back Par 4'},... - {'Full background', allowedTypes.Data.value, 'Back Par 1', 'Back Par 2', 'Back Par 3', 'Back Par 4', 'Back Par 5'},... - {'Overfilled background', allowedTypes.Constant.value, 'Back Par 1', 'Back Par 2', 'Back Par 3', 'Back Par 4', 'Back Par 5', 'Back Par 6'}} % Inputs for "addRow" - - addedRow = {{'New background 1',allowedTypes.Constant.value,'','','','',''},... - {'Added background',allowedTypes.Constant.value,'','','','',''},... - {'Name and Type',allowedTypes.Data.value,'','','','',''},... - {'Three params',allowedTypes.Function.value,'Back Par 1','','','',''},... - {'Four params',allowedTypes.Constant.value,'Back Par 1','Back Par 2','','',''},... - {'Five params',allowedTypes.Data.value,'Back Par 1','Back Par 2','Back Par 3','',''},... - {'Six params',allowedTypes.Function.value,'Back Par 1','Back Par 2','Back Par 3','Back Par 4',''},... - {'Full background', allowedTypes.Data.value, 'Back Par 1', 'Back Par 2','Back Par 3', 'Back Par 4', 'Back Par 5'},... - {'Overfilled background', allowedTypes.Constant.value, 'Back Par 1', 'Back Par 2','Back Par 3', 'Back Par 4', 'Back Par 5'}} % Resulting additional rows from "addRow" + {'Seven params', allowedTypes.Constant.value, 'Back Par 1', 'Back Par 2', 'Back Par 3', 'Back Par 4', 'Back Par 5'},... + {'Full background', allowedTypes.Data.value, 'Back Par 1', 'Back Par 2', 'Back Par 3', 'Back Par 4', 'Back Par 5', 'Back Par 6'},... + {'Overfilled background', allowedTypes.Function.value, 'Back Par 1', 'Back Par 2', 'Back Par 3', 'Back Par 4', 'Back Par 5', 'Back Par 6', 'Back Par 7'}} % Inputs for "addRow" + + addedRow = {{'New background 1',allowedTypes.Constant.value,'','','','','',''},... + {'Added background',allowedTypes.Constant.value,'','','','','',''},... + {'Name and Type',allowedTypes.Data.value,'','','','','',''},... + {'Three params',allowedTypes.Function.value,'Back Par 1','','','','',''},... + {'Four params',allowedTypes.Constant.value,'Back Par 1','Back Par 2','','','',''},... + {'Five params',allowedTypes.Data.value,'Back Par 1','Back Par 2','Back Par 3','','',''},... + {'Six params',allowedTypes.Function.value,'Back Par 1','Back Par 2','Back Par 3','Back Par 4','',''},... + {'Seven params',allowedTypes.Constant.value,'Back Par 1','Back Par 2','Back Par 3','Back Par 4','Back Par 5',''},... + {'Full background', allowedTypes.Data.value, 'Back Par 1', 'Back Par 2','Back Par 3', 'Back Par 4', 'Back Par 5','Back Par 6'},... + {'Overfilled background', allowedTypes.Function.value, 'Back Par 1', 'Back Par 2','Back Par 3', 'Back Par 4', 'Back Par 5', 'Back Par 6', 'Back Par 7'}} % Resulting additional rows from "addRow" end properties @@ -48,9 +50,9 @@ function initialiseTable(testCase) % Set up a types table with a single row of empty strings - sz = [0 7]; - tableTypes = {'string','string','string','string','string','string','string'}; - tableNames = {'Name','Type','Value 1','Value 2','Value 3','Value 4','Value 5'}; + sz = [0 8]; + tableTypes = {'string','string','string','string','string','string','string','string'}; + tableNames = {'Name','Type','Source','Value 1','Value 2','Value 3','Value 4','Value 5'}; testCase.initialTable = table('Size',sz,'VariableTypes',tableTypes,'VariableNames',tableNames); end @@ -64,9 +66,9 @@ function initialiseMultiTypeTable(testCase) % This example is used in the backgrounds class for the % example calculation "DPPCStandardLayers.m" testCase.exampleTable = multiTypeTable(); - testCase.exampleTable.varTable(1,:) = {'Background D2O', allowedTypes.Constant.value, 'Backs par 1','','','',''}; - testCase.exampleTable.varTable(2,:) = {'Background SMW',allowedTypes.Constant.value,'Backs par SMW','','','',''}; - testCase.exampleTable.varTable(3,:) = {'Background H2O',allowedTypes.Constant.value,'Backs par H2O','','','',''}; + testCase.exampleTable.varTable(1,:) = {'Background D2O', allowedTypes.Constant.value, 'Backs par 1','','','','',''}; + testCase.exampleTable.varTable(2,:) = {'Background SMW', allowedTypes.Constant.value, 'Backs par SMW','','','','',''}; + testCase.exampleTable.varTable(3,:) = {'Background H2O', allowedTypes.Constant.value, 'Backs par H2O','','','','',''}; testCase.exampleTable.typesAutoNameString = 'New background'; testCase.numRows = height(testCase.exampleTable.varTable); @@ -84,7 +86,7 @@ function testGetNames(testCase) end function testAddRow(testCase) - newRow = {'New Row',allowedTypes.Constant.value,'','','','',''}; + newRow = {'New Row',allowedTypes.Constant.value,'','','','','',''}; expectedTable = [testCase.exampleTable.varTable; newRow]; testCase.exampleTable.addRow(newRow{:}); @@ -178,7 +180,7 @@ function testFindRowIndex(testCase) tableCols = testCase.exampleTable.varTable.Properties.VariableNames; testCase.verifyEqual(multiTypeTable.findRowIndex('Background SMW', tableRows), 2); - testCase.verifyEqual(multiTypeTable.findRowIndex('Value 3', tableCols), 5); + testCase.verifyEqual(multiTypeTable.findRowIndex('Value 3', tableCols), 6); % Check whitespace still matches testCase.verifyEqual(multiTypeTable.findRowIndex(' Background D2O', tableRows), 1);