am2geom.m 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. function Geometry = am2geom(AmiraMeshFile)
  2. % Geometry = am2geom(AmiraMeshFile) converts an AmiraMesh (.am) file to a
  3. % geometry structure, as long as the .am file is written in the recognized
  4. % format. The Geometry structure has the form:
  5. %
  6. % Geometry =
  7. % start: [3x1 double]
  8. % voxel_size: [3x1 double]
  9. % data: [MxNxQ double]
  10. %
  11. % Example acceptable .am file format:
  12. %
  13. % # AmiraMesh 3D BINARY 2.0
  14. %
  15. % # CreationDate: Thu Jun 01 15:42:59 2006
  16. %
  17. %
  18. % define Lattice 509 509 3
  19. %
  20. % Parameters {
  21. % Content "509x509x36 short, uniform coordinates",
  22. % BoundingBox -25.48 25.32 -25.48 25.32 9 26.5,
  23. % CoordType "uniform"
  24. % }
  25. %
  26. % Lattice { short Data } @1
  27. %
  28. % # Data section follows
  29. % @1
  30. %
  31. % Ryan T Flynn 23 August 2007
  32. %
  33. % ensure that the user input a string
  34. if ~ischar(AmiraMeshFile)
  35. error('AmiraMeshFile must be a character string.');
  36. end
  37. % open the file
  38. fid = fopen(AmiraMeshFile,'r');
  39. if fid == -1
  40. error('Could not open %s.',AmiraMeshFile);
  41. end
  42. % Things to look for in the .am file:
  43. % 1) The 'BINARY' or 'ASCII' words
  44. % 2) The lattice size after the 'define Lattice' words
  45. % 3) The BoundingBox line, which is used to calculate start and voxel_size
  46. % 4) CoordType "uniform" line
  47. tline = fgetl(fid);
  48. % continue to read the file until the line containing only '@1' is found
  49. while ~strncmp(tline,'@1',2)
  50. if ~isempty(regexp(tline,'AmiraMesh 3D'))
  51. % found the BINARY or ASCII specification line
  52. p = regexp(tline,'AmiraMesh 3D'); % find the position of the key words
  53. r = tline(p+length('AmiraMesh 3D'):end); % get the remainder of the string
  54. binORascii = strtok(r); % pop off the data type (either BINARY or ASCII)
  55. end
  56. if ~isempty(regexp(tline,'define Lattice'))
  57. % found the lattice definition line
  58. p = regexp(tline,'define Lattice'); % find the position of the key words
  59. r = tline(p+length('define Lattice'):end); % get the remainder of the string
  60. siz = str2num(r); % convert the remainder to the lattice dimensions
  61. if length(siz) ~= 3
  62. error('Data lattice must be 3D.');
  63. end
  64. end
  65. if ~isempty(regexp(tline,'BoundingBox'))
  66. % found the bounding box line
  67. p = regexp(tline,'BoundingBox'); % position of BoundingBox word
  68. r = tline(p+length('BoundingBox'):end); % remainder of the string
  69. box = str2num(r); % convert the remainder to the box dimensions
  70. if length(box) ~= 6
  71. error('Number of parameters in BoundingBox line must be 6.');
  72. end
  73. end
  74. % Lattice { short Data } @1
  75. if ~isempty(regexp(tline,'Lattice {'))
  76. % found line that contains the data type for the grid
  77. p = regexp(tline,'Lattice {'); % position of BoundingBox word
  78. r = tline(p+length('Lattice {'):end); % remainder of the string
  79. AmiraDataType = strtok(r); % pop off the data type
  80. % Figure out what the data type is
  81. for k=1:6
  82. if strcmp(AmiraDataType,'byte')
  83. MatlabDataType = 'int8';
  84. elseif strcmp(AmiraDataType,'short')
  85. MatlabDataType = 'int16';
  86. elseif strcmp(AmiraDataType,'ushort')
  87. MatlabDataType = 'uint16';
  88. elseif strcmp(AmiraDataType,'int32')
  89. MatlabDataType = 'int32';
  90. elseif strcmp(AmiraDataType,'float')
  91. MatlabDataType = 'single';
  92. elseif strcmp(AmiraDataType,'double')
  93. MatlabDataType = 'double';
  94. else
  95. error('Amira data type in %s is not supported by Matlab.',AmiraMeshFile);
  96. end
  97. end
  98. end
  99. tline = fgetl(fid);
  100. end
  101. % ensure that all of the required lines were found
  102. if ~exist('binORascii')
  103. error('Could not determine of data are stored in binary or ascii format.');
  104. end
  105. if ~exist('siz')
  106. error('Could not find the data dimensions during the reading process.');
  107. end
  108. if ~exist('box')
  109. error('Could not find the bounding box in the reading process.');
  110. end
  111. if ~exist(MatlabDataType)
  112. error('Could not find the data type for file %s.',AmiraMeshFile);
  113. end
  114. % ensure that the data are stored in binary format
  115. if ~strcmp(binORascii,'BINARY')
  116. error('Data in %s must be stored in binary format.',AmiraMeshFile);
  117. end
  118. % calculate the voxel_size vector
  119. if siz(1) == 1
  120. Geometry.voxel_size(1) = box(2) - box(1);
  121. elseif siz(1) > 1
  122. Geometry.voxel_size(1) = (box(2) - box(1))/(siz(1)-1);
  123. else
  124. error('First dimension of data lattice must be greater than zero.');
  125. end
  126. if siz(2) == 1
  127. Geometry.voxel_size(2) = box(4) - box(3);
  128. elseif siz(2) > 1
  129. Geometry.voxel_size(2) = (box(4) - box(3))/(siz(2)-1);
  130. else
  131. error('Second dimension of data lattice must be greater than zero.');
  132. end
  133. if siz(3) == 1
  134. Geometry.voxel_size(3) = box(6) - box(5);
  135. elseif siz(3) > 1
  136. Geometry.voxel_size(3) = (box(6) - box(5))/(siz(3)-1);
  137. else
  138. error('Third dimension of data lattice must be greater than zero.');
  139. end
  140. % calculate the start vector
  141. Geometry.start(1) = box(1);
  142. Geometry.start(2) = box(3);
  143. Geometry.start(3) = box(5);
  144. % allocate space for the data
  145. Geometry.data = zeros(siz,MatlabDataType);
  146. % read in the data
  147. Geometry.data = fread(fid,[MatlabDataType '=>' MatlabDataType],'ieee-be');
  148. % If reading byte-by-byte, throw out last byte -- it's just a carriage return
  149. if strcmp(MatlabDataType,'int8')
  150. Geometry.data(end,:) = [];
  151. end
  152. Geometry.data = reshape(Geometry.data,siz(1),siz(2),siz(3));
  153. % close the AmiraMesh file
  154. fclose(fid);