DMRITool  v0.1.1-139-g860d86b4
Diffusion MRI Tool
mexGetSPFBasisMatrix.cxx
Go to the documentation of this file.
1 
19 #include <cstdio>
20 #include <iostream>
21 #include <cstdlib>
22 
23 #include "mex.h"
24 #include "utl.h"
25 #include "mexutils.h"
26 #include "mexSTD.h"
27 #include "utlMEX.h"
28 
30 
31 
32 
33 template <typename T>
34  inline void callFunction(mxArray* plhs[], const mxArray* prhs[],
35  const int nlhs,const int nrhs)
36 {
37  utlGlobalException(!utl::mexCheckType<T>(prhs[2]), "type of argument 2 is not consistent");
38 
39  int shRank = mxGetScalar(prhs[0]);
40  int raRank = mxGetScalar(prhs[1]);
41 
42  const mwSize* dimsOrientation = mxGetDimensions(prhs[2]);
43  int row = static_cast<int>(dimsOrientation[0]);
44  int column = static_cast<int>(dimsOrientation[1]);
45 
46  typedef utl::NDArray<double,2> MatrixType;
47 
48  utlException (column!=3, "orientation matrix should have 3 columns (x,y,z)");
49 
50  utl_shared_ptr<MatrixType > qOrientationMatrix( new MatrixType(row, column));
51  utl::GetUtlMatrixFromMXArray(prhs[2], qOrientationMatrix.get());
52  *qOrientationMatrix = utl::CartesianToSpherical(*qOrientationMatrix); // spherical format is used
53 
54  const mwSize* dimsBVectors = mxGetDimensions(prhs[3]);
55  int rowB = static_cast<int>(dimsBVectors[0]);
56  int columnB = static_cast<int>(dimsBVectors[1]);
57 
58  // utlPrintVar2(true, rowB, columnB);
59  utlException(columnB!=1 && rowB!=1, "orientation matrix should have 1 column or 1 row");
60  utlException((columnB==1 && rowB!=row) || (rowB==1 && columnB!=column), "orientation matrix and B vector should have the same number of rows");
61 
62  utl_shared_ptr<std::vector<double> > bVector (new std::vector<double>());
63  utl::GetSTDVectorFromMXArray( prhs[3], bVector.get());
64 
65 
66  typedef double PrecisionType;
67  typedef itk::VectorImage<PrecisionType, 3> VectorImageType;
69  typename SPFIFilterBaseType::Pointer spfiFilter = SPFIFilterBaseType::New();
70  spfiFilter->GetSamplingSchemeQSpace()->SetBVector(bVector);
71  spfiFilter->GetSamplingSchemeQSpace()->SetOrientationsSpherical(qOrientationMatrix);
72  spfiFilter->SetSHRank(shRank);
73  spfiFilter->SetRadialRank(raRank);
74  bool originalBasis = true;
75  if (nrhs>4)
76  {
77  utlGlobalException(mxGetClassID(prhs[4])!=mxSTRUCT_CLASS, "the fifth input has to be a struct");
78  T tau = utl::GetScalarStructDef<T>(prhs[4],"tau", ONE_OVER_4_PI_2); // 4*pi*pi*tau=1
79  spfiFilter->GetSamplingSchemeQSpace()->SetTau(tau);
80 
81  T scale = utl::GetScalarStructDef<T>(prhs[4],"scale", -1.0);
82  if (scale>0)
83  spfiFilter->SetBasisScale(scale);
84 
85  originalBasis = utl::GetScalarStructDef<bool>(prhs[4],"original", true); // 0: original SPF matrix, 1: independent SPF basis matrix
86  }
87 
88 
89  utl_shared_ptr<MatrixType > basisMatrix (new MatrixType());
90  // spfiFilter->SetDebug(true);
91  spfiFilter->ComputeBasisMatrix();
92  basisMatrix = spfiFilter->GetBasisMatrix();
93  // if (basisMatrix)
94  // {
95  // utl::PrintUtlMatrix(*basisMatrix, "basisMatrix");
96  // }
97 
98  if (originalBasis)
99  {
100  utl::GetMXArrayFromUtlMatrix(basisMatrix.get(), plhs[0]);
101  }
102  else
103  {
104 
105  int n_b_sh = (shRank+1)*(shRank+2)/2;
106  int n_b_ra = raRank + 1;
107 
108  MatrixType basisMatrixIndependent;
109 
110  spfiFilter->ComputeRadialVectorForE0InBasis();
111  utl_shared_ptr<std::vector<double> > R_n_0_vec = spfiFilter->GetGn0();
112  basisMatrixIndependent.ReSize(basisMatrix->Rows(), n_b_sh*(n_b_ra-1));
113  // utlException(R_n_0_vec[0]==0, "it should be not zero!, R_n_0_vec[0]="<< R_n_0_vec[0]);
114 
115  for ( int i = 0; i < raRank; i += 1 )
116  {
117  for ( int j = 0; j < n_b_sh; j += 1 )
118  {
119  for ( int ss = 0; ss < basisMatrixIndependent.Rows(); ss += 1 )
120  {
121  basisMatrixIndependent(ss,i*n_b_sh+j) = (*basisMatrix)(ss,(i+1)*n_b_sh+j) - (*R_n_0_vec)[i+1]/(*R_n_0_vec)[0] * (*basisMatrix)(ss,j);
122  }
123  }
124  }
125 
126  utl::GetMXArrayFromUtlMatrix(&basisMatrixIndependent, plhs[0]);
127  }
128 
129 
130  return;
131 }
132 
133 void mexFunction(int nlhs, mxArray *plhs[],
134  int nrhs, const mxArray *prhs[])
135 {
136  utlGlobalException(nrhs!=4 && nrhs!=5, "Bad number of inputs arguments");
137  utlGlobalException(nlhs!=1, "Bad number of outputs arguments");
138 
139  // if (mxGetClassID(prhs[2]) == mxSINGLE_CLASS)
140  // callFunction<float>(plhs,prhs,nlhs,nrhs);
141  // else
142  callFunction<double>(plhs,prhs,nlhs,nrhs);
143 }
144 
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
helper functions specifically used in dmritool
#define utlException(cond, expout)
Definition: utlCoreMacro.h:548
int mwSize
Definition: utils.h:38
NDArray< T, 2 > CartesianToSpherical(const NDArray< T, 2 > &in)
void GetMXArrayFromUtlMatrix(const NDArray< T, 2 > *mat, mxArray *&pr)
Definition: utlMEX.h:50
#define utlGlobalException(cond, expout)
Definition: utlCoreMacro.h:372
#define ONE_OVER_4_PI_2
Definition: utlCoreMacro.h:63
Contains miscellaneous functions for mex files. utl functions for mex code. Some codes are from spams...
void callFunction(mxArray *plhs[], const mxArray *prhs[], const int nlhs, const int nrhs)
void GetUtlMatrixFromMXArray(const mxArray *pr, NDArray< T, 2 > *mat)
Definition: utlMEX.h:33
itk::VectorImage< ScalarType, 3 > VectorImageType
Definition: 4DImageMath.cxx:30
void GetSTDVectorFromMXArray(const mxArray *pr, std::vector< T > *vec)
Definition: mexSTD.h:30