function varargout = ARPESView(varargin) % ARPESVIEW M-file for ARPESView.fig % ARPESVIEW, by itself, creates a new ARPESVIEW or raises the existing % singleton*. % H = ARPESVIEW returns the handle to a new ARPESVIEW or the handle to % the existing singleton*. % ARPESVIEW('CALLBACK',hObject,eventData,handles,...) calls the local % function named CALLBACK in ARPESVIEW.M with the given input arguments. % ARPESVIEW('Property','Value',...) creates a new ARPESVIEW or raises the % existing singleton*. Starting from the left, property value pairs are % applied to the GUI before EasyLineSetup_OpeningFunction gets called. An % unrecognized property name or invalid value makes property application % stop. All inputs are passed to ARPESView_OpeningFcn via varargin. % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one % instance to run (singleton)". % See also: GUIDE, GUIDATA, GUIHANDLES % Edit the above text to modify the response to help ARPESView % Last Modified by GUIDE v2.5 03-Mar-2021 15:31:22 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @ARPESView_OpeningFcn, ... 'gui_OutputFcn', @ARPESView_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT % --- Executes just before ARPESView is made visible. function ARPESView_OpeningFcn(hObject,~,handles,varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % varargin command line arguments to ARPESView (see VARARGIN) clear global; global IniDir RunFile CubePos EWin valPre hGUI % choose default command line output for ARPESView handles.output = hObject; % update handles structure guidata(hObject, handles); % initial directory IniDir='X:\'; % run file and pushbutton visibility if exist('C:\ARPES Tools','dir')==7 RunFile='C:\temp\LastRun.h5'; else set(handles.pushbuttonRunFile,'Visible','Off'); end % openGL rendering necessary for R2013a or some graphics drivers try opengl software; end % data cube axis(handles.axesCube,[-1 1 -1 1 -1 1]); set(gca,'layer','top','box','on','Projection','Orthographic','TickLength',[0 0],'XTick',[],'YTick',[],'ZTick',[]); axis square tight; view(-86,6); set(gca,'PlotBoxAspectRatio',[5 1 1]); try set(gca,'boxstyle','full'); end % R2017b CubePos=get(handles.axesCube,'Position'); % initial viewMode value %viewMode=1; % initial iso-energy window EWin=[-0.1 0]; valPre=0; %set(handles.editEnergy,'String',sprintf('%g+-%g',[mean(EWin) diff(EWin)/2])); % Setup panels % - LockSetup global feat_Lock featIni setTo_Lock setToIni % dEWin_Lock dEWinIni dESm_Lock dESmIni % dEWinIni=[]; dEWin_Lock=dEWinIni; dESmIni=[]; dESm_Lock=dESmIni; featIni='Edge'; feat_Lock=featIni; setToIni=0.0; setTo_Lock=setToIni; % - NormSetup global scCoeffIni scCoeff scCoeffIni=0.75; scCoeff=scCoeffIni; % - ImgProcSetup initializes in itself because the image processing is activated by selecting XTra which calls ImgProcSetup % - ViewSetup global FracView FracViewIni gamma gammaIni render renderIni %XRange YRange FracViewIni=[1e-2 1-1e-4]; FracView=FracViewIni; gammaIni=1; gamma=gammaIni; renderIni='Flat'; render=renderIni; % XRange=[]; YRange=[]; % % - NaviSetup % % global hvNorm_Navi hvNormIni kxNorm_Navi kxNormIni thtANorm_Navi thtANormIni thtMNorm_Navi thtMNormIni surfNx % % hvNormIni=0; hvNorm_Navi=hvNormIni; kxNormIni=0; kxNorm_Navi=kxNormIni; thtANormIni=0; thtANorm_Navi=thtANormIni; % % thtMNormIni=0; thtMNorm_Navi=thtMNormIni; surfNx=0; % global surfNx surfNx=[]; % % position of the Kz-transform fields % PosHvKz=get(handles.radiobuttonHvKz,'Position'); PosTextVo=get(handles.textVo,'Position'); PosEditVo=get(handles.editVo,'Position'); % PosSurfNy=get(handles.editSurfNy,'Position'); shift=PosHvKz(2)-PosSurfNy(2); % set(handles.radiobuttonHvKz,'Position',[PosHvKz(1) PosHvKz(2)-shift PosHvKz(3:4)]); % set(handles.textVo,'Position',[PosTextVo(1) PosTextVo(2)-shift PosTextVo(3:4)]); % set(handles.editVo,'Position',[PosEditVo(1) PosEditVo(2)-shift PosEditVo(3:4)]); % % initial state of menus % global valMenuLockPre; valMenuLockPre=1; % GUI handle hGUI=gcf; % --- Outputs from this function are returned to the command line. function varargout = ARPESView_OutputFcn(~,~,handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % Get default command line output from handles structure varargout{1} = handles.output; % --- Executes on button press in pushbuttonDirFile function pushbuttonDirFile_Callback(~,~,handles) % Hint: get(hObject,'Value') returns toggle state of togglebutton2 global FullName IniDir DataFull DataXC FullList % loading filename [filename,pathname]=uigetfile({'*.h5;*.sp2'},'Data File',IniDir); if isequal(filename,0) || isequal(path,0); return; end % return if Cancel pressed IniDir=pathname; FullName=[pathname filename]; % reset data and load file DataFull=[]; DataXC=[]; LoadFile(handles,FullName); % file list % - trim filename to show in menu lenMax=37; if length(FullName)>lenMax TrimName=['...' FullName(max(1,end-(lenMax-4)):end)]; else TrimName=FullName; end % - full- and trimmed-name lists TrimList=get(handles.menuFileList,'String'); if isempty(TrimList); FullList={FullName}; TrimList={TrimName}; else FullList=[{FullName};FullList]; TrimList=[{TrimName};TrimList]; end % remove previous identical filenames for iList=2:size(FullList,1) % [num2str(iList) ' ' FullList{iList} ' ' FullName ' ' num2str(strcmp(FullList{iList},FullName))] if strcmp(FullList{iList},FullName)==1; FullList(iList,:)=[]; TrimList(iList,:)=[]; break; end end % - max number of last files maxList=5; FullList=FullList(1:min(end,maxList)); TrimList=TrimList(1:min(end,maxList)); % - set menu set(handles.menuFileList,'String',TrimList,'Value',1); % --- Executes on selection change in menuFileList. function menuFileList_Callback(hObject,~,handles) % Hints: contents = cellstr(get(hObject,'String')) returns menuFileList contents as cell array % contents{get(hObject,'Value')} returns selected item from menuFileList global DataFull DataXC FullList FullName n=get(hObject,'Value'); FullName=FullList(n); FullName=FullName{1}; % reset data and load file DataFull=[]; DataXC=[]; LoadFile(handles,FullName); % --- Executes on button press in pushbuttonRunFile function pushbuttonRunFile_Callback(~,~,handles) % hObject handle to menuFileList (see GCBO) global RunFile FullName DataFull DataXC % check if exists if exist(RunFile,'file')~=2 msgbox('Run File Inavailable','modal'); return; end FullName=RunFile; % reset data and load file DataFull=[]; DataXC=[]; LoadFile(handles,FullName); % --- Executes on selection change in radiobuttonEqImages. function radiobuttonEqImages_Callback(~,~,handles) % hObject handle to radiobuttonEqImages (see GCBO) global FullName if isempty(FullName); return; else; LoadFile(handles,FullName); end % --- Function to load data file function LoadFile(handles,FullName) % LoadFile loads data file with the full name FullName global Energy Angle ScanFull Scan SWin DataFull DataXC Data Note RawTable HV thtM tltM aDef ScanType ACorr ECorr ... dEWinIni dESmIni EAlign dESm_Lock dEWin_Lock feat_Lock ERange ARange AutoAWin AKx Kx KxRange ... AutoKxWin AKxRange AKxWin IDiv ISubtr CubePos setTo_Lock alpha % RangeIni RangeNorm % clear arrays Kx=[]; IDiv=[]; ISubtr=[]; ScanType=[]; disp('- cleared Kx IDiv ISubtr ScanType') % clear Scan field set(handles.editScan,'String','') % enable summation set(handles.radiobuttonEqImages,'Enable','On') % load file if new filename if isempty(DataFull) try h=waitbar(0.5,'Reading In','Windowstyle','Modal'); [Angle,Energy,ScanFull,DataFull,ep,Note,RawTable]=ReadARPES(FullName); close(h); catch msgbox('Data Input Error','modal'); return; end end Data=DataFull; Scan=ScanFull; % equivalent scans if ~isempty(Scan)&&~all(diff(Scan)) if get(handles.radiobuttonEqImages,'Value')==1 % - cross-correlated summation if isempty(DataXC) h=waitbar(0.5,'Reducing Equivalent Scans','Windowstyle','Modal'); maxLagE=0.2; DataXC=SumScanXC(Energy,Data,maxLagE); close(h) end Data=DataXC; Scan=[]; else % - artificial Scan of the image numbers Scan=1:1:length(ScanFull); ScanType='Number'; end else set(handles.radiobuttonEqImages,'Enable','Off') end % scan name if isempty(ScanType) PosColon=strfind(Note,':'); if ~isempty(PosColon) PosEqual=strfind(Note,'='); PosEqual=PosEqual(PosEqual1 if isequal(ScanType,'Number'); thtM=mean(thtM); else thtM=[]; end end end % tltM tltM=[]; try pos1=strfind(Note,'Tilt = '); pos2=strfind(Note,'Azimuth'); eval(['tltM=' Note(pos1+9:pos2-2) ';']); if length(tltM)>1; tltM=[]; end end % aDef (added at the upgrade to PHOIBOS225) aDef=[]; try pos1=strfind(Note,'ADef = '); pos2=strfind(Note,'Gain'); pos3=strfind(Note,'dt'); % 'Gain' in new files and 'dt' in older files eval(['aDef=' Note(pos1+9:min(pos2,pos3)-2) ';']); if length(aDef)>1; aDef=[]; end end % % adding up tltM and aDef if scalars, otherwise empty % tltM=tltM+aDef; % % adding scalar tltM and aDef to Scan % if isequal(ScanType,'Tilt') % Scan=Scan+tltMAdd+aDefAdd; % end % alpha alpha=20; try pos1=strfind(Note,'alpha'); pos2=strfind(Note,'Grating'); eval(['alpha=' Note(pos1+9:pos2-2) ';']); end % select compatible modes and show Scan range if isempty(Scan)||length(Scan)<2 if get(handles.menuViewMode,'Value')>2; set(handles.menuViewMode,'Value',1); end set(handles.menuViewMode,'String',{'Image';'Angle-Int Img'}) SWin=[0 0.5]; else set(handles.menuViewMode,'String',{'Image';'Angle-Int Img';'Image Series';'Iso-E';'Iso-Angle/Kx'}) SWin=[Scan(1) Scan(end)]; end % select curvature and warping correction modes pos=strfind(Note,'Corr'); if isequal(lower(Note(pos+10:pos+13)),'true') set(handles.radiobuttonCurvatureCorr,'Value',0,'Visible','Off') set(handles.radiobuttonWarpingCorr,'Value',0,'Visible','Off') else % set(handles.radiobuttonCurvatureCorr,'Value',1,'Visible','On') % set(handles.radiobuttonWarpingCorr,'Value',1,'Visible','On') set(handles.radiobuttonCurvatureCorr,'Visible','On') set(handles.radiobuttonWarpingCorr,'Visible','On') % disable curvature correction if HV unknown (edited in raw table) if any(isnan(HV)); set(handles.radiobuttonWarpingCorr,'Value',0,'Visible','Off'); end end % curvature and warping correction % - check if the data already corrected if contains(FullName,'_Export') && ... (get(handles.radiobuttonCurvatureCorr,'Value')==1||get(handles.radiobuttonWarpingCorr,'Value')==1) waitfor(warndlg('Data may be already corrected','')); end % - curvature corrected energy: 2D array if get(handles.radiobuttonCurvatureCorr,'Value')==1 ECorr=CurveCorr(Angle,Energy,ep); else ECorr=repmat(Energy,1,length(Angle)); end % - warping corrected angles: 2D array for images and angle scans/ 3D for hv scans if get(handles.radiobuttonWarpingCorr,'Value')==1 ACorr=WarpCorr(Angle,Energy,HV); else ACorr=repmat(Angle,length(Energy),1); if length(HV)>1; ACorr=repmat(ACorr,[1 1 length(HV)]); end end % % - - correcting average Angle % Angle=mean(ACorr,3); Angle=mean(Angle,1); % angle range and auto window ARange=[min(min(ACorr(:,1,:))) max(max(ACorr(:,end,:)))]; aMin=max(max(ACorr(:,1,:))); aMax=min(min(ACorr(:,end,:))); AutoAWin=[0.95*aMin+0.05*aMax 0.05*aMin+0.95*aMax]; AKx=ACorr; AKxRange=ARange; AKxWin=AutoAWin; % aligned energy and its range % In the case the aligment fails, should it be left here or better disactivate the menu? Left here, consistently with Angle->Kx and Norm/Subtr % set(handles.menuLock,'Value',1) if get(handles.menuLock,'Value')>1 h=waitbar(0.5,'Aligning EF','Windowstyle','Modal'); % waitbar % - alignment eWin=field2num(handles.editLockEF,0); if length(eWin)>1; eWin=linspace(eWin(1),eWin(2),size(Data,3)); end EAlign=AlignEF(Data,ECorr,eWin,dEWin_Lock,dESm_Lock,feat_Lock); EAlign=EAlign+setTo_Lock; % if ~isempty(Fail); uiwait(msgbox(['Warning: Failed to Lock EF in ' num2str(length(Fail)) ' images'],'modal')); end close(h) % close waitbar else EAlign=repmat(ECorr,[1 1 max(1,length(Scan))]); end % - update energy range ERange=[min(min(EAlign(:,1,:))) max(max(EAlign(:,end,:)))]; % ERange=[min(ECorr(1,:)) max(ECorr(end,:))]; % Kx-transform and auto Kx range if selected if get(handles.radiobuttonAKx,'Value')==1 surfNx=str2num(get(handles.editSurfNx,'String')); Kx=Kxx(HV,EAlign,thtM,ACorr,surfNx,alpha); % - Kx range and auto window KxRange=[min(min(Kx(:,1,:))) max(max(Kx(:,end,:)))]; aMin=max(max(Kx(:,1,:))); aMax=min(min(Kx(:,end,:))); AutoKxWin=[0.95*aMin+0.05*aMax 0.05*aMin+0.95*aMax]; AKx=Kx; AKxRange=KxRange; AKxWin=AutoKxWin; end % draw data cube axes(handles.axesCube); cla % - 2D case if isempty(Scan)||length(Scan)<2 axis([0 1 -0.5 0.5 ERange]); set(gca,'Position',[1.01*CubePos(1) CubePos(2) 0.8*CubePos(3:4)],'PlotBoxAspectRatio',[0.5 1 1]); % - 3D case else axis([Scan([1 end]) -0.5 0.5 ERange]); % axis square tight; set(gca,'Position',CubePos,'PlotBoxAspectRatio',[5 1 1]) end % ranges and auto windows % - Angle/Kx if get(handles.radiobuttonAKx,'Value')==0 set(handles.textAKx,'String',[sprintf('%0.1f',ARange(1)) 'max(Scan); return; end if length(SWin)==1; set(handles.editScan,'String',sprintf('%g',SWin)); else set(handles.editScan,'String',sprintf('%g:%g',SWin)); end % re-draw cube DrawCubeSlice(handles) % re-draw the existing view window try Pos=get(hFig,'Position'); createNewFig=0; ProcessView(handles); set(hFig,'Position',Pos); end % --- Executes on edit of editAKx. function editAKx_Callback(hObject,~,handles) global AutoAWin AutoKxWin AKxWin % hFig createNewFig % read in %AKxWin=sort( sscanf( get(hObject,'String'),'%g:%g') ); AKxWin=sort(field2num(hObject)); % check validity and substitute by automatic range if invalid if isempty(AKxWin) if get(handles.radiobuttonAKx,'Value')==0; set(hObject,'String',sprintf('%g:%g',AutoAWin)); else set(hObject,'String',sprintf('%g:%g',AutoKxWin)); end end % display set(hObject,'String',sprintf('%g:%g',AKxWin)) % re-draw cube DrawCubeSlice(handles) % % re-draw the existing view window % try Pos=get(hFig,'Position'); createNewFig=0; ProcessView(handles); set(hFig,'Position',Pos); end % --- Executes on button press in pushbuttonAKxMinus. function pushbuttonAKxMinus_Callback(~,~,handles) global AKxRange AKxWin hFig createNewFig % read in Angle/Kx AKxWin=sort(field2num(handles.editAKx)); % calculate and write new Angle/Kx AKxWin=AKxWin-diff(AKxWin); if AKxWin(1)AKxRange(2); return; end set(handles.editAKx,'String',sprintf('%g:%g',AKxWin)) % re-draw cube DrawCubeSlice(handles) % re-draw the existing view window try Pos=get(hFig,'Position'); createNewFig=0; ProcessView(handles); set(hFig,'Position',Pos); end % --- Executes on selection change in radiobuttonAKx. function radiobuttonAKx_Callback(hObject,~,handles) global HV ECorr ACorr ARange AutoAWin thtM Kx KxRange AutoKxWin AKx AKxRange AKxWin alpha if get(hObject,'Value')==0 set([handles.textSurfNx handles.editSurfNx handles.pushbuttonFindSurfNx],'Visible','Off'); else set([handles.textSurfNx handles.editSurfNx handles.pushbuttonFindSurfNx],'Visible','On'); end if isempty(HV); return; end % return if no data % change between angle and Kx modes if get(hObject,'Value')==0 % - display angle range AKx=ACorr; AKxRange=ARange; AKxWin=AutoAWin; set(handles.textAKx,'String',[sprintf('%0.1f',ARange(1)) 'ERange(2); EWin=[]; msgbox('Check energy-window ranges','modal'); return; end EWin=[eSlice-dE eSlice+dE]; % re-draw cube DrawCubeSlice(handles) % % re-draw the existing view window % try Pos=get(hFig,'Position'); createNewFig=0; ProcessView(handles); set(hFig,'Position',Pos); end % --- Executes on button press in pushbuttonEMinus. % Note: Replacement of malfunctioning Slider function pushbuttonEMinus_Callback(~,~,handles) global ERange EWin hFig createNewFig % read in energy window eStr=get(handles.editEnergy,'String'); pmPos=strfind(deblank(eStr),'+-'); eSlice=str2num(eStr(1:pmPos-1)); dE=str2num(eStr(pmPos+2:end)); % calculate and write new energy window eSlice=eSlice-dE; if eSlice-dEERange(2); return; end % leave the previous window if above the range EWin=[eSlice-dE eSlice+dE]; set(handles.editEnergy,'String',[num2str(eSlice) '+-' num2str(dE)]) % re-draw cube DrawCubeSlice(handles) % re-draw the existing view window try Pos=get(hFig,'Position'); createNewFig=0; ProcessView(handles); set(hFig,'Position',Pos); end % --- Executes on selection change in menuLock. function menuLock_Callback(hObject,~, handles) % Hints: contents = cellstr(get(hObject,'String')) returns menuLock contents as cell array % contents{get(hObject,'Value')} returns selected item from menuLock global hGUI Data HV thtM ACorr ECorr EAlign ERange Kx KxRange AutoKxWin AKxRange AKxWin ... dEWin_Lock dEWinIni dESm_Lock dESmIni feat_Lock featIni setTo_Lock setToIni IDiv ISubtr CubePos Scan alpha % % return if no change in selection % if get(hObject,'Value')==valMenuLockPre; return; else valMenuLockPre=get(hObject,'Value'); end % reset IDiv=[]; ISubtr=[]; disp('- cleared IDiv ISubtr') if get(hObject,'Value')==1 EAlign=repmat(ECorr,[1 1 max(1,length(Scan))]); else % set initial parameters if 'Auto' if get(hObject,'Value')==2 dEWin_Lock=dEWinIni; dESm_Lock=dESmIni; feat_Lock=featIni; setTo_Lock=setToIni; % draw the popup window and wait for initial parameters if 'XTra' else % position of the popup window PosGUI=get(hGUI,'Position'); PosPanel=get(handles.PanelProcessing,'Position'); PosButton=get(hObject,'Position'); xPos_Lock=PosGUI(1)+PosPanel(1)+PosButton(1)+PosButton(3); yPos_Lock=PosGUI(2)+PosPanel(2)+PosButton(2); % popup window h=LockSetup; Pos=get(h,'Position'); Pos=[xPos_Lock yPos_Lock-Pos(4)-30 Pos(3) Pos(4)]; set(h,'Position',Pos,'WindowStyle','modal'); uiwait(h); end % aligned energy and energy range h=waitbar(0.5,'Aligning EF','WindowStyle','Modal'); % open waitbar % - alignment eWin=field2num(handles.editLockEF,0); if length(eWin)>1; eWin=linspace(eWin(1),eWin(2),size(Data,3)); end EAlign=AlignEF(Data,ECorr,eWin,dEWin_Lock,dESm_Lock,feat_Lock); EAlign=EAlign+setTo_Lock; % if ~isempty(Fail); uiwait(msgbox(['Warning: Failed to Lock EF in ' num2str(length(Fail)) ' images'],'modal')); end close(h) % close waitbar end % update energy range ERange=[min(min(EAlign(:,1,:))) max(max(EAlign(:,end,:)))]; set(handles.textEnergy,'String',[sprintf('%0.1f',ERange(1)) '1; eWin=linspace(eWin(1),eWin(2),size(Data,3)); end EAlign=AlignEF(Data,ECorr,eWin,dEWin_Lock,dESm_Lock,feat_Lock); EAlign=EAlign+setTo_Lock; % if ~isempty(Fail); uiwait(msgbox(['Warning: Failed to Lock EF in ' num2str(length(Fail)) ' images'],'modal')); end close(h) % close waitbar % update energy range ERange=[min(min(EAlign(:,1,:))) max(max(EAlign(:,end,:)))]; set(handles.textEnergy,'String',[sprintf('%0.1f',ERange(1)) '1 % h=waitbar(0.5,'Aligning EF','Windowstyle','Modal'); % waitbar % % - parameters and alignment % % eWin=str2num(get(handles.editLockEF,'String')); % eWin=field2num(handles.editLockEF); % [EAlign,dECorr,Fail]=AlignEF(Data,ECorr,eWin,dEWin_Lock,dESm_Lock,feat_Lock); EAlign=EAlign+setTo_Lock; % % if ~isempty(Fail); uiwait(msgbox(['Warning: Failed to Lock EF in ' num2str(length(Fail)) ' images'],'modal')); end % close(h) % close waitbar % else % EAlign=repmat(ECorr,[1 1 max(1,length(Scan))]); % end % end % % update energy range % ERange=[min(min(EAlign(:,1,:))) max(max(EAlign(:,end,:)))]; set(handles.textEnergy,'String',[sprintf('%0.1f',ERange(1)) '1 if isempty(IDiv) h=waitbar(0.5,'Forming Normalization Array','Windowstyle','Modal'); if isempty(RangeNorm); IntEWin=[0.9*ERange(1)+0.1*ERange(2) 0.1*ERange(1)+0.9*ERange(2)]; else IntEWin=RangeNorm; end IDiv=Slice(ACorr,EAlign,Data3,'isoE',IntEWin); close(h) if isempty(IDiv) msgbox('Error: Inconsistent normalization energy window','modal'); return; end IDiv=Gaco2(IDiv,5,0); % HWHM adjusted to suppress uneven sensitivity of the CCD channels IDiv=repmat(IDiv,1,1,size(Data3,1)); IDiv=permute(IDiv,[3 2 1]); end Data3=Data3./IDiv; % subtract angle-integrated spectrum and clip negative values into global output Data3 if scCoeff~=0 if isempty(ISubtr) h=waitbar(0.5,'Forming Subtraction Array','Windowstyle','Modal'); ISubtr=Slice(ACorr,EAlign,Data3,'isoK',AutoAWin); close(h) ISubtr=repmat(ISubtr,1,1,size(Data3,2)); ISubtr=permute(ISubtr,[1 3 2]); end Data3=Data3-scCoeff*ISubtr; if clipNormNeg==1; Data3(Data3<0)=0; end end end % processing and image modes into global output X,Y,Z switch viewMode % % *** image *** (summation of images from 3D data ignores their energy shifts; in principle, should use remapping) case 1 if size(AKx,3)>1; X=mean(AKx(:,:,nS1:nPeriod:nS2),3); else X=AKx; end Y=mean(EAlign(:,:,nS1:nPeriod:nS2),3); Z=mean(Data3(:,:,nS1:nPeriod:nS2),3); % case 2 % *** angle integrated image *** % [Y,X]=IntAngle(mean(Data3(:,:,nS1:nS2),3),Angle,mean(EAlign(:,:,nS1:nS2),3),AKxWin); if ismatrix(AKx); MeanAKx=AKx; else MeanAKx=mean(AKx(:,:,nS1:nPeriod:nS2),3); end [Y,X]=Slice(MeanAKx,mean(EAlign(:,:,nS1:nPeriod:nS2),3),mean(Data3(:,:,nS1:nPeriod:nS2),3),'isoK',AKxWin); Z=[]; % % **** series of images mode **** case 3 % plot images in the selected Scan range if size(AKx,3)>1; A=AKx(:,:,nS1:nPeriod:nS2); else A=AKx; end % if size(EAlign,3)>1; EAlignV=EAlign(:,:,nS1:nPeriod:nS2); else EAlignV=EAlign; end modeMap=get(handles.menuColormap,'Value'); modeMapC=get(handles.menuColormap,'String'); colorScheme=[char(modeMapC(modeMap)) '(256)']; % color scheme nRows=3; nCols=3; ViewSeries(A,EAlign(:,:,nS1:nPeriod:nS2),Scan(nS1:nPeriod:nS2),Data3(:,:,nS1:nPeriod:nS2),nRows,nCols,colorScheme,FracView(1),FracView(2)) X=[]; Y=[]; Z=[]; % % *** iso-E mode *** case 4 % - slice formation waitbar h=waitbar(0.5,'Forming Data Slice','Windowstyle','Modal'); % - slice within EWin if size(ACorr,3)>1; A=ACorr(:,:,nS1:nPeriod:nS2); else A=ACorr; end try [ISliceE,ASliceE]=Slice(A,EAlign(:,:,nS1:nPeriod:nS2),Data3(:,:,nS1:nPeriod:nS2),'isoE',EWin); catch; beep; close(h); return; end % try [ISliceE,ASliceE]=Slice(ACorr,EAlign(:,:,nS1:nPeriod:nS2),Data3(:,:,nS1:nPeriod:nS2),'isoE',EWin); catch; beep; close(h); return; end % - close waitbar close(h) % scan normalization normScanMode=get(handles.menuNormScans,'Value'); switch normScanMode % - no normalization case 1 ISliceN=ISliceE; otherwise % - integral intensity of scans over 90% of angular range nA=size(ISliceE,2); n1=round(0.05*nA); n2=round(0.95*nA); ISliceN=ISliceE(:,n1:n2); ISliceN=sum(ISliceN,2)/(n2-n1+1); % - 2-order smoothing of integral intensity if normalization set to 'Smooth' if normScanMode==3; P=polyfit(Scan(nS1:nPeriod:nS2)',ISliceN,2); ISliceN=polyval(P,Scan(nS1:nPeriod:nS2)'); end % - normalization ISliceN=ISliceE./repmat(ISliceN,1,nA); % % - bilinear over 90% of angular range % [~,Coeffs]=Flat(AngleN,Scan,ISliceN); % [AngleM,ScanM]=meshgrid(Angle,Scan); % ISliceN=ISliceE./(Coeffs(1)*AngleM+Coeffs(2)*ScanM+Coeffs(3)); end % Kx-conversion if switchAKx==0 AKxSliceE=ASliceE; else if isequal(ScanType,'Tilt')||isequal(ScanType,'ADef'); AKxSliceE=Kxx(HV,mean(EWin),thtM,ASliceE,surfNx,alpha); end if isequal(ScanType,'hv'); AKxSliceE=Kxx(HV(nS1:nPeriod:nS2),mean(EWin),thtM,ASliceE,surfNx,alpha); end end % - image output X=AKxSliceE; Y=Scan(nS1:nPeriod:nS2)'; Z=ISliceN; % K-space transformation if Kx activated if switchAKx==1 surfNy=field2num(handles.editSurfNy); % - Tilt scan if isequal(ScanType,'Tilt') Ky=Kyy(HV,mean(EWin),ASliceE,thtM,Scan(nS1:nPeriod:nS2)-surfNy,surfNx,alpha); Y=Ky; end % - ADef scan if isequal(ScanType,'ADef') % Ky=Kyy(HV,mean(EWin),ASliceE,thtM,Scan(nS1:nPeriod:nS2)+tltM-surfNy,surfNx,alpha); ADefM=repmat((Scan(nS1:nPeriod:nS2))',1,size(ASliceE,2)); Ky=0.5124*sqrt(HV-ePhi+mean(EWin)).*sind(tltM+ADefM-surfNy).*cosd(ASliceE+thtMPhys)+2*pi*HV*sind(alpha+thtMPhys).*sind(tltM)/12400; Y=Ky; end % - hv scan if isequal(ScanType,'hv') if get(handles.radiobuttonHvKz,'Value')==1 Vo=field2num(handles.editVo,-10); Kz=Kzz(HV(nS1:nPeriod:nS2),mean(EWin),thtM,ASliceE,tltM+aDef-surfNy,Vo,surfNx,alpha); Y=Kz; end end end % % *** Iso-Angle/Kx mode *** case 5 % angle integration h=waitbar(0.5,'Angle Integrating','Windowstyle','Modal'); % waitbar % [ISliceA,ESliceA]=IntAngle(Data3,Angle,EAlign,AWin); if size(AKx,3)>1; A=AKx(:,:,nS1:nPeriod:nS2); else A=AKx; end try [ISliceA,ESliceA]=Slice(A,EAlign(:,:,nS1:nPeriod:nS2),Data3(:,:,nS1:nPeriod:nS2),'isoK',AKxWin); catch; beep; close(h); return; end close(h) % close waitbar % scan normalization normScanMode=get(handles.menuNormScans,'Value'); ISliceZ=ISliceA'; switch normScanMode % - no normalization case {2,3} % - integral intensity of scans over 80% of energy range nE=size(ISliceZ,2); n1=round(0.1*nE); n2=round(0.9*nE); ISliceN=ISliceZ(:,n1:n2); ISliceN=sum(ISliceN,2)/(n2-n1+1); % - 2-order smoothing of integral intensity if normalization set to 'Smooth' if normScanMode==3; P=polyfit(Scan',ISliceN,2); ISliceN=polyval(P,Scan'); end % - normalization ISliceZ=ISliceZ./repmat(ISliceN,1,nE); end % image data % X=ESliceA'; Y=Scan'; Z=ISliceZ; X=ESliceA'; Y=Scan(nS1:nPeriod:nS2)'; Z=ISliceZ; % interpolation to uniform energy grid if active energy alignment if get(handles.menuLock,'Value')>1 XGrid=linspace(min(X(:,1)),max(X(:,end)),size(X,2)); % energy grid column vector for iScan=1:length(Y) Z(iScan,:)=interp1(X(iScan,:),Z(iScan,:),XGrid); % interpolation to the same energy grid end X=XGrid; end % K-space transformations if Kx activated if get(handles.radiobuttonAKx,'Value')==1 % surfNx=str2num(get(handles.editSurfNx,'String')); % surfNx=field2num(handles.editSurfNx); thtMPhys=thtM+surfNx; % surfNy=str2num(get(handles.editSurfNy,'String')); surfNy=field2num(handles.editSurfNy); kx=mean(AKxWin); % - Tilt scan if isequal(ScanType,'Tilt') Eb=X; TltM=repmat(Y,1,size(X,2))-surfNy; ThtA=asind((kx+2*pi*HV*cosd(alpha+thtMPhys)/12400)./(0.5124*sqrt(HV-ePhi+Eb)))-thtMPhys; Ky=0.5124*sqrt(HV-ePhi+Eb).*sind(TltM).*cosd(ThtA+thtMPhys)+2*pi*HV*sind(alpha+thtMPhys).*sind(TltM)/12400; Y=Ky; end % - ADef scan if isequal(ScanType,'ADef') Eb=X; ADefM=repmat(Y,1,size(X,2))-surfNy; ThtA=asind((kx+2*pi*HV*cosd(alpha+thtMPhys)/12400)./(0.5124*sqrt(HV-ePhi+Eb)))-thtMPhys; Ky=0.5124*sqrt(HV-ePhi+Eb).*sind(tltM+ADefM).*cosd(ThtA+thtMPhys)+2*pi*HV*sind(alpha+thtMPhys).*sind(tltM)/12400; Y=Ky; end % - hv scan if isequal(ScanType,'hv') if get(handles.radiobuttonHvKz,'Value')==1 % Vo=str2num(get(handles.editVo,'String')); Vo=field2num(handles.editVo,-10); Eb=X; HV2=repmat(Y,1,size(X,2)); ThtA=asind((kx+2*pi*HV2*cosd(alpha+thtMPhys)/12400)./(0.5124*sqrt(HV2-ePhi+Eb)))-thtMPhys; Kxy_2=(HV2-ePhi+Eb).*(sind(ThtA+thtMPhys).^2+(sind(tltM+aDef-surfNy).*cosd(ThtA+thtMPhys)).^2); Kz=0.5124*sqrt(HV2+Eb+Vo-Kxy_2)+2*pi*HV2*sind(alpha+thtMPhys)/12400; Y=Kz; end end end end % image filter if viewMode~=2 if get(handles.menuImgProcMode,'Value')==2 dx=mean(mean(diff(X'))); dy=mean(mean(diff(Y))); % - Gaussian pre-smoothing hwPtsX=0.5*presmdX/dx; hwPtsY=0.5*presmdY/dy; Z=Gaco2(Z,hwPtsX,hwPtsY,2*hwPtsX,2*hwPtsY); % - image structure switch structMode case 2 % curvature along X if sharp==0; Z=-1*(DifC(Z',2))'; else; Z=-DiffFlt2(Z','1D',sharp)'; end case 3 % curvature along Y if sharp==0; Z=-1*DifC(Z,2); else; Z=-DiffFlt2(Z,'1D',sharp); end case 4 % curvature along XY if sharp==0; Z=-1*(DifC(Z,2)+(dy/dx)^2*(DifC(Z',2))'); else; Z=-DiffFlt2(Z,'2D',sharp,dx/dy); end end % - Gaussian post-smoothing hwPtsX=0.5*postsmdX/dx; hwPtsY=0.5*postsmdY/dy; Z=Gaco2(Z,hwPtsX,hwPtsY); % - clipping negative values if clipImgProcNeg==1; Z(Z<0)=0; end end end % enable export set(handles.menuExport,'Enable','On') % % *** end 3D block *** % end % % *** plot *** Pos=strfind(FullName,'\'); if isempty(Pos); Pos=strfind(FullName,'/'); end % parsing universal between Windows and Mac/Linux FileName=FullName(Pos(end)+1:end); Opts.FileName=FileName; Opts.Scan=Scan; Opts.ScanType=ScanType; PlotAll(X,Y,Z,Opts,handles) % --- Plot and set callbacks function function PlotAll(X,Y,Z,Opts,handles) global switchAKx FracView render XRange YRange hFig createNewFig gamma ZView % presmdX presmdY structMode sharp postsmdX postsmdY clipImgProcNeg ScanType hIm hXDC hYDC viewMode=get(handles.menuViewMode,'Value'); % reject image series if viewMode==3; return; end % color scheme modeMap=get(handles.menuColormap,'Value'); modeMapC=get(handles.menuColormap,'String'); colorScheme=[char(modeMapC(modeMap)) '(256)']; % scan type ScanType=Opts.ScanType; % deactivate slope readout % set(handles.menuReadout,'Value',1,'Enable','Off'); % set previous or create new figure if createNewFig==0 % try delete(hFig); end % - set previous figure as current figure(hFig) % clf(hFig) % - retrieve previous image axes handle and set it active UserData=get(hFig,'UserData'); hIm=UserData.hIm; axes(hIm) else % - new figure with callbacks hFig=figure('WindowButtonDownFcn',{@window_Zoom,handles},'WindowButtonUpFcn',{@window_H,handles}); % default normalized units end % linear plot if isempty(Z) plot(X,Y); axis tight; set(gca,'TickDir','Out') % image plots else % set image limits % - render 1D-X,Y to 2D-X,Y if size(X,1)==1; XX=repmat(X,size(Y,1),1); else XX=X; end if size(Y,2)==1; YY=repmat(Y,1,size(X,2)); else YY=Y; end % - set NaN outside the limits if ~isempty(XRange); Z(XXXRange(2))=NaN; end if ~isempty(YRange); Z(YYYRange(2))=NaN; end % set contrast % RawZ=Z; ZView=SetContrast(Z,FracView(1),FracView(2),gamma); % if get(handles.menuNorm,'Value')==1; Z=Z*scale; end % different image modes switch viewMode % - image case 1 ImData(X,Y,ZView,render); axis tight; colorbar; eval(['colormap ''' colorScheme '''']) % - iso-E case 4 ImData(X,Y,ZView,render); axis tight; colorbar; eval(['colormap ''' colorScheme '''']) % - Iso-E(Angle) if isequal(ScanType,'Tilt')||isequal(ScanType,'ADef') axis tight equal %set(gca,'YDir','Reverse'); set(handles.menuReadout,'Enable','On'); end % - angle-integrated scan case 5 ImData(X,Y,ZView,render); axis tight; colorbar; eval(['colormap ''' colorScheme '''']) end end % update image axes handle hIm=gca; % limitsOpts.Scan if ~isempty(XRange); xlim(XRange); end if ~isempty(YRange); ylim(YRange); end % title and axes information if switchAKx==0; titleAKx=', Angle='; else titleAKx=', Kx='; end switch viewMode case 1 if isempty(Opts.Scan); titleStr=Opts.FileName; else titleStr=[Opts.FileName ', Scan=' get(handles.editScan,'string')]; end if switchAKx==0; xlabel('Angle (deg)'); else xlabel('K_{x} (1/A)'); end if min(Y)>100; ylabel('E_{k} (eV)'); else ylabel('E_{B} (eV)'); end case 2 if isempty(Opts.Scan); titleStr=[Opts.FileName titleAKx get(handles.editAKx,'string')]; else titleStr=[Opts.FileName ', Scan=' get(handles.editScan,'string') titleAKx get(handles.editAKx,'string')]; end if min(X)>100; xlabel('E_{k} (eV)'); else xlabel('E_{B} (eV)'); end ylabel('Intensity'); case 4 titleStr=[Opts.FileName ', E=' get(handles.editEnergy,'string')]; if switchAKx==0; xlabel('Angle (deg)'); else xlabel('K_{x} (1/A)'); end switch(ScanType) case 'Number'; ylabel('Image Number'); case 'hv'; if get(handles.radiobuttonHvKz,'Value')==0; ylabel('hv (eV)'); else ylabel('K_{z} (1/A)'); end case {'Theta','Azimuth'}; ylabel([ScanType ' (deg)']) case {'Tilt','ADef'}; if switchAKx==0; ylabel([ScanType ' (deg)']); else ylabel('K_{y} (1/A)'); end case {'X','Z'}; ylabel([ScanType ' (mm)']) end case 5 titleStr=[Opts.FileName titleAKx get(handles.editAKx,'string')]; if min(X)>100; xlabel('E_{k} (eV)'); else xlabel('E_{B} (eV)'); end switch(ScanType) case 'Number'; ylabel('Image Number'); case 'hv'; if get(handles.radiobuttonHvKz,'Value')==0; ylabel('hv (eV)'); else ylabel('K_{z} (1/A)'); end case {'Theta','Azimuth'}; ylabel([ScanType ' (deg)']) case {'Tilt','ADef'}; if switchAKx==0; ylabel([ScanType ' (deg)']); else ylabel('K_{y} (1/A)'); end case {'X','Z'}; ylabel([ScanType ' (mm)']) end end if get(handles.menuNorm,'value')>1; titleStr=[titleStr ', Subtr']; end if isequal(get(handles.menuNormScans,'enable'),'on') && get(handles.menuNormScans,'value')~=1 titleStr=[titleStr ', NormScans']; end title(titleStr,'Interpreter','none','fontweight','normal'); % white background set(hFig,'color','w') % user data for Zoom UserData.viewMode=viewMode; UserData.Opts=Opts; UserData.X=X; UserData.Y=Y; UserData.Z=Z; UserData.hIm=hIm; set(hFig,'UserData',UserData) % % *** add XDC/YDC panels *** if viewMode~=2 && viewMode~=3 && get(handles.radiobuttonXYDC,'Value')==1 % switch off the Zoom callback on WindowButtonDownFcn set(hFig,'WindowButtonDownFcn',[]); % switch off resizing (resizing corrupts positioning of the panels) set(hFig,'resize','off') % extend figure for the XYDC panels PosFig=get(hFig,'Position'); sizeFig=max(PosFig([3 4])); set(hFig,'Position',[PosFig(1) PosFig(2)+PosFig(4)-sizeFig sizeFig sizeFig]) % prepare the figure axis square; colorbar('off'); hIm=gca; % remove old and draw new panels set(hIm,'position',[0.1 0.1 0.5 0.5]); % XLim=get(hIm,'XLim'); YLim=get(hIm,'YLim'); % hPlot=plot(hOver,XLim,YLim); set(hPlot,'visible','off') try delete(UserData.hXDC); end; hXDC=axes('position',[0.1 0.7 0.5 0.25],'box','on','XTick',[],'YTick',[]); try delete(UserData.hYDC); end; hYDC=axes('position',[0.7 0.1 0.25 0.5],'box','on','XTick',[],'YTick',[]); % X/Y edit fields hY=uicontrol('Callback',@PlotXYDC,'Style','edit','fontsize',11,'units','normalized','position',[0.65 0.8 0.16 0.04], ... 'string',['-0.1' '+-' sprintf('%0.1f',0.1)]); uicontrol('Style','text','string','Y=','units','normalized','position',[0.61 0.795 0.04 0.04],'BackgroundColor','w','fontsize',11); hX=uicontrol('Callback',@PlotXYDC,'Style','edit','fontsize',11,'units','normalized','position',[0.76 0.625 0.16 0.04], ... 'string',['0.0' '+-' sprintf('%0.1f',0.1)]); uicontrol('Style','text','string','X=','units','normalized','position',[0.72 0.62 0.04 0.04],'BackgroundColor','w','fontsize',11); % set callback on cursor motion set(hFig,'WindowButtonDownFcn',@Ginput_XYDC); % set(hFig,'WindowButtonMotionFcn',@window_XYDC,'BusyAction','Cancel'); % add user data %UserData.RawZ=RawZ; UserData.hIm=hIm; UserData.hYDC=hYDC; UserData.hXDC=hXDC; UserData.hX=hX; UserData.hY=hY; set(hFig,'UserData',UserData) %UserData.hOver=hOver; % plot the ROI-cross and XYDCs PlotXYDC end % --- Executes on button press in radiobuttonXYDC. function radiobuttonXYDC_Callback(hObject, ~, handles) % hObject handle to radiobuttonXYDC (see GCBO) if get(hObject,'Value')==0 set(handles.menuExport,'String',{'Data';'Raw Image';'View Image'}) else set(handles.menuExport,'String',{'Data';'Raw Image';'View Image';'XDC';'YDC'}) end % graphical input of ROI for XYDCs function Ginput_XYDC(~,~,~) global hFig % retrieve user data from the current figure UserData=get(hFig,'UserData'); hIm=UserData.hIm; try hX=UserData.hX; hY=UserData.hY; catch; return; end % return if the previous figure without edit fields % remove previous lines try delete([hLine1 hLine2 hLine3 hLine4]); end %delete(hIm) deleting image makes the function reactive % plot(hIm,[0 1],[0 1]) % current point XY=get(hIm,'CurrentPoint'); x=XY(1,1); y=XY(1,2); % XY=get(hOver,'CurrentPoint'); x=XY(1,1); y=XY(1,2); % return if outside the image XLim=get(hIm,'XLim'); YLim=get(hIm,'YLim'); if xXLim(2) || yYLim(2); return; end % X- and Y-fields xStr=get(hX,'String'); pmPos=strfind(deblank(xStr),'+-'); dX=str2num(xStr(pmPos+2:end)); set(hX,'String',[sprintf('%0.2f+-%0.2f',[x dX])]); yStr=get(hY,'String'); pmPos=strfind(deblank(yStr),'+-'); dY=str2num(yStr(pmPos+2:end)); set(hY,'String',[sprintf('%0.2f+-%0.2f',[y dY])]); % plot the ROI-cross and XYDCs PlotXYDC % plot the ROI-cross and XYDCs function PlotXYDC(~,~,~) global hLine1 hLine2 hLine3 hLine4 hFig XPts XDC YPts YDC % remove previous lines try delete([hLine1 hLine2 hLine3 hLine4]); end % retrieve user data from the current figure UserData=get(hFig,'UserData'); X=UserData.X; Y=UserData.Y; Z=UserData.Z; hIm=UserData.hIm; hXDC=UserData.hXDC; hYDC=UserData.hYDC; hX=UserData.hX; hY=UserData.hY; %hOver=UserData.hOver; % x- and y-windows xStr=get(hX,'String'); pmPos=strfind(deblank(xStr),'+-'); x=str2num(xStr(1:pmPos-1)); dX=abs(str2num(xStr(pmPos+2:end))); if isempty(x*dX); msgbox('Check format X+-dX','modal'); return; end yStr=get(hY,'String'); pmPos=strfind(deblank(yStr),'+-'); y=str2num(yStr(1:pmPos-1)); dY=abs(str2num(yStr(pmPos+2:end))); if isempty(y*dY); msgbox('Check format Y+-dY','modal'); return; end % return if outside the image XLim=get(hIm,'XLim'); YLim=get(hIm,'YLim'); if x+dXXLim(2) || y+dYYLim(2); return; end % cross hLine1=line(hIm,[XLim(1) x-dX x-dX],[y-dY y-dY YLim(1)],'color','g'); hLine2=line(hIm,[x+dX x+dX XLim(2)],[YLim(1) y-dY y-dY ],'color','g'); hLine3=line(hIm,[x+dX x+dX XLim(2)],[YLim(2) y+dY y+dY ],'color','g'); hLine4=line(hIm,[XLim(1) x-dX x-dX],[y+dY y+dY YLim(2)],'color','g'); % XDC panel [XPts,XDC]=Cut(X,Y,Z,'mdc',[y-dY y+dY]); if isempty(XDC); cla(hXDC) else plot(hXDC,XPts,XDC,'linewidth',1); set(hXDC,'xlim',XLim,'xtickmode','auto'); end % YDC panel [YPts,YDC]=Cut(X,Y,Z,'edc',[x-dX x+dX]); if isempty(YDC); cla(hYDC) else plot(hYDC,YDC,YPts,'linewidth',1); set(hYDC,'ylim',YLim,'ytickmode','auto') end % --- Zoom and XY/slope readout function function window_Zoom(~,~,handles) global CurrentXY PSave ha hc hl hFig hGUI createNewFig % return if GUI if isequal(gcf,hGUI); return; end % clear previous line try delete([ha hc hl]); end % retrieve user data from the figure hFig=gcf; UserData=get(hFig,'UserData'); viewMode=UserData.viewMode; Opts=UserData.Opts; X=UserData.X; Y=UserData.Y; Z=UserData.Z; % reject image series if viewMode==3; return; end % keep the plot figure handle which gets spoiled by rbbox hhFig=hFig; % previous limits XLim0=get(gca,'XLim'); YLim0=get(gca,'YLim'); % rbbox and its borders p1=get(gca,'CurrentPoint'); p1x=p1(1,1); p1y=p1(1,2); rbbox; p2=get(gca,'CurrentPoint'); p2x=p2(1,1); p2y=p2(1,2); % XY-coordinates if point click if (p2x-p1x)==0 && (p2y-p1y)==0 % return if the coordinates outside the plot if p1xXLim0(2)||p1yYLim0(2); return; end % readout set to XY if get(handles.menuReadout,'Value')==1 % hc=line(p1x-[-1 1 0 0 0]*diff(XLim0)/20,p1y-[0 0 0 1-1]*diff(YLim0)/20); set(hc,'color','g','linewidth',1.5) % draw cross hold on; hc=plot(p1x,p1y,'+g','markersize',20); hold off ha=annotation('textbox', [0.65, 0.02, 0.35, 0.05],'String',['X=' sprintf('%0.3f',p1x) '; Y=' sprintf('%0.3f',p1y)],'EdgeColor','W','FontSize',11); CurrentXY=[p1x p1y]; % pause(1); delete(hc) return % readout set to Slope else if isempty(PSave) PSave=[p1x p1y]; hold on; hc=plot(p1x,p1y,'*g','markersize',10); hold off else hl=line([PSave(1) p1x],[PSave(2) p1y]); set(hl,'color','g','linewidth',1.5); Fit=polyfit([PSave(1) p1x],[PSave(2) p1y],1); slope=atand(Fit(1)); ha=annotation('textbox', [0.7, 0.02, 0.3, 0.05],'String',['Slope=' sprintf('%0.3f',slope)],'EdgeColor','W','FontSize',11); % pause(1); delete(hl) PSave=[]; end end end % restore the plot figure handle hFig=hhFig; % process current point XLim=sort([p1x p2x]); YLim=sort([p1y p2y]); XLim=[max(XLim(1),XLim0(1)) min(XLim(2),XLim0(2))]; YLim=[max(YLim(1),YLim0(1)) min(YLim(2),YLim0(2))]; % return if rbbox is too small % if diff(XLim)*diff(YLim)==0; return; end if diff(XLim)<0.01*diff(XLim0) || diff(YLim)<0.01*diff(YLim0); return; end % % return if not the last plotted figure % if ~isequal(gcf,hhFig); % hMsg=msgbox('Zooming Active Only in the Last Plot','modal'); pause(2); close(hMsg); return; % end % trimming of images to re-colorscale ZZ=Z; switch viewMode case 1 ZZ(XXLim(2))=NaN; ZZ(YYLim(2))=NaN; case 2 ZZ=[]; case {4,5} if size(Y,2)==1; YY=repmat(Y,1,size(X,2)); else YY=Y; end % 1D vector of angles vs 2D array of k ZZ(XXLim(2))=NaN; ZZ(YYYLim(2))=NaN; % case 5 % [XX,YY]=meshgrid(X,Y); % ZZ(XXLim(2))=NaN; ZZ(YYYLim(2))=NaN; end % draw zoomed figure % close(gcf) % replace previous figure createNewFig=0; PlotAll(X,Y,ZZ,Opts,handles); set(gca,'XLim',XLim,'YLim',YLim) % --- Function to set global handle of the active figure for readout function window_H(~,~,handles) global hFig hGUI % return if GUI if isequal(gcf,hGUI); return; end hFig=gcf; % set XDC/YDC of the figure hAllAxes=findobj(hFig,'Type','axes'); if length(hAllAxes)==1; set(handles.radiobuttonXYDC,'Value',0); else set(handles.radiobuttonXYDC,'Value',1); end % enable slope readout A=daspect; if isequal(A(1),A(2)); set(handles.menuReadout,'Enable','On'); else set(handles.menuReadout,'Value',1,'Enable','Off'); end % --- Executes on selection change in menuColormap. function menuColormap_Callback(~,~,handles) % % colorscheme % global colorScheme % modeMap=get(hObject,'Value'); modeMapC=get(hObject,'String'); colorScheme=[char(modeMapC(modeMap)) '(256)']; % % ['set(gca,''colormap'', ' colorScheme '(256))']; eval(['set(gca,''colormap'', ' colorScheme '(256))']) % does not work % re-draw image global createNewFig createNewFig=0; ProcessView(handles); % --- Executes on selection change in menuReadout. function menuReadout_Callback(hObject,~,~) global PSave if get(hObject,'Value')==2; PSave=[]; end % --- Executes on button press in CloseFigs. function CloseFigs_Callback(~,~,~) % hObject handle to CloseFigs (see GCBO) % handles of all figures global hGUI hPlots=findobj('Type','figure'); % remove the GUI handle hPlots=hPlots(hPlots~=hGUI); % close all plots close(hPlots) % --- Executes on button press in pushbuttonExport. function pushbuttonExport_Callback(~,~,handles) % hObject handle to pushbuttonExport (see GCBO) global Scan Data3 Note EAlign FullName AKx X Y Z ZView XPts XDC YPts YDC global ExpX ExpY ExpZ % share output data % DataX=Data; ECorrX=ECorr; EAlignX=EAlign; ACorrX=ACorr; % check data and activated corrections if isempty(Data3); errordlg('No Data','','modal'); return; end if contains(FullName,'_Exp'); waitfor(warndlg('Data file seems already exported','')); end % filename to export Dots=strfind(FullName,'.'); dot=Dots(end); [filename,pathname]=uiputfile('*.h5','Export As',[FullName(1:dot-1) '_Exp.h5']); if filename~=0; filename=[pathname filename]; else errordlg('Invalid Filename','','modal'); return end % select export mode switch get(handles.menuExport,'Value') % - current data generated by ProcessView (incl. energy alignment and normalization/subtraction) case 1; ExpX=AKx; ExpY=EAlign; ExpZ=Data3; % - current image or plot (empty Z) generated by ProcessView (+ scan normalizaton and image filtering) case 2; ExpX=X; ExpY=Y; ExpZ=Z; % - current image generated by PlotAll (+ contrast enhancement and X/Y ranges) case 3; ExpX=X; ExpY=Y; ExpZ=ZView; % - current XDC case 4; ExpX=XPts; ExpY=XDC; ExpZ=[]; % - current YDC case 5; ExpX=YPts; ExpY=YDC; ExpZ=[]; end % remapping % - linear plots if isempty(ExpZ) % - interpolate if non-equidistant if any(diff(diff(ExpX))~=0) LinX=linspace(ExpX(1),ExpX(end),length(ExpX)); ExpY=interp1(ExpX,ExpY,LinX,'pchip'); ExpX=LinX; end % - data or images else % - remapping (3D data processed sequentally through the images) h=waitbar(0.5,'Remapping Data','Windowstyle','Modal'); [ExpX,ExpY,ExpZ]=Remap(ExpX,ExpY,ExpZ); close(h) end % % conversion to int32 (normalized to use the full resolution of int32) % ExpZ=int32(double(intmax('int32'))*ExpZ/max(max(max(ExpZ))) ); % IGOR's scales xaxis = [ExpX(1) mean(diff(ExpX))]; if get(handles.menuExport,'Value')>=4; scale = [0 0; xaxis]; else yaxis = [ExpY(1) mean(diff(ExpY))]; if get(handles.menuExport,'Value')>=2; scale = [0 0; xaxis; yaxis]; else % if repeated scans (such as hi-stat scans) the original Scan is ScanFull of the repeated parameters and Scan is their sequential numbers scan = [Scan(1) mean(diff(Scan))]; scale = [0 0; xaxis; yaxis; scan]; ExpZ = permute(ExpZ, [3 1 2]); end end % open writing waitbar h=waitbar(0.5,'Saving Data','Windowstyle','Modal'); % delete the file to overwrite which otherwise causes error in h5create if exist(filename,'file'); delete(filename); end % ExpY to ExpZ substitution for linear plots if isempty(ExpZ); ExpZ=ExpY; end % writing h5create(filename, '/Matrix', size(ExpZ)); h5write(filename, '/Matrix', ExpZ); h5writeatt(filename, '/Matrix', 'IGORWaveNote', Note,'TextEncoding', 'system'); h5writeatt(filename, '/Matrix', 'IGORWaveScaling', fliplr(scale)'); % close waitbar close(h) % % --- Executes on button press in pushbuttonExport. % function pushbuttonExport_Callback(~,~,handles) % % hObject handle to pushbuttonExport (see GCBO) % global ScanFull Scan Data3 Note EAlign FullName AKx hFig ExpX ExpY ExpZ % % DataX=Data; ECorrX=ECorr; EAlignX=EAlign; ACorrX=ACorr; % % check data and activated corrections % if isempty(Data3); errordlg('No Data','','modal'); return; end % if contains(FullName,'_Export'); waitfor(warndlg('Data file seems already exported','')); end % % filename to export % Dots=strfind(FullName,'.'); dot=Dots(end); % [filename,pathname]=uiputfile('*.h5','Export As',[FullName(1:dot-1) '_Export.h5']); % if filename~=0; filename=[pathname filename]; % else errordlg('Invalid Filename','','modal'); return; % end % % select export of the current image % if get(handles.menuExport,'Value')==2 % get(hFig,'UserData',UserData); % ExpX=UserData.X; ExpY=UserData.Y; ExpZ=UserData.Z; % % select export of the whole data % else % ExpX=AKx; ExpY=EAlign; ExpZ=Data3; % end % % open waitbar % h=waitbar(0.5,'Remapping Data','Windowstyle','Modal'); % % remapping (3D data processed sequentally through the images) % [ExpX,ExpY,ExpZ]=Remap(ExpX,ExpY,ExpZ); % % % conversion to int32 (normalization to use the full resolution of int32) % % ExpZ=int32(double(intmax('int32'))*ExpZ/max(max(max(ExpZ))) ); % % arrays in the IGOR-compatible format % % repeated Data (any acquisition with ones(XXX)) are saved as a sequence of numbered frames and can no more be summed up with correlation; % % all normal scans are OK because Scan is saved % xaxis = [ExpX(1) mean(diff(ExpX))]; % yaxis = [ExpY(1) mean(diff(ExpY))]; % if isempty(Scan) % scale = [0 0; xaxis; yaxis;]; % else % ExpZ = permute(ExpZ, [3 1 2]); % % if repeated scans (such as hi-stat scans) the original Scan is ScanFull of the repeated parameters and Scan is their sequential numbers % % scan = [Scan(1) mean(diff(Scan))]; % scan = [ScanFull(1) mean(diff(ScanFull))]; % scale = [0 0; xaxis; yaxis; scan]; % end % close(h); h=waitbar(0.5,'Saving Data','Windowstyle','Modal'); % % delete the file to overwrite which otherwise causes error in h5create % if exist(filename,'file'); delete(filename); end % % write into HDF5 file % h5create(filename, '/Matrix', size(ExpZ)); % h5write(filename, '/Matrix', ExpZ); % h5writeatt(filename, '/Matrix', 'IGORWaveNote', Note); % h5writeatt(filename, '/Matrix', 'IGORWaveScaling', fliplr(scale)'); % % close waitbar % close(h); % --- Executes during object deletion, before destroying properties. function figure1_DeleteFcn(~,~,~) % handles of all figures hPlots=findobj('Type','figure'); % close all figures including the GUI close(hPlots) % 07.01.2021 % X,Y,Z from ProcessView are written by PlotAll to UserData of each plot; after zooming, PlotAll updates Z where all values outside the X/Y range are set to NaN % RawZ excluded; contrast-enhanced ImZ deglobalized (it looks like previously zoom applied to already contrast-enhanced data) % Global Z is set only in ProcessView