123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612 |
- function [weights, dose] = RDX_linlsqOptimization(optSettings)
- % Input: optSettings structure, defined as follows:
- % optSettings
- % .prescInfo
- % .savePresc = 'yes' or 'no' (defaults to 'no')
- % .presc (prescription structure, which has the form:
- % .presc.siz = [M N Q] size of each beamlet
- % .presc.tissue = Structure array of tissue-specific
- % prescription. savePrescription subfunction has details.
- % Defaults to an empty matrix.
- % .prescFileName (defaults to 'prescription.txt')
- %
- % .beamletInfo
- % .saveBeamlets = 'yes' or 'no' (defaults to 'no')
- % .saveBeamletHeader = 'yes' or 'no' (defaults to 'no')
- % .beamletFolder (defaults to 'beamlets')
- % .beamlets (cell array of Matlab-style sparse beamlets stored as:
- % .beamlets{n}.Dij{m}, where Dij contains the sparse data)
- % Defaults to an empty matrix.
- % .beamletBatchBaseName (defaults to 'beamletbatch')
- % .beamletBatchExtension (defaults to 'bin')
- % .beamletHeaderFileName (defaults to 'beamlet_header.txt')
- % .Nbeamlets (defaults to 1)
- % .Nbeamletbatches (defaults to 1)
- % .beamletDim (defaults to [1 1 1])
- %
- % .optInfo
- % .saveOptInfo = 'yes' or 'no' (defaults to 'no')
- % .optRun = 'yes' or 'no' (defaults to 'no')
- % .waitForResults = 'yes' or 'no' (defaults to 'no')
- % .optFolder (Folder containing optimizer's Visual C++ code)
- % Defaults to 'C:\rtflynn\library\matlabAdditions\optimization\linlsq\linlsqOpt'
- % .inputFolder (defaults to 'input')
- % .outputFolder (defaults to 'output')
- % .inputFile (defaults to optInput.txt)
- % .Niterations (Defaults to 100)
- % .Nperbatch (Defaults to 50)
- % .doseBatchBaseName (defaults to 'dosebatch')
- % .doseBatchExtension (defaults to 'img')
- % .weightBatchBaseName (defaults to 'weightbatch')
- % .weightBatchExtension (defaults to 'img')
- % .optExeName (defaults to 'linlsqOpt.exe')
- % .objFuncFileName (defaults to 'objFunc.bin')
- % .modFactor (defaults to 1e10)
- %
- % .initialGuessInfo
- % .saveInitialGuess = 'yes' or 'no' (defaults to 'no')
- % .w0 (initial guess for all beamlet weights, defaults to empty matrix)
- % .initBeamWeightFile (defaults to 'init_beam_weight_file')
- % .calcInitialGuessFlag (defaults to 1) % if 1, optimizer calculates
- % the initial guess
- %
- % Outputs:
- % w optimized beamlet weights
- % dose optimized dose distribution
- %
- % Outputs are empty matrices unless the 'waitForResults' flag is set to
- % 'yes'. Otherwise, load results at a later time.
- %
- % Ryan Flynn, David Westerly
- % Xiaohu Mo
- % Fixed pathsep (/\) portability issue
- % Check input structure for inconistencies, set defaults for fields that
- % were optional and not included.
- optSettings = parseInput(optSettings);
- % From this point on, it is assumed that all fields that are required for
- % any functions for the rest of this script are present.
- origDir = pwd; % copy the directory path from which this script was called
- warning off;
- % Change to the directory containing the linlsqOpt source code.
- cd(optSettings.optInfo.optFolder);
- % save prescription info
- savePrescription(optSettings);
- % save beamlet info
- saveBeamlets(optSettings);
- % save initial guess info
- saveInitialGuess(optSettings);
- % save optimization info
- saveOptInfo(optSettings);
- % run optimizer
- [weights, dose] = runOptimizer(optSettings);
- cd(origDir); % go back to the original directory
- function optSettings = parseInput(optSettings)
- % Checks the optSettings input structure for inconsistencies and applies
- % defaults to optional fields that were not included in the input
- % structure.
- % set optimizer defaults
- optSettingsDefault.prescInfo.savePresc = 'no';
- optSettingsDefault.prescInfo.presc = [];
- optSettingsDefault.prescInfo.prescFileName = 'prescription.txt';
- optSettingsDefault.beamletInfo.saveBeamlets = 'no';
- optSettingsDefault.beamletInfo.saveBeamletHeader = 'no';
- optSettingsDefault.beamletInfo.beamletFolder = 'beamlets';
- optSettingsDefault.beamletInfo.beamlets = [];
- optSettingsDefault.beamletInfo.beamletBatchBaseName = 'beamletbatch';
- optSettingsDefault.beamletInfo.beamletBatchExtension = 'bin';
- optSettingsDefault.beamletInfo.beamletHeaderFileName = 'beamlet_header.txt';
- optSettingsDefault.beamletInfo.Nbeamlets = 1;
- optSettingsDefault.beamletInfo.Nbeamletbatches = 1;
- optSettingsDefault.beamletInfo.beamletDim = [1 1 1];
- optSettingsDefault.optInfo.saveOptInfo = 'no';
- optSettingsDefault.optInfo.optRun = 'no';
- optSettingsDefault.optInfo.waitForResults = 'no';
- optSettingsDefault.optInfo.optFolder = ...
- 'F:\Treatment_Planning\optimizer';
- optSettingsDefault.optInfo.inputFolder = 'input';
- optSettingsDefault.optInfo.outputFolder = 'output';
- optSettingsDefault.optInfo.inputFile = 'optInput.txt';
- optSettingsDefault.optInfo.Niterations = 100;
- optSettingsDefault.optInfo.Nperbatch = 50;
- optSettingsDefault.optInfo.doseBatchBaseName = 'dosebatch';
- optSettingsDefault.optInfo.doseBatchExtension = 'img';
- optSettingsDefault.optInfo.weightBatchBaseName = 'weightbatch';
- optSettingsDefault.optInfo.weightBatchExtension = 'img';
- optSettingsDefault.optInfo.optExeName = 'linlsqOptimizer.exe';
- optSettingsDefault.optInfo.objFuncFileName = 'objFunc.bin';
- optSettingsDefault.optInfo.modFactor = 1e10; % modulation factor
- optSettingsDefault.initialGuessInfo.saveInitialGuess = 'no';
- optSettingsDefault.initialGuessInfo.w0 = [];
- optSettingsDefault.initialGuessInfo.initBeamWeightFile = 'init_beam_weight_file.img';
- optSettingsDefault.initialGuessInfo.calcInitialGuessFlag = 1;
- % Traverse the optSettings structure tree, and, whenever a leaf is missing
- % in the tree, fill it in with its default value.
- nodeVec = [1 1]; % vector corresponding to nodes in the structure tree
- while length(nodeVec) > 1 % traverse as long as we're not back at the top of the tree
- % Create a field access string, which is used to access the node
- % referred to by nodeVec.
- fldAccStr = 'optSettingsDefault';
- for k=2:length(nodeVec)
- eval(['fieldNames = fieldnames(' fldAccStr ');']);
- fldAccStr = [fldAccStr '.' fieldNames{nodeVec(k)}];
- end
-
- % Check if the field is a number or a string (leaf).
- eval(['numFlag = isnumeric(' fldAccStr ');']);
- eval(['charFlag = ischar(' fldAccStr ');']);
-
- if numFlag == 1 | charFlag == 1 % found a leaf
- % Traverse input structure, searching for leaves that exist in the
- % default structure but do not exist in the input structure. This
- % is done by working down the input tree until either a node or a
- % leaf is missing from the input
- fldAccStrInp = 'optSettings';
- fldAccStrDummy = 'optSettingsDefault';
- for k=2:length(nodeVec)
- eval(['fieldNamesDummy = fieldnames(' fldAccStrDummy ');']);
- eval(['fieldFlag = isfield(' fldAccStrInp ',''' fieldNamesDummy{nodeVec(k)} ''');']);
- if fieldFlag == 1
- fldAccStrInp = [fldAccStrInp '.' fieldNamesDummy{nodeVec(k)}];
- fldAccStrDummy = [fldAccStrDummy '.' fieldNamesDummy{nodeVec(k)}];
- else % Leaf cannot exist, so set it to its default.
- [tok,rem] = strtok(fldAccStr,'.');
- fldAccStrInp = ['optSettings' rem];
- eval([fldAccStrInp ' = ' fldAccStr ';']);
- break;
- end
- end
-
- % go to the next node vector
- while length(nodeVec) > 1
- fldAccStr = 'optSettingsDefault';
- for k=2:length(nodeVec)
- eval(['fieldNames = fieldnames(' fldAccStr ');']);
- fldAccStr = [fldAccStr '.' fieldNames{nodeVec(k)}];
- end
- % Go to next leaf or nodes on the same level, if one exists.
- if nodeVec(end) + 1 <= length(fieldNames)
- nodeVec(end) = nodeVec(end) + 1;
- break;
- else % No more leaves or nodes on this level, so go up a level.
- nodeVec(:,end) = [];
- end
- end
- else % found another field that is not a leaf
- nodeVec = [nodeVec 1]; % go down a level in the tree
- end
- end
- % If beamlets were included with optSettings, ensure that the
- % Nbeamletbatches, Nbeamlets, and beamletDim fields are consistent
- if ~isempty(optSettings.beamletInfo.beamlets)
- % get the beamlet dimensions
- [Xcount,Ycount,Zcount] = size(full(optSettings.beamletInfo.beamlets{1}.Dij{1}));
- optSettings.beamletInfo.beamletDim = [Xcount Ycount Zcount];
- optSettings.beamletInfo.Nbeamletbatches = numel(optSettings.beamletInfo.beamlets);
- optSettings.beamletInfo.Nbeamlets = 0;
- for k=1:optSettings.beamletInfo.Nbeamletbatches
- optSettings.beamletInfo.Nbeamlets = optSettings.beamletInfo.Nbeamlets ...
- + numel(optSettings.beamletInfo.beamlets{k}.Dij);
- end
- else
- % If optSettings.prescInfo.presc.siz was defined, then that field
- % should contain beamlet dimensions.
- if isfield(optSettings.prescInfo.presc,'siz')
- optSettings.beamletInfo.beamletDim = optSettings.prescInfo.presc.siz;
- end
- end
- function savePrescription(optSettings)
- % If the savePresc field is 'yes', saves a prescription structure to a file
- % format that is useable by the linear least squares optimizer.
- %% .prescInfo
- %% .savePresc = 'yes' or 'no'
- % .presc (prescription structure, which has the form:
- % .presc.siz = [M N Q] size of each beamlet
- % .presc.tissue = structure array of tissue-specific
- % prescription. savePrescription subfunction has details.
- % .prescFile (defaults to 'prescription.txt')
- infValue = 10e10; % value of infinity
- % Check the savePresc flag. If 'no', do not save prescription
- if strcmp(lower(optSettings.prescInfo.savePresc),'no')
- return;
- end
- % create input and output folders
- success = mkdir(optSettings.optInfo.inputFolder);
- % delete old output folder if it exists first
- success = rmdir(optSettings.optInfo.outputFolder,'s');
- success = mkdir(optSettings.optInfo.outputFolder);
- % Check the prescription structure to ensure all proper fields are present.
- prescTissueFields = {'name' 'alpha' 'betaVPlus' 'dVPlus' 'vPlus' 'betaVMinus' ...
- 'dVMinus' 'vMinus' 'betaPlus' 'betaMinus' 'ind' 'dPlus' 'dMinus'};
-
- if isempty(optSettings.prescInfo.presc)
- error('optSettings.prescInfo.presc not defined -- define it or set optSettings.prescInfo.savePresc to ''no''');
- end
-
- if ~isfield(optSettings.prescInfo.presc,'siz')
- error('Missing ''siz'' field from optSettings.prescInfo.presc structure');
- end
- % siz is present, so make sure it is a 3 element vector
- if numel(optSettings.prescInfo.presc.siz) ~= 3
- error('The ''siz'' field from optSettings.prescInfo.presc structure must be a 3-element vector');
- end
- if ~isfield(optSettings.prescInfo.presc,'tissue')
- error('Missing ''tissue'' field from prescInfo.presc structure');
- end
- % search for subfields of tissue field
- for k=1:numel(prescTissueFields)
- if ~isfield(optSettings.prescInfo.presc.tissue,prescTissueFields{k})
- error(['Missing ''' prescTissueFields{k} ''' field from optSettings.prescInfo.presc.tissue structure']);
- end
- end
- % write the prescription file
- fid = fopen([optSettings.optInfo.inputFolder filesep optSettings.prescInfo.prescFileName],'w');
- if fid == -1
- error('Failed to open prescription file.');
- end
- fprintf(fid,'Ntissue\n');
- fprintf(fid,[num2str(numel(optSettings.prescInfo.presc.tissue)) '\n\n']);
- for k=1:numel(optSettings.prescInfo.presc.tissue) % write prescription parameters for each tissue type
- % write the current tissue number
- fprintf(fid,'tissueNum\n');
- fprintf(fid,[num2str(k-1) '\n']);
- fprintf(fid,'name\n');
- fprintf(fid,[optSettings.prescInfo.presc.tissue(k).name '\n']);
-
- % throughout writing process, always check for infinities before printing values
-
- % write the tissue importance
- fprintf(fid,'alpha\n');
- if isinf(optSettings.prescInfo.presc.tissue(k).alpha)
- fprintf(fid,[num2str(infValue) '\n']);
- else
- fprintf(fid,[num2str(optSettings.prescInfo.presc.tissue(k).alpha) '\n']);
- end
- fprintf(fid,'betaVPlus\n');
- if isinf(optSettings.prescInfo.presc.tissue(k).betaVPlus)
- fprintf(fid,[num2str(infValue) '\n']);
- else
- fprintf(fid,[num2str(optSettings.prescInfo.presc.tissue(k).betaVPlus) '\n']);
- end
-
- fprintf(fid,'dVPlus\n');
- if isinf(optSettings.prescInfo.presc.tissue(k).dVPlus)
- fprintf(fid,[num2str(infValue) '\n']);
- else
- fprintf(fid,[num2str(optSettings.prescInfo.presc.tissue(k).dVPlus) '\n']);
- end
-
- fprintf(fid,'vPlus\n');
- if isinf(optSettings.prescInfo.presc.tissue(k).vPlus)
- fprintf(fid,[num2str(infValue) '\n']);
- else
- fprintf(fid,[num2str(optSettings.prescInfo.presc.tissue(k).vPlus) '\n']);
- end
-
- fprintf(fid,'betaVMinus\n');
- if isinf(optSettings.prescInfo.presc.tissue(k).betaVMinus)
- fprintf(fid,[num2str(infValue) '\n']);
- else
- fprintf(fid,[num2str(optSettings.prescInfo.presc.tissue(k).betaVMinus) '\n']);
- end
-
- fprintf(fid,'dVMinus\n');
- if isinf(optSettings.prescInfo.presc.tissue(k).dVMinus)
- fprintf(fid,[num2str(infValue) '\n']);
- else
- fprintf(fid,[num2str(optSettings.prescInfo.presc.tissue(k).dVMinus) '\n']);
- end
-
- fprintf(fid,'vMinus\n');
- if isinf(optSettings.prescInfo.presc.tissue(k).vMinus)
- fprintf(fid,[num2str(infValue) '\n']);
- else
- fprintf(fid,[num2str(optSettings.prescInfo.presc.tissue(k).vMinus) '\n']);
- end
-
-
- fprintf(fid,'betaPlus\n');
- if isinf(optSettings.prescInfo.presc.tissue(k).betaPlus)
- fprintf(fid,[num2str(infValue) '\n']);
- else
- fprintf(fid,[num2str(optSettings.prescInfo.presc.tissue(k).betaPlus) '\n']);
- end
-
- % create a name for the underdose penalty prescription file
- dose_presc_filename = [regexprep(optSettings.prescInfo.presc.tissue(k).name,{' ','\','/'},'') 'DosePlus.bin'];
- fprintf(fid,'dosePlusFilename\n');
- fprintf(fid,'%s\n', fullfile(optSettings.optInfo.optFolder, optSettings.optInfo.inputFolder, dose_presc_filename));
-
- % save the mask as a sparse matrix
- fid2 = fopen([optSettings.optInfo.inputFolder filesep dose_presc_filename],'wb');
- fwrite(fid2,optSettings.prescInfo.presc.siz,'int');
- fwrite(fid2,length(optSettings.prescInfo.presc.tissue(k).ind),'int');
- fwrite(fid2,optSettings.prescInfo.presc.tissue(k).ind-1,'int');
- fwrite(fid2,optSettings.prescInfo.presc.tissue(k).dPlus,'single');
- fclose(fid2);
-
- fprintf(fid,'betaMinus\n');
- if isinf(optSettings.prescInfo.presc.tissue(k).betaMinus)
- fprintf(fid,[num2str(infValue) '\n']);
- else
- fprintf(fid,[num2str(optSettings.prescInfo.presc.tissue(k).betaMinus) '\n']);
- end
-
- % create a name for the overdose penalty prescription file
- dose_presc_filename = [regexprep(optSettings.prescInfo.presc.tissue(k).name,{' ','\','/'},'') 'DoseMinus.bin'];
- fprintf(fid,'doseMinusFilename\n');
- fprintf(fid,'%s\n', fullfile(optSettings.optInfo.optFolder, optSettings.optInfo.inputFolder, dose_presc_filename));
-
- % save the mask as a sparse matrix
- fid2 = fopen([optSettings.optInfo.inputFolder filesep dose_presc_filename],'wb');
- fwrite(fid2,optSettings.prescInfo.presc.siz,'int');
- fwrite(fid2,length(optSettings.prescInfo.presc.tissue(k).ind),'int');
- fwrite(fid2,optSettings.prescInfo.presc.tissue(k).ind-1,'int');
- fwrite(fid2,optSettings.prescInfo.presc.tissue(k).dMinus,'single');
- fclose(fid2);
-
- fprintf(fid,'\n');
- end
- fclose(fid);
- function saveBeamlets(optSettings)
- % Saves a set of beamlets to filename. Dij is a cell array of beamlets,
- % each of which must be sparse 2D Matlab matrices.
- %
- %% .beamletInfo
- %% .saveBeamlets = 'yes' or 'no' (if 'yes', beamlets saved)
- %% .beamletFolder (required, folder containing beamlets their header)
- % .beamlets (cell array of Matlab-style sparse beamlets stored as:
- % .beamlets{n}.Dij{m}, where Dij contains the sparse data)
- % .beamletBatchBaseName (defaults to 'beamletbatch')
- % .beamletBatchExtension (defaults to 'bin')
- % .beamletHeaderFileName (defaults to 'beamlet_header.txt')
- % .Nbeamlets
- % .Nbeamletbatches
- % .beamletDim
- % Check if the beamlet header will need to be saved
- if strcmp(lower(optSettings.beamletInfo.saveBeamletHeader),'no') ...
- && strcmp(lower(optSettings.beamletInfo.saveBeamlets),'no')
- return;
- end
- if strcmp(lower(optSettings.beamletInfo.saveBeamlets),'yes')
- % delete all of the old beamlets and header info
- success = rmdir([optSettings.optInfo.optFolder '/' optSettings.beamletInfo.beamletFolder],'s');
- mkdir([optSettings.optInfo.optFolder '/' optSettings.beamletInfo.beamletFolder]);
- end
- % create a folder for the beamlets if it doesn't already exist
- mkdir(optSettings.beamletInfo.beamletFolder);
- % create the beamlet header file
- fid = fopen([optSettings.beamletInfo.beamletFolder '/' optSettings.beamletInfo.beamletHeaderFileName],'w');
- if fid == -1
- error('Failed to open beamlet header file.');
- end
- fprintf(fid,'beamletDim\n');
- fprintf(fid,'%g %g %g\n',optSettings.beamletInfo.beamletDim);
- fprintf(fid,'Nbeamlets\n');
- fprintf(fid,'%g\n',optSettings.beamletInfo.Nbeamlets);
- fprintf(fid,'Nbeamletbatches\n');
- fprintf(fid,'%g\n',optSettings.beamletInfo.Nbeamletbatches);
- fprintf(fid,'beamletFolder\n');
- fprintf(fid,'%s\n', fullfile(optSettings.optInfo.optFolder, optSettings.beamletInfo.beamletFolder));
- fprintf(fid,'beamletBatchBaseName\n');
- fprintf(fid,[optSettings.beamletInfo.beamletBatchBaseName '\n']);
- fprintf(fid,'beamletBatchExtension\n');
- fprintf(fid,[optSettings.beamletInfo.beamletBatchExtension '\n']);
- fclose(fid);
- % Check if the beamlets need to be saved
- if strcmp(lower(optSettings.beamletInfo.saveBeamlets),'no')
- return;
- end
- if isempty(optSettings.beamletInfo.beamlets)
- error('No beamlets to save -- supply beamlets or set saveBeamlets to ''no''');
- end
- % Save the beamlets
- beamletNum = 0;
- for k=1:optSettings.beamletInfo.Nbeamletbatches
- beamletFileName = [optSettings.beamletInfo.beamletFolder '/' ...
- optSettings.beamletInfo.beamletBatchBaseName num2str(k-1) '.' ...
- optSettings.beamletInfo.beamletBatchExtension];
- fid = fopen(beamletFileName,'wb');
- if fid == -1
- error(['Failed to open ' beamletFileName]);
- end
- Nbib = numel(optSettings.beamletInfo.beamlets{k}.Dij); % number of beamlet in batch
- fwrite(fid,Nbib,'int');
- for m=1:Nbib
- % dimensions of current beamlet
- [Nx,Ny,Nz] = size(full(optSettings.beamletInfo.beamlets{k}.Dij{m}));
- if Nx - optSettings.beamletInfo.beamletDim(1) ~= 0 ...
- || Ny - optSettings.beamletInfo.beamletDim(2) ~= 0 ...
- || Nz - optSettings.beamletInfo.beamletDim(3) ~= 0
- error(['Dimensions of optSettings.beamletInfo.beamlets{' ...
- num2str(k) '}.Dij{' num2str(m) '} are not (' ...
- num2str(optSettings.beamletInfo.beamletDim(1)) ',' ...
- num2str(optSettings.beamletInfo.beamletDim(2)) ',' ...
- num2str(optSettings.beamletInfo.beamletDim(3)) ')']);
- end
- % save the beamlet
- fwrite(fid,beamletNum,'int'); % beamlet number
- fwrite(fid,optSettings.beamletInfo.beamletDim,'int'); % beamlet dimensions
- ind = find(optSettings.beamletInfo.beamlets{k}.Dij{m}); % beamlet indices
- ind = ind - 1; % convert Matlab indices to C indices
- fwrite(fid,numel(ind),'int'); % number of non-zero indices
- fwrite(fid,ind,'int'); % non-zero indices
- fwrite(fid,nonzeros(optSettings.beamletInfo.beamlets{k}.Dij{m}),'float');
- beamletNum = beamletNum + 1;
- end
- fclose(fid); % close the current beamlet batch
- end
- function saveInitialGuess(optSettings)
- % save the initial guess
- % exit if the initial guess is not to be saved
- if strcmp(lower(optSettings.initialGuessInfo.saveInitialGuess),'no')
- return;
- end
- % create input and output folders
- success = mkdir(optSettings.optInfo.inputFolder);
- success = mkdir(optSettings.optInfo.outputFolder);
- initBeamWeightFile = [optSettings.optInfo.optFolder filesep optSettings.optInfo.inputFolder ...
- filesep optSettings.initialGuessInfo.initBeamWeightFile];
- fid = fopen(initBeamWeightFile,'wb');
- if fid == -1
- error(['Failed to open initial beam weight file: ' initBeamWeightFile]);
- end
- fwrite(fid,optSettings.initialGuessInfo.w0,'float');
- fclose(fid);
- function saveOptInfo(optSettings)
- % Exit if optimization info is not supposed to be saved
- if strcmp(lower(optSettings.optInfo.saveOptInfo),'no')
- return;
- end
- % create input and output folders
- success = mkdir(optSettings.optInfo.inputFolder);
- success = mkdir(optSettings.optInfo.outputFolder);
- % create the optimization input file
- optInfoFileName = optSettings.optInfo.inputFile;
- fid = fopen(optInfoFileName,'w');
- if fid == -1
- error(['Failed to open optimization input file: ' optInfoFileName]);
- end
- fprintf(fid,'Niterations\n');
- fprintf(fid,'%d\n',optSettings.optInfo.Niterations);
- fprintf(fid,'Nperbatch\n');
- fprintf(fid,'%d\n',optSettings.optInfo.Nperbatch);
- fprintf(fid,'prescFile\n');
- fprintf(fid,'%s\n',fullfile(optSettings.optInfo.optFolder, optSettings.optInfo.inputFolder, optSettings.prescInfo.prescFileName));
- fprintf(fid,'initBeamWeightFile\n');
- if optSettings.initialGuessInfo.calcInitialGuessFlag == 0
- % supply the initial guess file
- fprintf(fid,'%s\n',[optSettings.optInfo.optFolder '/' optSettings.initialGuessInfo.initBeamWeightFile]);
- else % no need to supply file, as optimizer will calculate initial guess
- fprintf(fid,'%s\n','optimizerCalculatesInitialGuess');
- end
- fprintf(fid,'beamletHeaderFileName\n');
- fprintf(fid,'%s\n', fullfile(optSettings.optInfo.optFolder, optSettings.beamletInfo.beamletFolder, optSettings.beamletInfo.beamletHeaderFileName));
- fprintf(fid,'doseBatchBaseName\n');
- fprintf(fid,'%s\n', fullfile(optSettings.optInfo.optFolder, optSettings.optInfo.outputFolder, optSettings.optInfo.doseBatchBaseName));
- fprintf(fid,'doseBatchExtension\n');
- fprintf(fid,[optSettings.optInfo.doseBatchExtension '\n']);
- fprintf(fid,'weightBatchBaseName\n');
- fprintf(fid,'%s\n', fullfile(optSettings.optInfo.optFolder, optSettings.optInfo.outputFolder, optSettings.optInfo.weightBatchBaseName));
- fprintf(fid,'weightBatchExtension\n');
- fprintf(fid,[optSettings.optInfo.weightBatchExtension '\n']);
- fprintf(fid,'objFuncFileName\n');
- fprintf(fid,'%s\n', fullfile(optSettings.optInfo.optFolder, optSettings.optInfo.outputFolder, optSettings.optInfo.objFuncFileName));
- fprintf(fid,'modFactor\n');
- fprintf(fid,[num2str(optSettings.optInfo.modFactor) '\n']);
- fprintf(fid,'calcInitialGuessFlag\n');
- fprintf(fid,[num2str(optSettings.initialGuessInfo.calcInitialGuessFlag) '\n']);
- fclose(fid);
- function [weights, dose] = runOptimizer(optSettings)
- dose = [];
- weights = [];
- % Exit function of optimizer is not to be run.
- if strcmp(lower(optSettings.optInfo.optRun),'no')
- return;
- end
- currDir = pwd; % save a copy of the current directory path
- % copy the most recent build of optimizer to the optFolder
- exeDebugFile = [optSettings.optInfo.optFolder '\Debug\' optSettings.optInfo.optExeName];
- exeFile = [optSettings.optInfo.optFolder filesep optSettings.optInfo.optExeName];
- success = copyfile(exeDebugFile,exeFile);
- if success == 0
- error(['Error copying ' exeDebugFile ' to ' exeFile]);
- end
- % do the optimization
- delete('optDone.txt'); % delete the old dose file if it exists
- fprintf('Running optimizer...\n');
- % run the optimization from the console
- eval(['! ' optSettings.optInfo.optExeName ' ' optSettings.optInfo.inputFile ' &']);
- % Exit if the user did not wish to wait for results
- if strcmp(lower(optSettings.optInfo.waitForResults),'no')
- return;
- end
- % Check for the flag indicating that the optimization is finished
- while ~exist('optDone.txt','file')
- pause(1); % pause before resuming
- end
- % Optimization finished, so load the beamlet weights
- fid = fopen([optSettings.optInfo.outputFolder '/' ...
- optSettings.optInfo.weightBatchBaseName num2str(optSettings.optInfo.Niterations) '.' ...
- optSettings.optInfo.weightBatchExtension],'rb');
- if fid == -1
- error('Unable to open optimized weight results.');
- end
- weights = fread(fid,'float');
- fclose(fid);
- % load the dose distribution
- fid = fopen([optSettings.optInfo.outputFolder '/' ...
- optSettings.optInfo.doseBatchBaseName num2str(optSettings.optInfo.Niterations) '.' ...
- optSettings.optInfo.doseBatchExtension],'rb');
- if fid == -1
- error('Unable to open optimized dose results.');
- end
- dose = fread(fid,'float');
- try
- dose = reshape(dose,optSettings.beamletInfo.beamletDim);
- catch
- error(['Unable to reshape optimized dose distribution. Ensure ' ...
- 'that optSettings.beamletInfo.beamletDim field matches dose grid dimensions']);
- end
|