%% clear all close all clc %% %Replace with location of spectra and script files %cd 'C:\Users...' %% Define wavelength range and spacing for simulations WLS=linspace(1,4,601).'; %% Input the total number of simulations to run. first 1/2 will be mare, second 1/2 will be highlands NumSpectra=100; %% Set abundance limits for spectral endmembers in mixture LowAbunReg=0.0; HighAbunReg=0.25; LowAbunPyr=0.0; HighAbunPyr=0.25; LowAbunMORB=0.0; HighAbunMORB=0.3; rng(0,'twister'); %% Load in optical constants or reflectance data and calculate SSA using Hapke model %Density and grain size of MORB glass densMORB=2.8; dMORB=69E-6; %Low wavelength portion of MORB spectrum (<1.5 microns) Morb_D38A_LowLam=readtable('../data/Morb_D38A_Low_wavelength.txt'); Morb_D38A_LowLam=table2array(Morb_D38A_LowLam); WaterPPM=[1522,762,176,22]; %Total water measured from step-heating experiments %Load in MORB step-wise heating spectra MORB_D38A=dir('../data/*.csv'); %Use the 650C spectrum for the lower wavelength portion of the spectrum MORB_D38A2=fullfile(MORB_D38A(1).folder, MORB_D38A(1).name); MORB_D38A2=readtable(MORB_D38A2); MORB_D38A2=table2array(MORB_D38A2); MORB_D38A2(:,1)=1E4./MORB_D38A2(:,1); %convert from cm^-1 to microns MORB_D38A2(:,2)=MORB_D38A2(:,2)/100; %convert from percent to decimal MORB_D38A2=MORB_D38A2(6481:11648,:); %only use the spectral region of interest MORB_D38A2=flipud(MORB_D38A2); MORB_D38A_MidLam=MORB_D38A2; %Normalize all MORB spectra to the reflectance at 2.6 microns at the %lowest water amount and highest temperature (22 ppm, 800 C) NormalizationValue=0.2363; NormFactor=MORB_D38A_MidLam(end,2)/NormalizationValue; MORB_D38A_MidLam(:,2)=MORB_D38A_MidLam(:,2)./NormFactor; clear MORB_D38A2 %Perform Normalization of MORB spectra at 650, 700, 750, 800 C for i=1:4 MORB_D38A2=fullfile(MORB_D38A(i).folder, MORB_D38A(i).name); %start from 650 C spectrum MORB_D38A2=readtable(MORB_D38A2); MORB_D38A2=table2array(MORB_D38A2); MORB_D38A2(:,1)=1E4./MORB_D38A2(:,1); %convert from cm^-1 to microns MORB_D38A2(:,2)=MORB_D38A2(:,2)/100; %convert from percent to decimal MORB_D38A2=flipud(MORB_D38A2); %Normalize NormFactor=MORB_D38A2(12752,2)/NormalizationValue; %normalize at 2.6 micron MORB_D38A2(:,2)=MORB_D38A2(:,2)./NormFactor; %Stitch with low wavelength spectrum Morb_D38A_LowLam2=Morb_D38A_LowLam; Morb_D38A_LowLam2(:,2)=Morb_D38A_LowLam(:,2)*(MORB_D38A2(6901,2)/0.15); Morb_D38A_LowLam2=Morb_D38A_LowLam2(1:15,:); MORB_D38A2=cat(1,Morb_D38A_LowLam2,MORB_D38A2(6902:end,:)); % Interpolate data to 5 nm spacing between 1 and 4 microns InterpMorb=interp1(MORB_D38A2(:,1),MORB_D38A2(:,2),WLS); if i>1 % Use 650 C spectrum below 2.6 microns to isolate 3 micron feature changes InterpMorb(1:321)=RMORB(1:321,1); else end RMORB(:,i)=InterpMorb; %Use Hapke model to convert from laboratory reflectance to single %scattering albedo using reflectance and scattering asymmetry % factor (p) of 0.81 (see manuscript for details on Hapke model) SSAMORB(:,i)=Hapke_Inverse_Function_Passive(RMORB(:,i),0.81,WLS); end %% Interpolation of MORB Spectra %Set range and resolution for interpolation %(standard is 1 ppm spacing from 0 to 1666 ppm) With 30% maximum MORB %abundance this gives a maximum total water abundance of 500 ppm. WatInterp=linspace(0,1666,1667); for m=1:numel(WLS) %For each wavelength, fit a line to the ESPAT values for each heating step spectrum ESPAT(m,:)=polyfit(WaterPPM(1:4),(1-SSAMORB(m,1:4))./SSAMORB(m,1:4),1); %linear function %For each wavelength, create new synthetic spectra from the linear ESPAT relationship TotalWatInterpESPAT(:,m)=1./(ESPAT(m,1).*WatInterp+ESPAT(m,2)+1); end % Check match of interpolated spectra with real MORB spectra figure(1); RealMorbIndices=[23,177,763,1523]; for k=1:4 scatter(WLS,SSAMORB(:,k),20,'filled'); hold on end for k=1:4 plot(WLS,TotalWatInterpESPAT(RealMorbIndices(k),:),'Color','black','linestyle','-','linewidth',2); end xlabel('Wavelength (\mum)','FontSize',16,'FontWeight','bold'); ylabel('SSA','FontSize',16,'FontWeight','bold'); ax=gca; ax.XLim=[2.5,3.5]; ax.LineWidth = 2; ax.TickDir='in'; ax.FontName='arial'; ax.FontSize=14; ax.FontWeight='bold'; box on grid on %% Load in other spectral endmembers (regolith and pyroxene) densReg=1.8; dReg=32E-6; %Mare Mature Endmember MareMature=readtable('../data/Mare_70181_Spectra.txt'); MareMature=table2array(MareMature); MareMatureRaw=MareMature; %Remove Water and organics Signature by fitting a linear continuum between %2.65 and 3.8 microns [V ind32]=min(abs(MareMature(:,1)-2.65)); [V ind36]=min(abs(MareMature(:,1)-3.8)); SandIQuad=polyfit([MareMature(ind32,1),MareMature(ind36,1)],[MareMature(ind32,2),MareMature(ind36,2)],1); NewRs=MareMature(ind32:ind36,1)*SandIQuad(1)+SandIQuad(2); MareMature(ind32:ind36,2)=NewRs; PassiveMareMature=interp1(MareMature(:,1),MareMature(:,2),WLS); SSAMareMature=Hapke_Inverse_Function_Passive(PassiveMareMature,0.81,WLS); % Mare Immature Endmember MareImmature=readtable('../data/Mare_71061_Spectra.txt'); MareImmature=table2array(MareImmature); MareImmatureRaw=MareImmature; %Remove Water and organics Signature [V ind32]=min(abs(MareImmature(:,1)-2.65)); [V ind36]=min(abs(MareImmature(:,1)-3.8)); SandIQuad=polyfit([MareImmature(ind32,1),MareImmature(ind36,1)],[MareImmature(ind32,2),MareImmature(ind36,2)],1); NewRs=MareImmature(ind32:ind36,1)*SandIQuad(1)+SandIQuad(2); MareImmature(ind32:ind36,2)=NewRs; PassiveMareImmature=interp1(MareImmature(:,1),MareImmature(:,2),WLS); SSAMareImmature=Hapke_Inverse_Function_Passive(PassiveMareImmature,0.81,WLS); % Highlands Mature Endmember HighlandsMature=readtable('../data/Highlands_62231_Spectra.txt'); HighlandsMature=table2array(HighlandsMature); HighlandsMatureRaw=HighlandsMature; %Remove Water and organics Signature [V ind32]=min(abs(HighlandsMature(:,1)-2.65)); [V ind36]=min(abs(HighlandsMature(:,1)-3.8)); SandIQuad=polyfit([HighlandsMature(ind32,1),HighlandsMature(ind36,1)],[HighlandsMature(ind32,2),HighlandsMature(ind36,2)],1); NewRs=HighlandsMature(ind32:ind36,1)*SandIQuad(1)+SandIQuad(2); HighlandsMature(ind32:ind36,2)=NewRs; PassiveHighlandsMature=interp1(HighlandsMature(:,1),HighlandsMature(:,2),WLS); SSAHighlandsMature=Hapke_Inverse_Function_Passive(PassiveHighlandsMature,0.81,WLS); % Highlands Immature Endmember HighlandsImmature=readtable('../data/Highlands_61221_Spectra.txt'); HighlandsImmature=table2array(HighlandsImmature); HighlandsImmatureRaw=HighlandsImmature; %Remove Water and organics Signature [V ind32]=min(abs(HighlandsImmature(:,1)-2.65)); [V ind36]=min(abs(HighlandsImmature(:,1)-3.8)); SandIQuad=polyfit([HighlandsImmature(ind32,1),HighlandsImmature(ind36,1)],[HighlandsImmature(ind32,2),HighlandsImmature(ind36,2)],1); NewRs=HighlandsImmature(ind32:ind36,1)*SandIQuad(1)+SandIQuad(2); HighlandsImmature(ind32:ind36,2)=NewRs; PassiveHighlandsImmature=interp1(HighlandsImmature(:,1),HighlandsImmature(:,2),WLS); SSAHighlandsImmature=Hapke_Inverse_Function_Passive(PassiveHighlandsImmature,0.81,WLS); %Apollo 15 Pyroxene Endmember densPyrox=3.2; dPyrox=70E-6; Apollo15_Pyroxene=readtable('../data/Apollo15Sample15555ReddishBrownPyroxeneB.txt'); Apollo15_Pyroxene=table2array(Apollo15_Pyroxene); Apollo15_PyroxeneRaw=Apollo15_Pyroxene; %Remove Water and organics Signature [V, ind32]=min(abs(Apollo15_Pyroxene(:,1)-3.2)); %only need to remove organics here [V ind36]=min(abs(Apollo15_Pyroxene(:,1)-3.6)); SandIQuad=polyfit([Apollo15_Pyroxene(ind32,1),Apollo15_Pyroxene(ind36,1)],[Apollo15_Pyroxene(ind32,2),Apollo15_Pyroxene(ind36,2)],1); NewRs=Apollo15_Pyroxene(ind32:ind36,1)*SandIQuad(1)+SandIQuad(2); Apollo15_Pyroxene(ind32:ind36,2)=NewRs; PassivePyrox=interp1(Apollo15_Pyroxene(:,1),Apollo15_Pyroxene(:,2),WLS); RPyrox=PassivePyrox; SSAPyrox=Hapke_Inverse_Function_Passive(RPyrox,0.81,WLS); %% %Place densities, grain sizes, and SSAs into arrays rho=1000*[NaN,densMORB,densMORB,densMORB,densMORB,densReg,densReg,densReg,densReg,densPyrox]; d=[NaN,dMORB,dMORB,dMORB,dMORB,dReg,dReg,dReg,dReg,dPyrox]; ConstituentSSAs=[SSAMORB,SSAHighlandsMature,SSAHighlandsImmature,SSAMareMature,SSAMareImmature,SSAPyrox]; %% Create spectral mixtures for j=1:NumSpectra %Use Monte Carlo method to determine abundances in each mixture PCTsMORB(j)=((HighAbunMORB-LowAbunMORB).*rand(1)+LowAbunMORB); %First half of spectra will be mare if j