function [optSettings,missingInfo] = loadOptSettings(optimizerFolder,optInputFile) % [optSettings,missingInfo] = loadOptSettings(optimizerFolder,optInputFile) % loads the linear least squares optimization settings from the % optimization input file into a Matlab structure. Beamlets are not % loaded, but everything else is. If any inconsistancies are found, such as % % missing fields, etc, the inconsistancies are stored in the cell array, % missingInfo. The optInputFile must be that absolute path of the input % file. % % RTF 1/19/07 % initialize outputs optSettings = []; missingInfo = {}; % Open the optimization input file fid = fopen([optimizerFolder '/' optInputFile],'r'); if fid == -1 error(['Unable to open ' optimizerFolder '/' optInputFile]); end optSettings = []; % optimization settings structure % read the file into a cell array, line-by-line fileText = {}; while 1 tline = fgetl(fid); if ~ischar(tline) break; end fileText{end+1} = tline; end fclose(fid); % Extract the folder name that contains the input file inputFileNameRev = fliplr(optInputFile); % flip the input filename around % pop off the reversed file name [fileNameRev,inputFolderRev] = strtok(inputFileNameRev,{'/','\'}); inputFolder = fliplr(inputFolderRev); if isempty(inputFolder) % input folder is the current folder inputFolder = pwd; end optSettings.optInfo.inputFile = fliplr(fileNameRev); % Field Name subfield conversion function fieldFunctions = {'Niterations' 'optInfo' 'str2num' 'Nperbatch' 'optInfo' 'str2num' 'prescFile' 'prescInfo' '' 'initBeamWeightFile' 'initialGuessInfo' '' 'beamletHeaderFileName' 'beamletInfo' '' 'doseBatchBaseName' 'optInfo' '' 'doseBatchExtension' 'optInfo' '' 'weightBatchBaseName' 'optInfo' '' 'weightBatchExtension' 'optInfo' '' 'objFuncFileName' 'optInfo' '' 'modFactor' 'optInfo' 'str2num' 'calcInitialGuessFlag' 'initialGuessInfo' 'str2num'}; % search for key fields for k=1:length(fileText) for m=1:size(fieldFunctions,1) if strcmp(deblank(fileText{k}),fieldFunctions{m,1}) eval(['optSettings.' fieldFunctions{m,2} '.' fieldFunctions{m,1} ' = ' fieldFunctions{m,3} '(''' fileText{k+1} ''');']); end end end % search for missing fields for k=1:size(fieldFunctions,1) if ~isfield(optSettings,fieldFunctions{k,2}) | ~eval(['isfield(optSettings.' fieldFunctions{k,2} ',''' fieldFunctions{k,1} ''')']) missingInfo{end+1} = ['Missing: optSettings.' fieldFunctions{k,2} '.' fieldFunctions{k,1}]; end end % find the output folder if isfield(optSettings,'optInfo') & isfield(optSettings.optInfo,'doseBatchBaseName') doseBatchBaseNameRev = fliplr(optSettings.optInfo.doseBatchBaseName); [fileNameRev,outputFolderRev] = strtok(doseBatchBaseNameRev,{'/','\'}); optSettings.optInfo.outputFolder = fliplr(outputFolderRev); optSettings.optInfo.outputFolder(:,end) = []; % delete last character, which is a '/' or '\' optSettings.optInfo.doseBatchBaseName = fliplr(fileNameRev); end % get the weightBatchBaseName if isfield(optSettings,'optInfo') & isfield(optSettings.optInfo,'weightBatchBaseName') doseBatchBaseNameRev = fliplr(optSettings.optInfo.weightBatchBaseName); [fileNameRev,outputFolderRev] = strtok(doseBatchBaseNameRev,{'/','\'}); optSettings.optInfo.weightBatchBaseName = fliplr(fileNameRev); end % find the input folder if isfield(optSettings,'prescInfo') & isfield(optSettings.prescInfo,'prescFile') prescFileRev = fliplr(optSettings.prescInfo.prescFile); [fileNameRev,inputFolderRev] = strtok(prescFileRev,{'/','\'}); optSettings.optInfo.inputFolder = fliplr(inputFolderRev); optSettings.optInfo.inputFolder(:,end) = []; % delete last character, which is a '/' or '\' optSettings.prescInfo.prescFile = fliplr(fileNameRev); end % get the initial beam weights file name if isfield(optSettings,'initialGuessInfo') & isfield(optSettings.initialGuessInfo,'initBeamWeightFile') initBeamWeightFileRev = fliplr(optSettings.initialGuessInfo.initBeamWeightFile); [fileNameRev,inputFolderRev] = strtok(initBeamWeightFileRev,{'/','\'}); optSettings.initialGuessInfo.initBeamWeightFile = fliplr(fileNameRev); end % trim off the objective function filename if isfield(optSettings,'optInfo') & isfield(optSettings.optInfo,'objFuncFileName') prescFileRev = fliplr(optSettings.optInfo.objFuncFileName); [fileNameRev,inputFolderRev] = strtok(prescFileRev,{'/','\'}); optSettings.optInfo.objFuncFileName = fliplr(fileNameRev); end % get the beamletFolder and beamletHeader if isfield(optSettings,'beamletInfo') & isfield(optSettings.beamletInfo,'beamletHeaderFileName') beamletHeaderFileNameRev = fliplr(optSettings.beamletInfo.beamletHeaderFileName); [fileNameRev,beamletFolderRev] = strtok(beamletHeaderFileNameRev,{'/','\'}); optSettings.beamletInfo.beamletFolder = fliplr(beamletFolderRev); optSettings.beamletInfo.beamletFolder(:,end) = []; % delete last character, which is a '/' or '\' optSettings.beamletInfo.beamletHeaderFileName = fliplr(fileNameRev); end % open the prescription file if it has been specified properly if isfield(optSettings,'optInfo') & isfield(optSettings,'prescInfo') ... & isfield(optSettings.optInfo,'inputFolder') & isfield(optSettings.prescInfo,'prescFile') prescFile = [optSettings.optInfo.inputFolder '/' optSettings.prescInfo.prescFile]; fid = fopen([prescFile],'r'); if fid == -1 missingInfo{end+1} = ['Unable to open prescription file: ' prescFile]; else % read the entire file into a cell array fileText = {}; while 1 tline = fgetl(fid); if ~ischar(tline) break; end fileText{end+1} = tline; end fclose(fid); if ~strcmp(deblank(fileText{1}),'Ntissue') error('First line of prescription file must be ''Ntissue'''); else Ntissue = str2num(fileText{2}); end k = 5; % skip up to the 5th line of the file, which is the tissue number % read in the tissues for m=1:Ntissue % read through the lines for the current tissue tissNum = str2num(fileText{k}); k = k + 2; optSettings.prescInfo.presc.tissue(m).name = fileText{k}; k = k + 2; optSettings.prescInfo.presc.tissue(m).alpha = str2num(fileText{k}); k = k + 2; optSettings.prescInfo.presc.tissue(m).betaVPlus = str2num(fileText{k}); k = k + 2; optSettings.prescInfo.presc.tissue(m).dVPlus = str2num(fileText{k}); k = k + 2; optSettings.prescInfo.presc.tissue(m).vPlus = str2num(fileText{k}); k = k + 2; optSettings.prescInfo.presc.tissue(m).betaVMinus = str2num(fileText{k}); k = k + 2; optSettings.prescInfo.presc.tissue(m).dVMinus = str2num(fileText{k}); k = k + 2; optSettings.prescInfo.presc.tissue(m).vMinus = str2num(fileText{k}); k = k + 2; optSettings.prescInfo.presc.tissue(m).betaPlus = str2num(fileText{k}); k = k + 2; optSettings.prescInfo.presc.tissue(m).dosePlusFileName = fileText{k}; k = k + 2; optSettings.prescInfo.presc.tissue(m).betaMinus = str2num(fileText{k}); k = k + 2; optSettings.prescInfo.presc.tissue(m).doseMinusFileName = fileText{k}; % load-in the dPlus inforomation fid = fopen(optSettings.prescInfo.presc.tissue(m).dosePlusFileName,'rb'); siz = fread(fid,3,'int'); % size of the sparse array Nind = fread(fid,1,'int'); ind = fread(fid,Nind,'int=>int'); dat = fread(fid,Nind,'float=>float'); fclose(fid); optSettings.prescInfo.presc.tissue(m).ind = ind + 1; optSettings.prescInfo.presc.tissue(m).dPlus = dat; % load-in the dMinus inforomation fid = fopen(optSettings.prescInfo.presc.tissue(m).doseMinusFileName,'rb'); siz = fread(fid,3,'int')'; % size of the sparse array Nind = fread(fid,1,'int'); ind = fread(fid,Nind,'int=>int'); dat = fread(fid,Nind,'float=>float'); fclose(fid); optSettings.prescInfo.presc.tissue(m).ind = ind + 1; optSettings.prescInfo.presc.tissue(m).dMinus = dat; k = k + 3; % skip up to the next tissueNum value field end optSettings.prescInfo.presc.siz = siz; % size of all of the dose grid end end % read in the initial guess information if isfield(optSettings,'initialGuessInfo') & isfield(optSettings.initialGuessInfo,'initBeamWeightFile') ... & isfield(optSettings,'optInfo') & isfield(optSettings.optInfo,'inputFolder') if ~isfield(optSettings.initialGuessInfo,'calcInitialGuessFlag') ... || (isfield(optSettings.initialGuessInfo,'calcInitialGuessFlag') & optSettings.initialGuessInfo.calcInitialGuessFlag == 0) fid = fopen([optimizerFolder '/' optSettings.optInfo.inputFolder '/' optSettings.initialGuessInfo.initBeamWeightFile]); if fid == -1 missingInfo{end+1} = ['Unable to open initial guess file for beam weights: ' optSettings.initialGuessInfo.initBeamWeightFile]; else optSettings.initialGuessInfo.w0 = fread(fid,'float'); fclose(fid); end end end % read in the beamlet file and folder information if isfield(optSettings,'beamletInfo') & isfield(optSettings.beamletInfo,'beamletFolder') ... & isfield(optSettings.beamletInfo,'beamletFolder') beamletHeaderFile = [optSettings.beamletInfo.beamletFolder '/' optSettings.beamletInfo.beamletHeaderFileName]; fid = fopen(beamletHeaderFile,'r'); if fid == -1 missingInfo{end+1} = ['Unable to open beamlet header file: ' beamletHeaderFile]; else % read the file into a cell array, line-by-line fileText = {}; while 1 tline = fgetl(fid); if ~ischar(tline) break; end fileText{end+1} = tline; end fclose(fid); fieldFunctions = { ... 'beamletDim' 'beamletInfo' 'str2num' 'Nbeamlets' 'beamletInfo' 'str2num' 'Nbeamletbatches' 'beamletInfo' 'str2num' 'beamletFolder' 'beamletInfo' '' 'beamletBatchBaseName' 'beamletInfo' '' 'beamletBatchExtension' 'beamletInfo' '' }; % search for key fields for k=1:length(fileText) for m=1:size(fieldFunctions,1) if strcmp(deblank(fileText{k}),fieldFunctions{m,1}) eval(['optSettings.' fieldFunctions{m,2} '.' fieldFunctions{m,1} ' = ' fieldFunctions{m,3} '(''' fileText{k+1} ''');']); end end end % search for missing fields for k=1:size(fieldFunctions,1) if ~isfield(optSettings,fieldFunctions{k,2}) | ~eval(['isfield(optSettings.' fieldFunctions{k,2} ',''' fieldFunctions{k,1} ''')']) missingInfo{end+1} = ['Missing: optSettings.' fieldFunctions{k,2} '.' fieldFunctions{k,1}]; end end end end