GeometryGenerator.m 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. function Geometry = GeometryGenerator()
  2. %% % % GeometryGenerator % % % % %
  3. % This function builds the geometry files needed for the WiscPlan dose
  4. % optimization. Requires that you have my amiraStructReader function. You
  5. % need contours in any amira format. Contours should ALL BE CROPPED TO THE
  6. % SAME DIMENSION.
  7. %
  8. % DLB - 6/5/09
  9. s = pwd;
  10. % Get the planning CT
  11. [planningCT, CT_pathname, filterindex] = uigetfile({'*.am','Amira file (*.am)'},'Select the planning CT.','MultiSelect','off');
  12. cd(CT_pathname);
  13. % Generate a list of contours to include in Geometry.ROIS
  14. [files, pathname, filterindex] = uigetfile({'*.am','Amira file (*.am)'; '*.*','All files (*.*)'},'Select all the contours for the Geometry file (use Ctrl).','MultiSelect','on');
  15. cd(pathname);
  16. % Set the initial Geometry structure members
  17. data = amiraStructReader([CT_pathname planningCT]);
  18. Geometry.voxel_size = [data.xpix data.ypix data.zpix];
  19. Geometry.start = [data.boundingbox(1) data.boundingbox(3) data.boundingbox(5)];
  20. Geometry.data = single(data.image);
  21. %% Adding ROIS to Geometry
  22. for i = 1:length(files)
  23. data = amiraStructReader([pathname files{i}]);
  24. % remove the .am file extension
  25. name = strrep(files{i},'.am','');
  26. % remove everything before the first underscore
  27. name = name(findstr(name,'_')+1:length(name));
  28. % anything that remotely has the letters GTV is renamed GTV
  29. if ~isempty(findstr(name,'GTV'))
  30. name = 'GTV';
  31. end
  32. % assign parameters
  33. Geometry.ROIS{i}.name = name;
  34. Geometry.ROIS{i}.ind = int32(find(data.image));
  35. Geometry.ROIS{i}.dim = [data.dims(1) data.dims(2) data.dims(3)];
  36. Geometry.ROIS{i}.pix_dim = [data.xpix data.ypix data.zpix];
  37. Geometry.ROIS{i}.start = [data.boundingbox(1) data.boundingbox(3) data.boundingbox(5)];
  38. Geometry.ROIS{i}.start_ind = '(1,1,1)';
  39. end
  40. cd(pathname);
  41. % save the Geometry file in the same location as your contours.
  42. save('Geometry.mat','Geometry');
  43. % return to the original directory
  44. cd(s);
  45. %% This is the amiraStructReader in case you don't have it. %%
  46. function data = amiraStructReader(varargin)
  47. %% % % amiraStructReader % % % % %
  48. % Built for when you might need additional amira header info in matlab.
  49. % Same functionality as amiraReader, but adds stuff in structure format
  50. %
  51. % DLB - 5/5/09 Cinco de Mayo!!! But another 12 hour day :*(
  52. %
  53. warning off all; % you'll get truncation warnings because you read inf in line 24.
  54. cd('C:\Data\');
  55. switch nargin
  56. case 1
  57. filename = varargin{1};
  58. case 0
  59. [file, pathname] = uigetfile({'*.am'},'Please locate Amira file.','Multiselect','off');
  60. filename = [pathname file];
  61. end
  62. fid = fopen(filename,'r','ieee-be');
  63. datachar = char(fread(fid,inf,'char'))'; % this will be the char data in the header
  64. switch isempty(findstr(datachar,'BINARY-LITTLE-ENDIAN'))
  65. case 1
  66. endianness = 'be';
  67. case 0
  68. endianness = 'le';
  69. end
  70. lattice = findstr(datachar,'define Lattice');
  71. parameter = findstr(datachar,'Parameters');
  72. start_data_position = findstr(datachar,'@1'); % note there will be two @1, so take the second one!
  73. fseek(fid,lattice+14,'bof');
  74. data.dims = str2num(fgetl(fid));
  75. bounding = findstr(datachar,'Bounding');
  76. fseek(fid,bounding + 11,'bof');
  77. data.boundingbox = str2num(fgetl(fid));
  78. data.x = (data.boundingbox(2)-data.boundingbox(1));
  79. data.y = (data.boundingbox(4)-data.boundingbox(3));
  80. data.z = (data.boundingbox(6)-data.boundingbox(5))*(1+1/(data.dims(3)-1));
  81. data.xpix = data.x/(data.dims(1)-1);
  82. data.ypix = data.y/(data.dims(2)-1);
  83. data.zpix = data.z/data.dims(3);
  84. %% Determine if we're dealing with a labelfield or regular data
  85. switch isempty(findstr(datachar,'HxByteRLE'))
  86. case 1 % regular data case
  87. data_type = char(datachar(findstr(datachar,'Lattice { ')+10:findstr(datachar,'Data } ')-2));
  88. switch data_type
  89. case 'byte'
  90. out_type = 'int8';
  91. case 'short'
  92. out_type = 'int16';
  93. case 'ushort'
  94. out_type = 'uint16';
  95. case 'int32'
  96. out_type = 'int32';
  97. case 'float'
  98. out_type = 'float';
  99. case 'double'
  100. out_type = 'double';
  101. end
  102. fid = fopen(filename,'r',['ieee-' endianness]);
  103. fseek(fid,start_data_position(2)+2,'bof');
  104. data.image = reshape(fread(fid,data.dims(1)*data.dims(2)*data.dims(3),out_type),data.dims(1),data.dims(2),data.dims(3));
  105. case 0 % labelfield case
  106. ByteRLE = findstr(datachar,'HxByteRLE,');
  107. DataSection = findstr(datachar,'# Data section follows');
  108. fseek(fid,ByteRLE+9,'bof');
  109. byte_length = str2num(char(fread(fid,DataSection - ByteRLE-13,'char'))');
  110. switch endianness
  111. case 'le'
  112. fclose(fid);
  113. fid = fopen(filename,'r',['ieee-' endianness]);
  114. fseek(fid,start_data_position(2)+2,'bof');
  115. data.image = fread(fid,byte_length,'int8');
  116. case 'be'
  117. fseek(fid,start_data_position(2)+2,'bof');
  118. data.image = fread(fid,byte_length,'int8');
  119. end
  120. out_line = zeros(data.dims(1)*data.dims(2)*data.dims(3),1);
  121. final_offset = sum(data.image(find(data.image<0))+127);
  122. net_counter = 0; % this sifts through the out_line variable
  123. offset = 0; % this adds an offset to data_counter when writing VERBATIM
  124. for i = 1:floor((byte_length-final_offset)/2) %
  125. data_counter = 2*i+offset; % this will sift through the data variable
  126. if ((data.image(data_counter) == 0) && (data.image(data_counter-1) > 0)) % check if the value is 0 AND that we're not writing VERBATIM
  127. net_counter = data.image(data_counter-1)+net_counter;
  128. else
  129. if data.image(data_counter-1) < 0 % check if we're writing VERBATIM
  130. for j = 1:128+data.image(data_counter-1)
  131. out_line(j+net_counter) = data.image(data_counter+j-1);
  132. end
  133. net_counter = 128+data.image(data_counter-1)+net_counter;
  134. offset = offset + 127+ data.image(data_counter-1);
  135. else % assume that we're copying value data(data_counter), data(data_counter-1) times.
  136. for j = 1:data.image(data_counter-1)
  137. out_line(j+net_counter) = data.image(data_counter);
  138. end
  139. net_counter = data.image(data_counter-1)+net_counter;
  140. end
  141. end
  142. end
  143. data.image = reshape(out_line,data.dims(1),data.dims(2),data.dims(3));
  144. end