DMRITool  v0.1.1-139-g860d86b4
Diffusion MRI Tool
itkTrackvisHeader.h
Go to the documentation of this file.
1 
11 #ifndef __itkTrackvisHeader_h
12 #define __itkTrackvisHeader_h
13 
14 #include <iostream>
15 #include <string>
16 #include <cstring>
17 
18 #include "utlCoreMacro.h"
19 #include "utlSmartAssert.h"
20 
21 #include "utlDMRI.h"
22 
23 namespace itk
24 {
25 
30 typedef struct {
31  char id_string[6]="TRACK"; // ID string for track file. The first 5 characters must be "TRACK".
32  short int dim[3]; // Dimension of the image volume.
33  float voxel_size[3]; // Voxel size of the image volume.
34  float origin[3]; // Origin of the image volume. This field is not yet being used by TrackVis. That means the origin is always (0, 0, 0).
35  short int n_scalars=0; // Number of scalars saved at each track point (besides x, y and z coordinates).
36  char scalar_name[10][20]; // Name of each scalar. Can not be longer than 20 characters each. Can only store up to 10 names.
37  short int n_properties=0; // Number of properties saved at each track.
38  char property_name[10][20]; // Name of each property. Can not be longer than 20 characters each. Can only store up to 10 names.
39  float vox_to_ras[4][4]; // 4x4 matrix for voxel to RAS (crs to xyz) transformation. If vox_to_ras[3][3] is 0, it means the matrix is not recorded. This field is added from version 2.
40  char reserved[444]; // Reserved space for future version.
41  char voxel_order[4]="RAS"; // Storing order of the original image data. Explained here.
42  char pad2[4]; // Paddings.
43  float image_orientation_patient[6]; // Image orientation of the original image. As defined in the DICOM header.
44  char pad1[2]; // Paddings.
45  unsigned char invert_x; // Inversion/rotation flags used to generate this track file. For internal use only.
46  unsigned char invert_y; // As above.
47  unsigned char invert_z; // As above.
48  unsigned char swap_xy; // As above.
49  unsigned char swap_yz; // As above.
50  unsigned char swap_zx; // As above.
51  int n_count=0; // Number of tracks stored in this track file. 0 means the number was NOT stored.
52  int version=2; // Version number. Current version is 2.
53  int hdr_size=1000; // Size of the header. Used to determine byte swap. Should be 1000.
55 
56 void
58 {
59  memcpy(&hTo, &hFrom, 1000);
60 }
61 
63 bool
65 {
66  for ( int i = 0; i < 3; ++i )
67  {
68  if (h1.dim[i]!=h2.dim[i] || h1.voxel_size[i]!=h2.voxel_size[i])
69  return false;
70  }
71 
72  if (h1.n_scalars!=h2.n_scalars || h1.n_properties!=h2.n_properties)
73  return false;
74 
75  for ( int i = 0; i < h1.n_properties; ++i )
76  {
77  if (strcmp(h1.property_name[i], h2.property_name[i])!=0)
78  return false;
79  }
80  for ( int i = 0; i < h1.n_scalars; ++i )
81  {
82  if (strcmp(h1.scalar_name[i], h2.scalar_name[i])!=0)
83  return false;
84  }
85 
86  return true;
87 }
88 
89 inline std::vector<std::string>
91 {
93 }
94 
95 inline std::vector<std::string>
97 {
99 }
100 
101 inline bool
102 HasPropertyName(const TrackVisHeaderType& header, const std::string& name)
103 {
104  for ( int i = 0; i < header.n_properties; ++i )
105  {
106  if (name==std::string(header.property_name[i]))
107  return true;
108  }
109  return false;
110 }
111 
112 inline bool
113 HasScalarName(const TrackVisHeaderType& header, const std::string& name)
114 {
115  for ( int i = 0; i < header.n_scalars; ++i )
116  {
117  if (name==std::string(header.scalar_name[i]))
118  return true;
119  }
120  return false;
121 }
122 
124 inline int
126 {
127  int num=0;
128  for ( int i = 0; i < header.n_scalars; ++i )
129  {
130  std::string name(header.scalar_name[i]);
131  if (name=="")
132  return num;
133  else
134  num += utl::GetScalarsDimentionByName(name);
135  }
136  return num;
137 }
138 
140 inline int
142 {
143  int num=0;
144  for ( int i = 0; i < header.n_properties; ++i )
145  {
146  std::string name(header.property_name[i]);
147  if (name=="")
148  return num;
149  else
150  num += utl::GetScalarsDimentionByName(name);
151  }
152  return num;
153 }
154 
156 inline void
157 RemoveScalarName(TrackVisHeaderType& header, const std::string& name)
158 {
159  int i=0;
160  for ( i = 0; i < header.n_scalars; ++i )
161  {
162  if (name==std::string(header.scalar_name[i]))
163  break;
164  }
165 
166  for ( int j = i; j+1 < header.n_scalars; ++j )
167  strcpy(header.scalar_name[j], header.scalar_name[j+1]);
168  strcpy(header.scalar_name[header.n_scalars-1], "");
169 
170  header.n_scalars--;
171 }
172 
174 inline void
175 RemovePropertyName(TrackVisHeaderType& header, const std::string& name)
176 {
177  int i=0;
178  for ( i = 0; i < header.n_properties; ++i )
179  {
180  if (name==std::string(header.property_name[i]))
181  break;
182  }
183 
184  for ( int j = i; j+1 < header.n_properties; ++j )
185  strcpy(header.property_name[j], header.property_name[j+1]);
186  strcpy(header.property_name[header.n_properties-1], "");
187 
188  header.n_properties--;
189 }
190 
191 
193 inline void
194 ReadTrackVisHeader( const std::string& filename, TrackVisHeaderType& header )
195 {
196  // read header
197  FILE* file;
198  file = fopen(filename.c_str(), "rb");
199  if (!file)
200  utlGlobalException(true, "Unable to open file " + filename);
201 
202  // read header
203  fseek (file, 0, SEEK_SET);
204  int hsize = fread((char*)(&header), 1, 1000, file);
205  utlGlobalException(hsize!=1000, "reading ERROR");
206  utlGlobalException(strcmp(header.id_string,"TRACK")!=0, "Wrong data format. Magic code is wrong. It is " + std::string(header.id_string) +". Should be 'TRACK'");
207 
208  // In case n_count is not correct, read remaining data file to get the correct n_count
209  fseek (file, 0, SEEK_END);
210  long fsize = ftell(file);
211  long offset=1000;
212  int n_count=0;
213  int dim_scalars=GetDimensionOfScalars(header);
214  int dim_properties=GetDimensionOfProperties(header);
215  while (offset<fsize)
216  {
217  fseek (file, offset, SEEK_SET);
218  int numPoints;
219  fread((char*)&numPoints, sizeof(int), 1, file);
220  offset += 4+ numPoints*(3+dim_scalars)*4 + dim_properties*4;
221  n_count++;
222  }
223 
224  // If n_count is not correct in header, then set it as the correct value from the file.
225  if (n_count!=header.n_count)
226  {
227  utlSAGlobalWarning(n_count!=header.n_count)(n_count)(header.n_count).
228  msg("The number of tracts in the header does not match the actual number of tracts in the file. We set n_count as the actual number of tracts in the file");
229  header.n_count = n_count;
230  }
231  fclose (file);
232 }
233 
235 inline void
236 WriteTrackVisHeader( const TrackVisHeaderType& header, FILE* file )
237 {
238  fseek(file, 0, SEEK_SET);
239  int hsize = fwrite((char*)&header, 1, 1000, file);
240  utlGlobalException (hsize!=1000, "Error when saving the fiber!");
241 }
242 
243 
244 
246 inline void
247 PrintTractVisHeader( const TrackVisHeaderType& header, std::ostream & os=std::cout)
248 {
249  os << "id_string : " << header.id_string << std::endl;
250  os << "version : " << header.version << std::endl;
251  os << "dim : " << header.dim[0] << ", " << header.dim[1] << ", " << header.dim[2] << std::endl;
252  os << "voxel_size : " << header.voxel_size[0] << ", " << header.voxel_size[1] << ", " << header.voxel_size[2] << std::endl;
253  os << "origin : " << header.origin[0] << ", " << header.origin[1] << ", " << header.origin[2] << std::endl;
254  os << "number of tracks : " << header.n_count << std::endl;
255  os << "number of scalars : " << header.n_scalars << std::endl;
256  for ( int i = 0; i < header.n_scalars; ++i )
257  {
258  os << "scalar_name[" << i << "] : " << std::string(header.scalar_name[i]) << std::endl;
259  }
260  os << "number of properties : " << header.n_properties << std::endl;
261  os << "dimension of scalars : " << GetDimensionOfScalars(header) << std::endl;
262  os << "dimension of properties : " << GetDimensionOfProperties(header) << std::endl;
263  for ( int i = 0; i < header.n_properties; ++i )
264  {
265  os << "property_name[" << i << "] : " << std::string(header.property_name[i]) << std::endl;
266  }
267  if (header.vox_to_ras[3][3]!=0)
268  {
269  os << "vox_to_ras : " << header.vox_to_ras[0][0] << ", " << header.vox_to_ras[0][1] << ", " << header.vox_to_ras[0][2] << ", " << header.vox_to_ras[0][3] << std::endl;
270  os << " " << header.vox_to_ras[1][0] << ", " << header.vox_to_ras[1][1] << ", " << header.vox_to_ras[1][2] << ", " << header.vox_to_ras[1][3] << std::endl;
271  os << " " << header.vox_to_ras[2][0] << ", " << header.vox_to_ras[2][1] << ", " << header.vox_to_ras[2][2] << ", " << header.vox_to_ras[2][3] << std::endl;
272  os << " " << header.vox_to_ras[3][0] << ", " << header.vox_to_ras[3][1] << ", " << header.vox_to_ras[3][2] << ", " << header.vox_to_ras[3][3] << std::endl;
273  }
274  os << "voxel_order : " << header.voxel_order << std::endl;
275 
276  const float* a= header.image_orientation_patient;
277  os << "image_orientation : " << a[0]<<","<<a[1]<<","<<a[2]<<","<<a[3]<<","<<a[4]<<","<<a[5]<< std::endl;
278 }
279 
280 }
281 
282 
283 #endif
bool IsSameStructure(const TrackVisHeaderType &h1, const TrackVisHeaderType &h2)
void RemoveScalarName(TrackVisHeaderType &header, const std::string &name)
void RemovePropertyName(TrackVisHeaderType &header, const std::string &name)
bool HasPropertyName(const TrackVisHeaderType &header, const std::string &name)
void PrintTractVisHeader(const TrackVisHeaderType &header, std::ostream &os=std::cout)
void CopyTrackvisHeader(const TrackVisHeaderType &hFrom, TrackVisHeaderType &hTo)
#define utlSAGlobalWarning(expr)
Definition: utlCoreMacro.h:357
std::vector< std::string > CovertChar2DArrayToStringArray(const char arr[][M], int N)
Definition: utlCore.h:605
#define utlGlobalException(cond, expout)
Definition: utlCoreMacro.h:372
int GetDimensionOfScalars(const TrackVisHeaderType &header)
std::vector< std::string > GetPropertyNames(const TrackVisHeaderType &header)
int GetScalarsDimentionByName(const std::string &name)
Definition: utlDMRI.h:93
bool HasScalarName(const TrackVisHeaderType &header, const std::string &name)
void ReadTrackVisHeader(const std::string &filename, TrackVisHeaderType &header)
macros for utlCore
void WriteTrackVisHeader(const TrackVisHeaderType &header, FILE *file)
std::vector< std::string > GetScalarNames(const TrackVisHeaderType &header)
int GetDimensionOfProperties(const TrackVisHeaderType &header)