function hd = coneAnalysis % datachoice = 'visual field'; % for main figure datachoice = 'retina'; % for supplementary figure warning('off','MATLAB:interp1:UsePCHIP') % deactivating the following cbrewer warning: % Warning: INTERP1(...,'CUBIC') will change in a future release. Use INTERP1(...,'PCHIP') instead. % > In interp1>sanitycheckmethod (line 265) % In interp1>parseinputs (line 401) % In interp1 (line 80) % In interpolate_cbrewer (line 31) % In cbrewer (line 101) % In heatmap20180823 (line 21) % global globalparam close all cd(['..\..\data\Fig6 cone data\']) % Define which character sequences identify the different types of data file. filestring.all = 'allCones'; filestring.blue = 'Blue'; filestring.green = 'Green'; filestring.red = 'Red'; filestring.uv = 'UV'; % Manually set max. cone density per square mm, as in Zimmermann et al. maxdensity = 35000; % Manually select data files, and automatically check their names. switch datachoice case 'visual field' fileselection = {'VisualFieldProjection_Red_8dpf.txt', ... 'VisualFieldProjection_Green_8dpf.txt','VisualFieldProjection_Blue_8dpf.txt', ... 'VisualFieldProjection_UV_8dpf.txt','VisualFieldProjection_allCones_8dpf.txt'}; case 'retina' fileselection = {'DensityinRetina_Red_8dpf.txt', ... 'DensityinRetina_Green_8dpf.txt','DensityinRetina_Blue_8dpf.txt', ... 'DensityinRetina_UV_8dpf.txt','DensityinRetina_allCones_8dpf.txt'}; end occurrence = struct('all',[],'blue',[],'green',[],'red',[],'uv',[]); for file = 1:numel(fileselection) occurrence.all = [occurrence.all, ~isempty(strfind(fileselection{file},filestring.all))]; occurrence.blue = [occurrence.blue, ~isempty(strfind(fileselection{file},filestring.blue))]; occurrence.green = [occurrence.green, ~isempty(strfind(fileselection{file},filestring.green))]; occurrence.red = [occurrence.red, ~isempty(strfind(fileselection{file},filestring.red))]; occurrence.uv = [occurrence.uv, ~isempty(strfind(fileselection{file},filestring.uv))]; end % Check whether each type of file was selected exactly once. if sum(occurrence.all) == 0 disp(['None of the file names contain the characters ''',filestring.all,'''.']) elseif sum(occurrence.all) > 1 error(['More than one file name contains the characters ''',filestring.all,'''!']) else datafile.all = fileselection{find(occurrence.all)}; %#ok end if sum(occurrence.blue) == 0 disp(['None of the file names contain the characters ''',filestring.blue,'''.']) elseif sum(occurrence.blue) > 1 error(['More than one file name contains the characters ''',filestring.blue,'''!']) else datafile.blue = fileselection{find(occurrence.blue)}; %#ok end if sum(occurrence.green) == 0 disp(['None of the file names contain the characters ''',filestring.green,'''.']) elseif sum(occurrence.green) > 1 error(['More than one file name contains the characters ''',filestring.green,'''!']) else datafile.green = fileselection{find(occurrence.green)}; %#ok end if sum(occurrence.red) == 0 disp(['None of the file names contain the characters ''',filestring.red,'''.']) elseif sum(occurrence.red) > 1 error(['More than one file name contains the characters ''',filestring.red,'''!']) else datafile.red = fileselection{find(occurrence.red)}; %#ok end if sum(occurrence.uv) == 0 disp(['None of the file names contain the characters ''',filestring.uv,'''.']) elseif sum(occurrence.uv) > 1 error(['More than one file name contains the characters ''',filestring.uv,'''!']) else datafile.uv = fileselection{find(occurrence.uv)}; %#ok end % % Fit centres from FitAzimElev20181217.txt: % leftnormmaxazim = 74.1675; % leftnormmaxelev = 5.9175; % leftnormmeanazim = 74.9488; % leftnormmeanelev = 5.7009; % leftnormratioazim = 74.9490; % leftnormratioelev = 5.7007; % rightnormmaxazim = -72.0633; % rightnormmaxelev = 7.3858; % rightnormmeanazim = -71.1931; % rightnormmeanelev = 7.5766; % rightnormratioazim = -71.1933; % rightnormratioelev = 7.5767; leftazim_body = -80.2647; leftelev_body = 6.0557; rightazim_body = +77.0306; rightelev_body = -1.9776; % Median eye position, pooled once, from positionAnalysis20181217.m: leftmedianazim = +6.2450; rightmedianazim = -9.8760; leftmeanazim = +5.2455; rightmeanazim = -9.8840; leftstdazim = 6.1703; rightstdazim = 6.5227; leftsemazim = 0.2472; rightsemazim = 0.2613; % Median vertical eye position, from figureVertical20190225.m: leftmeanelev = 3.4937; % meanmeanposition.UUH(:,:,1); rightmeanelev = 4.8735; % meanmeanposition.UUH(:,:,2); % Corrected to eye-centred visual field angles: leftazim_eye = abs(leftazim_body - leftmeanazim); leftelev_eye = leftelev_body - leftmeanelev; rightazim_eye = abs(rightazim_body - rightmeanazim); rightelev_eye = rightelev_body - rightmeanelev; % Create one figure panel per file, and all plots on it. datapresent = fieldnames(datafile); % Reorder field names to reflect desired arrangement of panels on figure. datapresent = {datapresent{[4 3 2 5 1]}}; for typeindex = 1:numel(datapresent) conetype = datapresent{typeindex}; textfile = datafile.(conetype); switch datachoice case 'visual field' conedata = importdata(textfile) * maxdensity; case 'retina' conedata = importdata(textfile); end switch datachoice case 'visual field' conedata = rot90(conedata,3); % so up is at top, anterior to the left case 'retina' conedata = rot90(conedata,1); % so up is at bottom, anterior to the right end conedata(conedata==0) = NaN; % consider nonzero data only, i.e. from the true area of the retina switch datachoice case 'visual field' % Undo approximate correction by Takeshi, then apply a more precise one: offsetAzimTakeshi = 8; offsetElevTakeshi = 5; offsetAzimAccurate = abs(leftmedianazim); offsetElevAccurate = leftmeanelev; resolutionAzim = size(conedata,2)/360; resolutionElev = size(conedata,1)/180; discreteShiftAzim = round((offsetAzimTakeshi-offsetAzimAccurate)/resolutionAzim); discreteShiftElev = round((offsetElevTakeshi-offsetElevAccurate)/resolutionElev); nandata = NaN(size(conedata)); % Execute shift (min/max sanitise indices in case shift is negative): nandata(max(1,1-discreteShiftElev):min(end,end-discreteShiftElev), ... max(1,1-discreteShiftAzim):min(end,end-discreteShiftAzim)) = ... conedata(max(1,1+discreteShiftElev):min(end,end+discreteShiftElev), ... max(1,1+discreteShiftAzim):min(end,end+discreteShiftAzim)); % Overwrite original data: conedata = nandata; case 'retina' % Cannot apply correction, as VF filter used by Takeshi is unknown. end % cd(['C:\Users\dehmelt\Dropbox\Documents\MATLAB\', ... % '201808 SphereAnalysis']) % % numelevation = size(conedata,1); % numazimuth = size(conedata,2); % % % The following four values represent the coordinates of the four corners % % of the 2D data sets provided by Baden lab (and are currently unknown). % elevation.max = 90; % elevation.min = -90; % azimuth.max = 180; % azimuth.min = -180; % % Build an (NX*NY x 2) array, where NX is the number of azimuth values, % % NY is the number of elevation values, NX*NY is the total number of data % % points, and for each data point (each row), the azimuth (column 1) and % % elevation (column 2) are listed. % elevation.step = (elevation.max-elevation.min)/(numelevation-1); % azimuth.step = (azimuth.max-azimuth.min)/(numazimuth-1); % elevationlist = elevation.max:-elevation.step:elevation.min; % azimuthlist = azimuth.max:-azimuth.step:azimuth.min; % predictor = []; % for k = 1:numazimuth % predictor = [predictor; ... % repmat(azimuthlist(k),[numelevation 1]), elevationlist']; % end % % One raw data value per data point, might have to be reformatted to match % % the order in which the list of data azimuths/elevations in "predictor" is % % being created. Predictor goes top-to-bottom, left-to-right. % response = conedata(:); % % offset = 0; % amplitude = 1; % meanazimuth = 90; % meanelevation = 0; % concentration = 1; % % globalparam.offset = offset; % globalparam.amplitude = amplitude; % globalparam.concentration = concentration; % % % figure(1) % % imagesc(conedata) % surf(conedata) % shading flat % axis square % colormap(cbrewer('div','PRGn',100)) % hold on % plot([1,numazimuth],[numelevation/2 numelevation/2],'--w','LineWidth',2) % plot([numazimuth/2, numazimuth/2],[1,numelevation],'--w','LineWidth',2) % hold off % set(gca,'XTick',[1,numazimuth*[1/4,1/2,3/4,1]],'XTickLabel',{180 90 0 -90 -180}) % set(gca,'YTick',[1,numelevation*[1/4,1/2,3/4,1]],'YTickLabel',{90 45 0 -45 -90}) % xlabel('azimuth'),ylabel('elevation'),set(gcf,'Color',[1 1 1]) % dataclim = get(gca,'CLim'); hd.cone.fg = figure(1); hd.cone.fg.Position = [400 160 1000 700]; % hd.cone.fg.Position = [500 50 540 380]; hd.cone.fg.Color = [1 1 1]; hd.cone.ax(typeindex,1) = axes; if typeindex < 4 hd.cone.ax(typeindex,1).Position = [.11+(typeindex-1)*.29 .61 hd.cone.fg.Position([4 3])/3500]; else hd.cone.ax(typeindex,1).Position = [.19+(typeindex-4)*.42 .11 hd.cone.fg.Position([4 3])/3500]; end az = 0:180/(size(conedata,1)-1):180; el = -90:180/(size(conedata,2)-1):90; % conedatanonnan = fliplr(flipud(conedata)); conedatanonnan = conedata; conedatanonnan(isnan(conedatanonnan)) = 0; density = conv2(conedatanonnan,fspecial('gaussian',[100 100],3),'same'); % surf(az,el,conv2(conedatanonnan,fspecial('gaussian',[100 100],10),'same')) % shading flat hold on if strcmp(datachoice,'retina') && typeindex == 5 % FD20190829 added as simple correction density = fliplr(density); end imagesc(az,el,density) % if strcmp(conetype,'all') % contour(az,el,density,'LevelStep',1e-1,'Color',.5*[1 1 1]) % else % contour(az,el,density,'LevelStep',3e-2,'Color',.5*[1 1 1]) % end contourlevels = (.1:.1:1) * max(max(density)); % increments = 10%-of-max. contour(az,el,density,contourlevels,'Color',.5*[1 1 1]); hold off % axis square % uistack(hd.cone.ax(typeindex,2),'bottom') % hd.cone.ax(2,2) = copyobj(hd.cone.ax(2,1),hd.cone.fg) hd.cone.ax(typeindex,1).XLim = [0,180]; hd.cone.ax(typeindex,1).YLim = [-90,90]; oldclim = hd.cone.ax(typeindex,1).CLim; % climcutoff = .8; climcutoff = .60; % climcutoff = 0; hd.cone.ax(typeindex,1).CLim = [min(oldclim)+climcutoff*(max(oldclim)-min(oldclim)), ... max(oldclim)]; switch datachoice case 'visual field' hd.cone.ax(typeindex,1).XLabel.String = 'azimuth'; hd.cone.ax(typeindex,1).YLabel.String = 'elevation'; case 'retina' hd.cone.ax(typeindex,1).XLabel.String = 'x (a.u.)'; hd.cone.ax(typeindex,1).YLabel.String = 'y (a.u.)'; end textfilesplit = strsplit(textfile,'_'); switch textfilesplit{2} case 'allCones' densitylabel = 'all cones combined'; case 'Green' densitylabel = 'green cones (mm^{-2})'; case 'Red' densitylabel = 'red cones (mm^{-2})'; case 'Blue' densitylabel = 'blue cones (mm^{-2})'; case 'UV' densitylabel = 'ultraviolet cones'; end % switch textfilesplit{2} % case 'allCones' % densitylabel = {'retinal density','(any cones)'}; % case 'Green' % densitylabel = {'retinal density / mm^{-2}','(green cones)'}; % case 'Red' % densitylabel = {'retinal density','(red cones)'}; % case 'Blue' % densitylabel = {'retinal density','(blue cones)'}; % case 'UV' % densitylabel = {'retinal density','(ultraviolet cones)'}; % end % switch textfilesplit{2} % case 'allCones' % densitylabel = 'density (any cones)'; % case 'Green' % densitylabel = 'density (green cones)'; % case 'Red' % densitylabel = 'density (red cones)'; % case 'Blue' % densitylabel = 'density (blue cones)'; % case 'UV' % densitylabel = 'density (ultraviolet cones)'; % end hd.cone.ax(typeindex,1).Title.String = densitylabel; hd.cone.ax(typeindex,1).Box = 'on'; % hd.cone.ax(typeindex,1).XTick = 0:15:180; % hd.cone.ax(typeindex,1).YTick = -90:15:90; % hd.cone.ax(typeindex,1).XTickLabel = {0,[],[],45,[],[],90,[],[],135,[],[],180}; % hd.cone.ax(typeindex,1).YTickLabel = {-90,[],[],-45,[],[],0,[],[],45,[],[],90}; % hd.cone.ax(typeindex,1).XTick = 0:45:180; % hd.cone.ax(typeindex,1).YTick = -90:45:90; % hd.cone.ax(typeindex,1).XTickLabel = {0,45,90,135,180}; % hd.cone.ax(typeindex,1).YTickLabel = {-90,-45,0,45,90}; hd.cone.ax(typeindex,1).XTick = 0:30:180; hd.cone.ax(typeindex,1).YTick = -90:30:90; switch datachoice case 'visual field' hd.cone.ax(typeindex,1).XTickLabel = {0,[],[],90,[],[],180}; hd.cone.ax(typeindex,1).YTickLabel = {-90,[],[],0,[],[],90}; case 'retina' hd.cone.ax(typeindex,1).XTickLabel = {0,[],[],[],[],[],1}; hd.cone.ax(typeindex,1).YTickLabel = {0,[],[],[],[],[],1}; end hd.cone.ax(typeindex,1).FontSize = 14; hd.cone.ax(typeindex,1).TitleFontSizeMultiplier = 1; hd.cone.ax(typeindex,1).TitleFontWeight = 'bold'; % hd.cone.ax(typeindex,1).Title.Interpreter = 'none'; hd.cone.ax(typeindex,1).Title.Interpreter = 'tex'; % [hd.cone.ax(typeindex,1).XLabel.FontSize, ... % hd.cone.ax(typeindex,1).YLabel.FontSize, ... % hd.cone.ax(typeindex,1).Title.FontSize, ... % ha.cone.ax(typeindex,1).FontSize, hd.cone.ax(typeindex,1).XGrid = 'on'; hd.cone.ax(typeindex,1).YGrid = 'on'; hd.cone.ax(typeindex,1).Layer = 'top'; hold on plot([0,180],[0,0],'--k') plot([90,90],[-90,90],'--k') hold off % % leftnormmaxazimVF = abs(leftnormmaxazim - leftmedianazim); % % leftnormmeanazimVF = abs(leftnormmeanazim - leftmedianazim); % % leftnormratioazimVF = abs(leftnormratioazim - leftmedianazim); % % rightnormmaxazimVF = abs(rightnormmaxazim - rightmedianazim); % % rightnormmeanazimVF = abs(rightnormmeanazim - rightmedianazim); % % rightnormratioazimVF = abs(rightnormratioazim - rightmedianazim); hold on hd.cone.ob(1,1) = plot([153,165],[-65,-65],'k'); hd.cone.ob(1,2) = plot([159,159],[-59,-71],'k'); switch datachoice case 'visual field' hd.cone.ob(1,3) = text(153,-64.5,'A','HorizontalAlignment','right','VerticalAlignment','middle'); hd.cone.ob(1,4) = text(166,-64.5,'P','HorizontalAlignment','left','VerticalAlignment','middle'); hd.cone.ob(1,5) = text(159.2,-59.5,'U','HorizontalAlignment','center','VerticalAlignment','bottom'); hd.cone.ob(1,6) = text(159.2,-69.5,'D','HorizontalAlignment','center','VerticalAlignment','top'); case 'retina' hd.cone.ob(1,3) = text(153,-64.5,'P','HorizontalAlignment','right','VerticalAlignment','middle'); hd.cone.ob(1,4) = text(166,-64.5,'A','HorizontalAlignment','left','VerticalAlignment','middle'); hd.cone.ob(1,5) = text(159.2,-59.5,'D','HorizontalAlignment','center','VerticalAlignment','bottom'); hd.cone.ob(1,6) = text(159.2,-69.5,'U','HorizontalAlignment','center','VerticalAlignment','top'); end hold off % circle.radius = 40/2; % circle.xcentre = leftnormmaxazimVF; % pick preferred measure here % circle.ycentre = leftnormmaxelev; % pick preferred measure here % circle.x = -circle.radius:.1:circle.radius; % circle.y = sqrt(circle.x(1)^2-circle.x.^2); % hold on % plot([circle.xcentre + circle.x, fliplr(circle.xcentre + circle.x)], ... % [circle.ycentre + circle.y, circle.ycentre - circle.y],'-','LineWidth',3,'Color',0*[1 1 1]) % plot([circle.xcentre + circle.x, fliplr(circle.xcentre + circle.x)], ... % [circle.ycentre + circle.y, circle.ycentre - circle.y],'-','LineWidth',2,'Color',1*[1 1 1]) % hold off % boundary.angle = 64; % % centre.azimuth = leftnormmaxazimVF; % % centre.elevation = leftnormmaxelev; % centre.azimuth = rightazim; % centre.elevation = rightelev; % boundary.resolution = .01; % [boundary.azimuth,boundary.elevation] = ... % diskBoundary(centre.azimuth,centre.elevation,boundary.angle,boundary.resolution); % hold on % plot(boundary.azimuth,boundary.elevation,'-','LineWidth',3,'Color',0*[1 1 1]) % plot(boundary.azimuth,boundary.elevation,'-','LineWidth',2,'Color',1*[1 1 1]) % hold off boundary.angle = 40; % centre.azimuth = leftnormmaxazimVF; % centre.elevation = leftnormmaxelev; % centre.azimuth = leftazim_body; % centre.elevation = leftelev_body; centre.azimuth = abs(leftazim_body); centre.elevation = leftelev_body; switch datachoice case 'retina' centre.azimuth = 180-centre.azimuth; centre.elevation = -centre.elevation; end switch datachoice case 'visual field' boundary.resolution = .01; [boundary.azimuth,boundary.elevation] = ... diskBoundary(centre.azimuth,centre.elevation,boundary.angle,boundary.resolution); hold on plot(boundary.azimuth,boundary.elevation,'-','LineWidth',3,'Color',0*[1 1 1]) plot(boundary.azimuth,boundary.elevation,'-','LineWidth',2,'Color',1*[1 1 1]) hold off end mtp = 'o'; msz = 100; mec = [0 0 0]; % mfc = [.2 .8 .2]; % mfa = .2; mfc = 1*[1 1 1]; mfa = .5; hold on % hd.cone.ob(1,7) = scatter(rightazim,rightelev,msz,mtp, ... % 'MarkerEdgeColor',mec,'MarkerFaceColor',mfc,'MarkerFaceAlpha',mfa); hd.cone.ob(1,8) = scatter(centre.azimuth,centre.elevation,msz,mtp, ... 'MarkerEdgeColor',mec,'MarkerFaceColor',mfc,'MarkerFaceAlpha',.8); % hd.cone.ob(1,9) = scatter(leftnormratioazimVF,leftnormratioelev,msz,mtp, ... % 'MarkerEdgeColor',mec,'MarkerFaceColor',mfc,'MarkerFaceAlpha',mfa); % hd.cone.ob(1,10) = scatter(rightnormmaxazimVF,rightnormmaxelev,msz,mtp, ... % 'MarkerEdgeColor',mec,'MarkerFaceColor',mfc,'MarkerFaceAlpha',mfa); % hd.cone.ob(1,11) = scatter(rightnormmeanazimVF,rightnormmeanelev,msz,mtp, ... % 'MarkerEdgeColor',mec,'MarkerFaceColor',mfc,'MarkerFaceAlpha',mfa); % hd.cone.ob(1,12) = scatter(rightnormratioazimVF,rightnormratioelev,msz,mtp, ... % 'MarkerEdgeColor',mec,'MarkerFaceColor',mfc,'MarkerFaceAlpha',mfa); hold off if typeindex == 2 || typeindex == 3 hd.cone.ax(typeindex,1).YLabel.String = []; hd.cone.ax(typeindex,1).YTickLabel = []; end switch conetype case 'blue' colormap(hd.cone.ax(typeindex,1),cbrewer('seq','Blues',100)) case 'green' colormap(hd.cone.ax(typeindex,1),cbrewer('seq','Greens',100)) case 'red' colormap(hd.cone.ax(typeindex,1),cbrewer('seq','Reds',100)) case 'uv' colormap(hd.cone.ax(typeindex,1),cbrewer('seq','Purples',100)) case 'all' colormap(hd.cone.ax(typeindex,1),cbrewer('seq','Greys',100)) end hd.cone.ax(typeindex,2) = axes; hd.cone.ax(typeindex,2).Position = hd.cone.ax(typeindex,1).Position + ... hd.cone.ax(typeindex,1).Position(3) * .28*[1 0 0 0]; hd.cone.cbar(typeindex) = colorbar; hd.cone.ax(typeindex,2).Colormap = hd.cone.ax(typeindex,1).Colormap; hd.cone.ax(typeindex,2).CLim = hd.cone.ax(typeindex,1).CLim; hd.cone.ax(typeindex,2).FontSize = hd.cone.ax(typeindex,1).FontSize; hd.cone.ax(typeindex,2).Color = 'none'; [hd.cone.ax(typeindex,2).XAxis.Visible,hd.cone.ax(typeindex,2).YAxis.Visible] = deal('off'); % colormap(cbrewer('div','PRGn',100)) end hd.cone.ax(1,3) = axes; hd.cone.ax(1,3).Position = [8 0 1 1]; hd.cone.ax(1,3).Color = 'none'; [hd.cone.ax(1,3).XAxis.Visible,hd.cone.ax(1,3).YAxis.Visible] = deal('off'); for typeindex = 1:numel(datapresent) parentpos = hd.cone.ax(typeindex,1).Position; xpos = parentpos(1)+parentpos(3)/2; ypos = parentpos(2)+parentpos(4)*1.128; hd.cone.ob(3,typeindex) = text(xpos, ypos, 'retinal density / mm^{-2}'); % hd.cone.ob(3,typeindex) = text(xpos, ypos, 'retinal density (µm^{-2})'); hd.cone.ob(3,typeindex).FontWeight = 'normal'; hd.cone.ob(3,typeindex).Interpreter = 'tex'; hd.cone.ob(3,typeindex).FontSize = hd.cone.ax(typeindex,1).FontSize; hd.cone.ob(3,typeindex).HorizontalAlignment = 'center'; hd.cone.ob(3,typeindex).VerticalAlignment = 'bottom'; end uistack(hd.cone.ax(1,3),'bottom') hd.cone.ax(1,4) = axes; hd.cone.ax(1,4).Position = [0 0 1 1]; hd.cone.ax(1,4).Color = 'none'; [hd.cone.ax(1,4).XAxis.Visible,hd.cone.ax(1,4).YAxis.Visible] = deal('off'); for typeindex = 1:numel(datapresent) parentpos = hd.cone.ax(typeindex,1).Position; % xpos = parentpos(1)+parentpos(3)*-.18; xpos = parentpos(1)+parentpos(3)*-.23; ypos = parentpos(2)+parentpos(4)*1.30; % hd.cone.ob(3,typeindex) = text(xpos, ypos, 'retinal density / mm^{-2}'); switch typeindex case 1 letterstring = 'a'; case 4 letterstring = 'b'; case 5 letterstring = 'c'; otherwise letterstring = ''; end hd.cone.ob(4,typeindex) = text(xpos, ypos, letterstring); hd.cone.ob(4,typeindex).FontWeight = 'bold'; hd.cone.ob(4,typeindex).Interpreter = 'tex'; hd.cone.ob(4,typeindex).FontSize = hd.cone.ax(typeindex,1).FontSize * 18/14; hd.cone.ob(4,typeindex).HorizontalAlignment = 'right'; hd.cone.ob(4,typeindex).VerticalAlignment = 'top'; end uistack(hd.cone.ax(1,3),'bottom') [hd.cone.ax(:,1).TickLength] = deal([0 0]); % for k = 1:5, hd.cone.cbar(k,1).Position(1) = hd.cone.ax(k,1).Position(1) + .83*hd.cone.ax(k,1).Position(3); end runtime = clock; timestring = ['_', ... num2str(runtime(1),'%.4u'), ... num2str(runtime(2),'%.2u'), ... num2str(runtime(3),'%.2u'), ... '_', ... num2str(runtime(4),'%.2u'), ... num2str(runtime(5),'%.2u'), ... num2str(runtime(6),'%02.0f')]; % savefig(2,['conefigure/',textfilesplit{2},timestring]) % figure(2),print(['conefigure/',textfilesplit{2},timestring],'-depsc') % % figure(2),print(['conefigure/',textfilesplit{2},timestring],'-dtiff') % figure(2),print(['conefigure/',textfilesplit{2},timestring],'-dtiffn') % figure(2),print(['conefigure/',textfilesplit{2},timestring],'-dpng') end function [azimuthOut, elevationOut] = diskBoundary(azimuthIn, elevationIn, angleIn, resolutionIn) centre.azimuth = azimuthIn; centre.elevation = elevationIn; border.angle = angleIn / 2; % convert solid angle ("diameter") to "radius" border.resolution = resolutionIn; % The following equation describes orthodromic (or "great circle") distance as an angle: % arccos(sin(centre.elevation)*sin(border.elevation) + ... % cos(centre.elevation)*cos(border.elevation)*cos(border.azimuth-centre.azimuth)) = angle; % border.elevation = centre.elevation-border.angle/2 : .1 : centre.elevation+border.angle/2; intended = -90 : border.resolution : 90; % intended = (centre.elevation-border.angle) : border.resolution : (centre.elevation+border.angle); % "auxiliary" elevations are explicitly added to guarantee coverage near top/bottom of circle: auxiliary = centre.elevation + border.angle*[-1 1]; % border.elevation = unique([intended,auxiliary]); limit = cosd([centre.elevation-border.angle centre.elevation+border.angle]); % intended = acosd(min(limit) : border.resolution : max(limit)); % % XXX Not sure why the following line leads to half of the curve segments not being computed... % intended = [-acosd(0:border.resolution:1),acosd(1-border.resolution:-border.resolution:0)]; % auxiliary = centre.elevation + border.angle*[-1 1]; border.elevation = unique([intended,auxiliary]); % figure(6) % plot(intended) border.azimuth = centre.azimuth + ... acosd((cosd(border.angle) - sind(centre.elevation)*sind(border.elevation)) ./ ... (cosd(centre.elevation)*cosd(border.elevation))); % Eliminate complex elements... border.azimuth(imag(border.azimuth)~=0) = NaN; % This statement sometimes fails horribly. % border.azimuth(imag(border.azimuth)>1e-5) = NaN; % This statement is silly, but more stable. % ...and compute corresponding values for the second half of the boundary. border.azimuth = [border.azimuth, 2*centre.azimuth-border.azimuth]; border.elevation = [border.elevation, border.elevation]; border.azimuth = mod(border.azimuth+180,360)-180; % jump = diff(border.azimuth) > 10*border.resolution; % border.azimuth(jump) = NaN; % border.elevation(jump) = NaN; azimuthOut = border.azimuth; elevationOut = border.elevation; end % function combinedvalue = vonmisesfisher2param_centre(param,predictor) % % global globalparam % % convention = 'CCW'; % dimension = 3; % radius = 1; % if size(predictor,2) == 2 % predictor(:,3) = radius*ones(size(predictor(:,1))); % end % [x,y,z] = geo2car(predictor(:,1),predictor(:,2),predictor(:,3),convention); % direction = [x,y,z]; % % numberofdistributions = 1; % <--- % value = NaN(size(predictor,1),numberofdistributions); % % for k = 1:numberofdistributions % % meanazimuth = param(2*k-1); % meanelevation = param(2*k); % % offset = globalparam.offset(k); % amplitude = globalparam.amplitude(k); % concentration = globalparam.concentration(k); % % [meanx,meany,meanz] = geo2car(meanazimuth,meanelevation,radius,convention); % meandirection = [meanx,meany,meanz]; % % bessel = concentration / ... % (2*pi * (exp(concentration) - exp(-concentration))); % % normalisation = concentration^(dimension/2 - 1) / ... % ((2*pi)^(dimension/2) * bessel); % % value(:,k) = normalisation * exp(concentration*meandirection*direction')'; % value(:,k) = amplitude * value(:,k) + offset; % % badness = fitpenalty(meanazimuth,-180,180) + ... % fitpenalty(meanelevation,-90,90) + ... % fitpenalty(amplitude,0,Inf) + ... % fitpenalty(concentration,0,Inf); % % value(:,k) = value(:,k) + 1e3*badness; % % end % % combinedvalue = sum(value,2); % % end % function penalty = fitpenalty(value,lowerlimit,upperlimit) % % factor = 1; % % if value < lowerlimit % % penalty = factor*(lowerlimit-value).^1; % % elseif value > upperlimit % % penalty = factor*(value-upperlimit).^1; % % else % % penalty = 0; % % end % % end % function combinedvalue = oneVonMisesFisher(params,predictor) % %TWOVONMISESFISHER Evaluate two overlapping von Mises-Fisher distributions. % % % % VALUE = VONMISESFISHER computes the value of only one(!) % % spherical (p=3) von Mises-Fisher distributions at the chosen location. % % % % It is formatted to match the input/output structure required by the % % built-in non-linear regression function nlinfit. % % convention = 'CW'; % dimension = 3; % radius = 1; % if size(predictor,2) == 2 % predictor(:,3) = radius*ones(size(predictor(:,1))); % end % [x,y,z] = geo2car(predictor(:,1),predictor(:,2),predictor(:,3),convention); % direction = [x,y,z]; % % numberofdistributions = 1; % <-- This is the only difference to "twoVonMisesFisher.m". % value = NaN(size(predictor,1),numberofdistributions); % % for k = 1:numberofdistributions % % offset = params(5*k-4); % amplitude = params(5*k-3); % meanazimuth = params(5*k-2); % meanelevation = params(5*k-1); % % meanelevation = 25; % HACK! % % % [meanx,meany,meanz] = geo2car(meanazimuth,meanelevation,radius,convention); % meandirection = [meanx,meany,meanz]; % % meandirection = geo2car([params((-2:-1)+4*k),radius]); % concentration = params(5*k); % % bessel = concentration / ... % (2*pi * (exp(concentration) - exp(-concentration))); % % normalisation = concentration^(dimension/2 - 1) / ... % ((2*pi)^(dimension/2) * bessel); % % value(:,k) = normalisation * exp(concentration*meandirection*direction')'; % value(:,k) = amplitude * value(:,k) + offset; % % % HACK to constrain values % if abs(meanazimuth) > 180 || ... % abs(meanelevation) > 90 || ... % amplitude < 0 || ... % concentration < 0 % % value(:,k) = 1e10*ones(size(value(:,k))); % % end % % end % % combinedvalue = sum(value,2); % % end