DMRITool  v0.1.1-139-g860d86b4
Diffusion MRI Tool
DWISimulator.cxx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: DWI Simulator
4 
5  Copyright (c) Pew-Thian Yap, Jian Cheng. All rights reserved.
6  See http://www.unc.edu/~ptyap/ for details.
7 
8  This software is distributed WITHOUT ANY WARRANTY; without even
9  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10  PURPOSE. See the above copyright notices for more information.
11 
12  =========================================================================*/
13 
14 #if defined(_MSC_VER)
15 #pragma warning ( disable : 4786 )
16 #endif
17 
18 #ifdef __BORLANDC__
19 #define ITK_LEAN_AND_MEAN
20 #endif
21 
22 #include <iostream>
23 #include <fstream>
24 #include "DWISimulatorCLP.h"
25 #include "itkImageFileWriter.h"
26 #include "itkVectorImage.h"
27 #include "itkDWIGenerator.h"
28 #include "itkDWIWriter.h"
29 #include "utl.h"
30 
31 int
32 main(int argc, char *argv[])
33 {
34  // GenerateCLP
35  PARSE_ARGS;
36 
37  // Input and Output Image Types
38  typedef itk::VectorImage<float, 3> OutputImageType;
39  OutputImageType::Pointer outputImage;
40 
41  typedef itk::Image<float, 3> ScalarImageType;
42  ScalarImageType::Pointer outputScalarImage;
43 
44  // DWI Generator
46  GeneratorType::Pointer dwiGenerator = GeneratorType::New();
47 
48  dwiGenerator->SetDebug(_DebugArg.isSet());
49 
50  // Generate Data
51  dwiGenerator->SetFileName( _ParameterFile );
52  utlGlobalException(_OutputDWIFile=="" && _OutputODFFile=="" && _OutputEAPFile==""
53  && _OutputMSDFile=="" && _OutputRTOFile=="", "need to set output dwi/odf/eap/peak/rto/msd");
54  dwiGenerator->SetIsOutputDWI(_OutputDWIFile!="");
55  dwiGenerator->SetIsOutputEAP(_OutputEAPFile!="");
56  dwiGenerator->SetIsOutputODF(_OutputODFFile!="");
57  dwiGenerator->SetIsOutputRTO(_OutputRTOFile!="");
58  dwiGenerator->SetIsOutputMSD(_OutputMSDFile!="");
59  if (_MaxNumberOfPeaks>0)
60  {
61  dwiGenerator->SetMaxNumberOfPeaks(_MaxNumberOfPeaks);
62  dwiGenerator->SetPeakType(itk::PeakContainerHelper::GetPeakType(_PeakType));
63  }
64 
65  if ( _SNRArg.isSet() )
66  dwiGenerator->SetSNR( _SNR );
67  if (_NoiseSigmaArg.isSet())
68  dwiGenerator->SetNoiseSigma( _NoiseSigma );
69 
70  utlGlobalException(_SNRArg.isSet() && _NoiseSigmaArg.isSet(), "Only one of these is allowed: --snr or --noisesigma");
71 
72  dwiGenerator->GetSamplingSchemeQSpace()->SetTau(_Tau);
73  dwiGenerator->GetSamplingSchemeRSpace()->SetTau(_Tau);
74 
75  utlGlobalException(!_QSpaceOrientationsArg.isSet() && !_RSpaceOrientationsArg.isSet(), "no gradient files in Q space and R space");
76 
77  GeneratorType::STDVectorPointer bvec(new GeneratorType::STDVectorType());
78  GeneratorType::STDVectorPointer rvec(new GeneratorType::STDVectorType());
79 
80  if (_QSpaceOrientationsArg.isSet())
81  {
82  utlGlobalException(!_BValuesArg.isSet() && !_BFileArg.isSet(), "need to set --bvalues or --bfile");
83  utlGlobalException(_BValuesArg.isSet() && _BFileArg.isSet(), "Only one of these is allowed: --bvalues or --bfile");
84 
85  if (_BValuesArg.isSet())
86  *bvec = _BValues;
87  if (_BFileArg.isSet())
88  utl::ReadVector(_BFile,*bvec);
89 
90  GeneratorType::MatrixPointer qMatrix = utl::ReadGrad<double>(_QSpaceOrientations,DIRECTION_NODUPLICATE, CARTESIAN_TO_CARTESIAN);
91 
92  utlGlobalException(_BFileArg.isSet() && _QSpaceOrientationsArg.isSet() && bvec->size()!=qMatrix->Rows(), "The size in --bfile and --qorientations are not the same");
93 
94  if (bvec->size()>0 && qMatrix->Rows()>0 && bvec->size()!=qMatrix->Rows())
95  utl::MatchBVectorAndGradientMatrix(*bvec, *qMatrix);
96  dwiGenerator->GetSamplingSchemeQSpace()->SetOrientationsCartesian( qMatrix );
97  dwiGenerator->GetSamplingSchemeQSpace()->SetBVector(bvec);
98  }
99 
100  if (_RSpaceOrientationsArg.isSet())
101  {
102  utlGlobalException(!_RValuesArg.isSet() && !_RFileArg.isSet(), "need to set --rvalues or --rfile");
103  utlGlobalException(_RValuesArg.isSet() && _RFileArg.isSet(), "Only one of these is allowed: --rvalues or --rfile");
104 
105  if (_RValuesArg.isSet())
106  *rvec = _RValues;
107  if (_RFileArg.isSet())
108  utl::ReadVector(_RFile,*rvec);
109 
110  GeneratorType::MatrixPointer rMatrix = utl::ReadGrad<double>(_RSpaceOrientations,DIRECTION_NODUPLICATE, CARTESIAN_TO_CARTESIAN);
111 
112  utlGlobalException(_RFileArg.isSet() && _RSpaceOrientationsArg.isSet() && rvec->size()!=rMatrix->Rows(), "The size in --rfile and --rorientations are not the same");
113 
114  if (rvec->size()>0 && rMatrix->Rows()>0 && rvec->size()!=rMatrix->Rows())
115  utl::MatchBVectorAndGradientMatrix(*rvec, *rMatrix);
116  dwiGenerator->GetSamplingSchemeRSpace()->SetOrientationsCartesian( rMatrix );
117  dwiGenerator->GetSamplingSchemeRSpace()->SetRadiusVector(rvec);
118  }
119 
120 
121  if (_BackgroundDiffusionParametersArg.isSet())
122  dwiGenerator->SetBackgroundDiffusionParameterValues(_BackgroundDiffusionParameters);
123 
124  utlGlobalException(_CylinderParameters.size()!=3, "wrong size in --cylinderparam");
125  GeneratorType::CylinderModelPointer cylinder = GeneratorType::CylinderModelType::New();
126  cylinder->SetLength(_CylinderParameters[0]);
127  cylinder->SetRadius(_CylinderParameters[1]);
128  cylinder->SetD0(_CylinderParameters[2]);
129  dwiGenerator->SetCylinderModel(cylinder);
130 
131  dwiGenerator->Update();
132 
133 
134  // Write Output
135 
136  if (_OutputDWIFile!="")
137  {
138  std::cout << "Writing DWI data ... " << std::endl;
139  outputImage = dwiGenerator->GetDWIImage();
140  if (_OutputDWIType!="4D")
141  {
142  typedef itk::DWIWriter<float> DWIWriterType;
143  DWIWriterType::Pointer writer = DWIWriterType::New();
144  writer->SetInput(outputImage);
145  if (_OutputDWIType=="EACHSHELL")
146  writer->SetOutputEachShell(true);
147  writer->SetSamplingSchemeQSpace(dwiGenerator->GetSamplingSchemeQSpace());
148 
149  std::string outputFile_noext, outputFile_ext;
150  utl::GetFileExtension(_OutputDWIFile, outputFile_ext, outputFile_noext);
151  writer->SetConfigurationFile(outputFile_noext + ".txt");
152  writer->SetBFile(outputFile_noext + "_b.txt");
153  writer->SetOrientationFile(outputFile_noext+"_grad.txt");
154  writer->SetDWIFile(outputFile_noext + ".nii.gz");
155  writer->Update();
156  }
157  else
158  {
159  itk::SaveImage<OutputImageType>(outputImage, _OutputDWIFile);
160  }
161 
162  if ( _B0FileArg.isSet() )
163  itk::SaveImage<ScalarImageType>(dwiGenerator->GetB0Image(), _B0File);
164  }
165 
166  if (_OutputEAPFile!="")
167  {
168  std::cout << "Writing EAP data ... " << std::endl;
169  outputImage = dwiGenerator->GetEAPImage();
170  utlException(itk::IsImageEmpty(outputImage), "logical error! eap image does not exist. Need to set --rorientations --rvalues");
171  itk::SaveImage<OutputImageType>(outputImage, _OutputEAPFile);
172  }
173 
174  if (_OutputODFFile!="")
175  {
176  std::cout << "Writing ODF data ... " << std::endl;
177  outputImage = dwiGenerator->GetODFImage();
178  utlException(itk::IsImageEmpty(outputImage), "logical error! odf image does not exist. Need to set --rorientations --rvalues");
179  itk::SaveImage<OutputImageType>(outputImage, _OutputODFFile);
180  }
181 
182  if (_OutputPeakFile!="")
183  {
184  std::cout << "Writing Peak data ... " << std::endl;
185  utlSAGlobalException(_MaxNumberOfPeaks<=0).msg("need to set _MaxNumberOfPeaks in --peaks");
186  outputImage = dwiGenerator->GetPeakImage();
187  utlException(itk::IsImageEmpty(outputImage), "logical error! peak image does not exist");
188  itk::SaveImage<OutputImageType>(outputImage, _OutputPeakFile);
189  }
190 
191  if (_OutputRTOFile!="")
192  {
193  std::cout << "Writing RTO data ... " << std::endl;
194  outputScalarImage = dwiGenerator->GetRTOImage();
195  utlException(itk::IsImageEmpty(outputScalarImage), "logical error! rto image does not exist. Need to set --rorientations --rvalues");
196  itk::SaveImage<ScalarImageType>(outputScalarImage, _OutputRTOFile);
197  }
198 
199  if (_OutputMSDFile!="")
200  {
201  std::cout << "Writing MSD data ... " << std::endl;
202  outputScalarImage = dwiGenerator->GetMSDImage();
203  utlException(itk::IsImageEmpty(outputScalarImage), "logical error! msd image does not exist. Need to set --rorientations --rvalues");
204  itk::SaveImage<ScalarImageType>(outputScalarImage, _OutputMSDFile);
205  }
206 
207  return EXIT_SUCCESS;
208 }
209 
helper functions specifically used in dmritool
bool IsImageEmpty(const SmartPointer< ImageType > &image)
Definition: utlITK.h:435
void MatchBVectorAndGradientMatrix(const T &br, std::vector< T > &vec, const NDArray< T, 2 > &grad)
Definition: utlDMRI.h:480
#define utlException(cond, expout)
Definition: utlCoreMacro.h:548
#define utlSAGlobalException(expr)
Definition: utlCoreMacro.h:362
static PeakType GetPeakType(const std::string &str)
#define utlGlobalException(cond, expout)
Definition: utlCoreMacro.h:372
write gradient file, b values and DWI files (with optional index file)
Definition: itkDWIWriter.h:60
void ReadVector(const std::string &vectorStr, std::vector< T > &vec, const char *cc=" ")
Definition: utlCore.h:1159
Generate DWI data based on provided parameter file.
int main(int argc, char *argv[])
void GetFileExtension(const std::string &fileNameAbsolute, std::string &ext, std::string &fileNoExt)
Definition: utlCore.h:559