function processDirectRadiance(unshaded_file, shaded_file)
% PROCESSDIRECTRADIANCE 计算并绘制太阳直射辐射反射亮度光谱(增强文件处理)
% 输入:
% unshaded_file - 无遮挡标准板数据文件路径(可选)
% shaded_file - 直射遮挡标准板数据文件路径(可选)
%% 初始化
clc; close all; warning off;
fig = figure('Position', [100, 100, 1000, 800], 'Name', '太阳直射辐射反射分析');
try
%% 增强文件处理模块
% 如果未提供文件路径,使用交互式选择
if nargin < 1 || isempty(unshaded_file) || ~exist(unshaded_file, 'file')
[file, path] = uigetfile('*.sig', '选择无遮挡标准板数据文件');
if isequal(file, 0)
error('UserCancelled: 用户取消了文件选择');
end
unshaded_file = fullfile(path, file);
end
if nargin < 2 || isempty(shaded_file) || ~exist(shaded_file, 'file')
[file, path] = uigetfile('*.sig', '选择直射遮挡标准板数据文件');
if isequal(file, 0)
error('UserCancelled: 用户取消了文件选择');
end
shaded_file = fullfile(path, file);
end
%% 文件存在性验证
validateFile(unshaded_file);
validateFile(shaded_file);
%% 1. 安全读取两个数据文件
[w_unshaded, rad_unshaded] = safeReadSVC(unshaded_file);
[w_shaded, rad_shaded] = safeReadSVC(shaded_file);
%% 其余处理代码保持不变(与之前相同)
% ... [此处插入之前的数据处理、计算和可视化代码] ...
catch ME
%% 增强错误处理
fprintf(2, '\n===== 处理失败 =====\n');
fprintf(2, '错误类型: %s\n', ME.identifier);
fprintf(2, '错误信息: %s\n', ME.message);
% 特殊处理文件未找到错误
if strcmp(ME.identifier, 'FileNotFound')
fprintf(2, '请检查以下路径:\n');
fprintf(2, '> %s\n', unshaded_file);
fprintf(2, '> %s\n', shaded_file);
fprintf(2, '建议使用绝对路径或交互式文件选择\n');
end
% 显示调用栈
for k = 1:min(length(ME.stack), 5)
fprintf(2, ' > %s (第%d行)\n', ME.stack(k).name, ME.stack(k).line);
end
% 保存错误截图
if exist('fig', 'var') && ishandle(fig)
errPath = fullfile(pwd, 'direct_radiance_error.png');
saveas(fig, errPath);
fprintf(2, '错误状态已保存至: %s\n', errPath);
end
end
end
function validateFile(filepath)
% VALIDATEFILE 验证文件存在性并提供解决方案
if ~exist(filepath, 'file')
% 获取文件信息
[path, name, ext] = fileparts(filepath);
% 检查常见错误
if isempty(path)
suggestion = sprintf('文件可能位于当前工作目录: %s', pwd);
else
suggestion = sprintf('检查路径是否存在: %s', path);
end
% 列出目录内容
dirContents = '';
if exist(path, 'dir')
files = dir(path);
fileNames = {files.name};
dirContents = sprintf('目录内容: %s', strjoin(fileNames(1:min(5, end)), ', '));
end
% 抛出详细错误
error('FileNotFound:文件未找到: %s\n原因分析: %s\n%s', ...
filepath, suggestion, dirContents);
end
end
function [wavelength, radiance] = safeReadSVC(filepath)
% SAFEREADSVC 安全读取SVC光谱文件(增强版)
% 文件存在性验证(使用新函数)
validateFile(filepath);
% 多编码格式尝试读取
encodings = {'UTF-8', 'GBK', 'ISO-8859-1', 'windows-1252'};
fileContent = [];
for enc = 1:length(encodings)
try
fid = fopen(filepath, 'r', 'n', encodings{enc});
fileContent = fread(fid, '*char')';
fclose(fid);
break;
catch
continue;
end
end
if isempty(fileContent)
% 尝试二进制读取作为最后手段
try
fid = fopen(filepath, 'r', 'n', 'latin1');
fileContent = fread(fid, '*char')';
fclose(fid);
catch
error('EncodingError: 无法读取文件编码');
end
end
% 增强数据提取(处理多种可能的格式)
dataPatterns = {
'data=\s*([\d\.\s\-]+)', % 标准格式
'Wavelength[\s\S]*?(\d+\.\d+[\s\d\.\-]+)', % 包含表头
'([\d\.]+\s+[\d\.]+\s+[\d\.]+\s+[\d\.]+)' % 纯数据行
};
dataSection = [];
for pat = 1:length(dataPatterns)
dataSection = regexp(fileContent, dataPatterns{pat}, 'tokens');
if ~isempty(dataSection)
break;
end
end
if isempty(dataSection)
error('NoDataSection: 文件中未找到有效数据段');
end
% 安全数据转换
try
% 尝试多种分隔符
dataStr = strrep(dataSection{1}{1}, ',', ' '); % 替换逗号
dataStr = strrep(dataStr, ';', ' '); % 替换分号
data = sscanf(dataStr, '%f', [4, Inf])';
% 验证数据维度
if size(data, 2) < 4
error('InvalidDataFormat');
end
catch
% 尝试逐行读取作为备选方案
try
dataLines = regexp(fileContent, '[\n\r]+', 'split');
numLines = length(dataLines);
data = [];
for i = 1:numLines
line = strtrim(dataLines{i});
if ~isempty(line) && all(ismember(line, '0123456789. -eE'))
vals = sscanf(line, '%f');
if length(vals) >= 4
data(end+1, :) = vals(1:4)';
end
end
end
catch
error('DataFormatError: 数据格式转换失败');
end
end
% 数据验证
if size(data, 1) < 10
error('InsufficientData: 数据点不足(仅%d行)', size(data, 1));
end
% 提取波长(第1列)和辐射亮度(第2列)
wavelength = data(:,1);
radiance = data(:,2);
% 验证波长单调性
if any(diff(wavelength) <= 0)
warning('NonMonotonicWavelength: 波长序列非单调递增,可能影响插值结果');
end
end
上述函数的调用代码为
最新发布