diff --git a/targetFunctions/common/makeSLDProfiles/makeSLDProfile.m b/targetFunctions/common/makeSLDProfiles/makeSLDProfile.m index 87aaaa3c9..14df77958 100644 --- a/targetFunctions/common/makeSLDProfiles/makeSLDProfile.m +++ b/targetFunctions/common/makeSLDProfiles/makeSLDProfile.m @@ -1,54 +1,75 @@ -function SLDProfile = makeSLDProfile(bulkIn,bulkOut,layers,ssub,nrepeats) +function SLD = makeSLDProfile(bulkIn,bulkOut,layers,lastRough,nRepeats) -numberOfLayers = size(layers,1); +% Scale the SLDs... +layers(:,2) = layers(:,2) * 1e6; +bulkIn = bulkIn * 1e6; +bulkOut = bulkOut * 1e6; -if numberOfLayers>0 +% Define cdf... +cdf = @(x,mu,r) 0.5*(erf((x-mu)/(sqrt(2)*r)) + 1); + +if size(layers,1) > 0 + % Make a z range for the profile... + % Find the maximum thickness, including any long roughness tail on final layer... totalThickness = sum(layers(:,1)); - totalRange = (totalThickness*nrepeats) + 150; - x = 0:totalRange; - Lays = zeros(length(x),(numberOfLayers*nrepeats)+2); - boxCen = 0; - boxWidth = 100; - - roughnessValues = layers(:,3)'; - roughnessValues(end+1) = ssub; - - nextLayerRoughness = roughnessValues(1); - airBox = asymconvstep(x,boxWidth,boxCen,nextLayerRoughness,nextLayerRoughness,bulkIn); - lastBoxEdge = boxCen + (0.5 * boxWidth); - - for n = 1:nrepeats - for i = 1:numberOfLayers - layerThickness = layers(i,1); - layerSLD = layers(i,2); - layerRoughness = roughnessValues(i); - nextLayerRoughness = roughnessValues(i+1); - thisBoxCentre = lastBoxEdge + (0.5 * layerThickness); - thisBox = asymconvstep(x,layerThickness,thisBoxCentre,layerRoughness,nextLayerRoughness,layerSLD); - Lays(:,i+(numberOfLayers*(n-1))) = thisBox; - lastBoxEdge = thisBoxCentre + (0.5 * layerThickness); + + % Find the point which covers 99% of the outer error function.. + % We need to make sure the total SLD range includes this... + outerLayerTailExtension = (erfcinv(0.01) * sqrt(2) * layers(end,3)); + totalRange = ((totalThickness + outerLayerTailExtension) * nRepeats); + + % Add some extra range at the end for bulk_out... + totalRange = totalRange + 100; + z = 0:totalRange; + + % Repeat the stack according to 'nRepeats'... + layers = repmat(layers,nRepeats,1); + + % Add an aditional 'layer' for the transition to bulk out... + outLayer = [0 bulkOut lastRough]; + layers = [layers; outLayer]; + + % Pre-definitions.... + nLayers = size(layers,1); + allFuncs = zeros(length(z),nLayers); + alpha = zeros(1,nLayers); + lastLayerSLD = bulkIn; + thisPos = 50; + + % Make the profile by adding an error function for each interface + % (we use 'cdf' because it scales more easily than 'erf'...) + for i = 1:nLayers + nextRough = layers(i,3); + nextLayerSLD = layers(i,2); + diff = nextLayerSLD - lastLayerSLD; + + thisFun = cdf(z,thisPos,nextRough); + if diff < 0 + thisFun = -thisFun; end - end - layerRoughness = nextLayerRoughness; - layerThickness = (x(end)-lastBoxEdge)*2; - layerSLD = bulkOut; - nextLayerRoughness = ssub; - thisBoxCentre = x(end); - Lays(:,(numberOfLayers*nrepeats)+1) = asymconvstep(x,layerThickness,thisBoxCentre,layerRoughness,nextLayerRoughness,layerSLD); - - Lays(:,(numberOfLayers*nrepeats)+2) = airBox; - SLD = sum(Lays,2); + allFuncs(:,i) = thisFun(:); + alpha(i) = abs(diff); + thisPos = layers(i,1) + thisPos; + lastLayerSLD = nextLayerSLD; + end + totalFuncs = allFuncs.* alpha; + total = sum(totalFuncs,2); else - x = 0:100; - subsBoxCen = max(x); - airBoxCen = 0; - widths = max(x); - airBox = asymconvstep(x,widths,airBoxCen,ssub,ssub,bulkIn); - subBox = asymconvstep(x,widths,subsBoxCen,ssub,ssub,bulkOut); - SLD = airBox + subBox; + % If we have no layers (i.e. just a bare interface), we only need one + % cdf... + z = 0:100; + pos = 50; + diff = bulkOut - bulkIn; + thisFun = cdf(z,pos,lastRough); + if diff < 1 + thisFun = -thisFun; + end + total = thisFun * abs(diff); end -SLDProfile = [x(:), SLD(:)]; +% Scale the SLD's back to Angstroms... +total = (total + bulkIn) * 1e-6; +SLD = [z(:) total(:)]; -end +end \ No newline at end of file diff --git a/tests/domainsTFReflectivityCalculation/domainsCustomLayersInputs.mat b/tests/domainsTFReflectivityCalculation/domainsCustomLayersInputs.mat index f9267d274..1c337c598 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 180cd5762..c8ac29f11 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 3599cfc9f..0ae3eed35 100644 Binary files a/tests/domainsTFReflectivityCalculation/domainsCustomLayersTFParams.mat and b/tests/domainsTFReflectivityCalculation/domainsCustomLayersTFParams.mat differ diff --git a/tests/domainsTFReflectivityCalculation/domainsCustomXYInputs.mat b/tests/domainsTFReflectivityCalculation/domainsCustomXYInputs.mat index dc096fff1..0e9dfa804 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 1fa8158f7..27fca9462 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 f1437b731..71e7a5e8c 100644 Binary files a/tests/domainsTFReflectivityCalculation/domainsCustomXYTFParams.mat and b/tests/domainsTFReflectivityCalculation/domainsCustomXYTFParams.mat differ diff --git a/tests/domainsTFReflectivityCalculation/domainsStandardLayersInputs.mat b/tests/domainsTFReflectivityCalculation/domainsStandardLayersInputs.mat index 5839b50e6..44c5e15fe 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 1e910a512..a43eed4eb 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 9cb99509d..60d6f3705 100644 Binary files a/tests/domainsTFReflectivityCalculation/domainsStandardLayersTFParams.mat and b/tests/domainsTFReflectivityCalculation/domainsStandardLayersTFParams.mat differ diff --git a/tests/normalTFReflectivityCalculation/absorptionInputs.mat b/tests/normalTFReflectivityCalculation/absorptionInputs.mat index d36cf8b08..f8e617e5f 100644 Binary files a/tests/normalTFReflectivityCalculation/absorptionInputs.mat and b/tests/normalTFReflectivityCalculation/absorptionInputs.mat differ diff --git a/tests/normalTFReflectivityCalculation/absorptionOutputs.mat b/tests/normalTFReflectivityCalculation/absorptionOutputs.mat index dd81ab798..1918a407c 100644 Binary files a/tests/normalTFReflectivityCalculation/absorptionOutputs.mat and b/tests/normalTFReflectivityCalculation/absorptionOutputs.mat differ diff --git a/tests/normalTFReflectivityCalculation/absorptionTFParams.mat b/tests/normalTFReflectivityCalculation/absorptionTFParams.mat index 704fb76a0..b16dc880f 100644 Binary files a/tests/normalTFReflectivityCalculation/absorptionTFParams.mat and b/tests/normalTFReflectivityCalculation/absorptionTFParams.mat differ diff --git a/tests/normalTFReflectivityCalculation/customLayersInputs.mat b/tests/normalTFReflectivityCalculation/customLayersInputs.mat index 0dc110389..1ad786562 100644 Binary files a/tests/normalTFReflectivityCalculation/customLayersInputs.mat and b/tests/normalTFReflectivityCalculation/customLayersInputs.mat differ diff --git a/tests/normalTFReflectivityCalculation/customLayersOutputs.mat b/tests/normalTFReflectivityCalculation/customLayersOutputs.mat index 85763ac22..a9ef3e179 100644 Binary files a/tests/normalTFReflectivityCalculation/customLayersOutputs.mat and b/tests/normalTFReflectivityCalculation/customLayersOutputs.mat differ diff --git a/tests/normalTFReflectivityCalculation/customLayersTFParams.mat b/tests/normalTFReflectivityCalculation/customLayersTFParams.mat index 47cfd09d5..d2b880115 100644 Binary files a/tests/normalTFReflectivityCalculation/customLayersTFParams.mat and b/tests/normalTFReflectivityCalculation/customLayersTFParams.mat differ diff --git a/tests/normalTFReflectivityCalculation/customXYInputs.mat b/tests/normalTFReflectivityCalculation/customXYInputs.mat index 4ce49da31..82f8879c9 100644 Binary files a/tests/normalTFReflectivityCalculation/customXYInputs.mat and b/tests/normalTFReflectivityCalculation/customXYInputs.mat differ diff --git a/tests/normalTFReflectivityCalculation/customXYOutputs.mat b/tests/normalTFReflectivityCalculation/customXYOutputs.mat index 9104c9518..dcd13aecd 100644 Binary files a/tests/normalTFReflectivityCalculation/customXYOutputs.mat and b/tests/normalTFReflectivityCalculation/customXYOutputs.mat differ diff --git a/tests/normalTFReflectivityCalculation/customXYTFParams.mat b/tests/normalTFReflectivityCalculation/customXYTFParams.mat index c0a44bc46..a42078cd5 100644 Binary files a/tests/normalTFReflectivityCalculation/customXYTFParams.mat and b/tests/normalTFReflectivityCalculation/customXYTFParams.mat differ diff --git a/tests/normalTFReflectivityCalculation/standardLayersInputs.mat b/tests/normalTFReflectivityCalculation/standardLayersInputs.mat index 4a4528987..71501cc64 100644 Binary files a/tests/normalTFReflectivityCalculation/standardLayersInputs.mat and b/tests/normalTFReflectivityCalculation/standardLayersInputs.mat differ diff --git a/tests/normalTFReflectivityCalculation/standardLayersOutputs.mat b/tests/normalTFReflectivityCalculation/standardLayersOutputs.mat index c06e873b0..817cae1e7 100644 Binary files a/tests/normalTFReflectivityCalculation/standardLayersOutputs.mat and b/tests/normalTFReflectivityCalculation/standardLayersOutputs.mat differ diff --git a/tests/normalTFReflectivityCalculation/standardLayersTFParams.mat b/tests/normalTFReflectivityCalculation/standardLayersTFParams.mat index cc1b71d4d..71d67aa14 100644 Binary files a/tests/normalTFReflectivityCalculation/standardLayersTFParams.mat and b/tests/normalTFReflectivityCalculation/standardLayersTFParams.mat differ diff --git a/tests/testCommonFunctions/makeSLDProfileOutputs.mat b/tests/testCommonFunctions/makeSLDProfileOutputs.mat index d86cb7fe1..24c138618 100644 Binary files a/tests/testCommonFunctions/makeSLDProfileOutputs.mat and b/tests/testCommonFunctions/makeSLDProfileOutputs.mat differ diff --git a/tests/testProjectConversion/DSPCBilayerProjectClass.mat b/tests/testProjectConversion/DSPCBilayerProjectClass.mat index fd8d35197..c9e9439f3 100644 Binary files a/tests/testProjectConversion/DSPCBilayerProjectClass.mat and b/tests/testProjectConversion/DSPCBilayerProjectClass.mat differ diff --git a/tests/testProjectConversion/DSPCBilayerStructInput.mat b/tests/testProjectConversion/DSPCBilayerStructInput.mat index a8cfa33ac..1a08760a0 100644 Binary files a/tests/testProjectConversion/DSPCBilayerStructInput.mat and b/tests/testProjectConversion/DSPCBilayerStructInput.mat differ diff --git a/tests/testProjectConversion/DSPCBilayerStructOutput.mat b/tests/testProjectConversion/DSPCBilayerStructOutput.mat index 8f110be31..48928fc10 100644 Binary files a/tests/testProjectConversion/DSPCBilayerStructOutput.mat and b/tests/testProjectConversion/DSPCBilayerStructOutput.mat differ diff --git a/tests/testProjectConversion/DSPCBilayerStructOutputWithR1Input.mat b/tests/testProjectConversion/DSPCBilayerStructOutputWithR1Input.mat index ff1fb0d11..34f1e1e45 100644 Binary files a/tests/testProjectConversion/DSPCBilayerStructOutputWithR1Input.mat and b/tests/testProjectConversion/DSPCBilayerStructOutputWithR1Input.mat differ diff --git a/tests/testProjectConversion/monolayerVolumeModelProjectClass.mat b/tests/testProjectConversion/monolayerVolumeModelProjectClass.mat index 5f4c39226..a0c820d88 100644 Binary files a/tests/testProjectConversion/monolayerVolumeModelProjectClass.mat and b/tests/testProjectConversion/monolayerVolumeModelProjectClass.mat differ diff --git a/utilities/plotting/plotRefSLD.m b/utilities/plotting/plotRefSLD.m index 30f251928..f3920ac30 100644 --- a/utilities/plotting/plotRefSLD.m +++ b/utilities/plotting/plotRefSLD.m @@ -43,7 +43,66 @@ function plotRefSLD(project, result, options) data.subRoughs = result.contrastParams.subRoughs; data.resample = projectStruct.resample; data.contrastNames = projectStruct.names.contrasts; + + % If we have air/substrate geometry, modify the SLD profiles slightly + % so that the substrates line up (for custom XY the user does this + % themselves)... + if strcmpi(projectStruct.geometry,'air/substrate') && ~strcmpi(projectStruct.modelType,'custom xy') + data = alignALProfiles(data); + end plotRefSLDHelper(data, false, options.linearX, options.q4, options.showErrorBar, ... options.showGrid, options.showLegend, options.shiftValue); end + + +function data = alignALProfiles(data) +% Aligns the A/L SLD profiles so that the substrates line up by padding the +% start of any shorter than the longest profile.. + +% Get the sld profiles out of data +slds = data.sldProfiles; +resamLays = data.resampledLayers; + +% Find the length of the longest profile... +f = @(x)size(x{:},1); +lengths = arrayfun(f,slds); +maxPos = find(lengths == max(lengths)); + +% If maxPos is an array we have many of equal (leng) length. +% We can just pick one of them... +if length(maxPos) > 1 + maxPos = maxPos(1); +end + +maxLen = lengths(maxPos); +max_XValue = slds{maxPos}(end,1); + +% Get the longest profile... +max_X = slds{maxPos}(:,1); + +% Pad the start of any profiles that are shorter than this +for i = 1:length(slds) + thisSLD = slds{i}; + thisLen = size(thisSLD,1); + if thisLen < maxLen + diffLen = maxLen - thisLen; + pad = zeros(diffLen,1); + newY = [pad ; thisSLD(:,2)]; + slds{i} = [max_X(:,1) newY(:)]; + + % For resampled layers, the pad is just one big layer at the start + thisResam = resamLays{i}; + if ~all(thisResam,'All') % not all zeros + totLength = sum(thisResam(:,1)); + padLength = max_XValue - totLength; + resamPad = [padLength 0 0]; + resamLays{i} = [resamPad ; thisResam]; + end + end +end + +data.sldProfiles = slds; +data.resampledLayers = resamLays; + +end \ No newline at end of file