// Definitions of classes that implements useful // concepts for the eddy current project. // // EddyHelperClasses.cpp // // Jesper Andersson, FMRIB Image Analysis Group // // Copyright (C) 2011 University of Oxford // #include #include #include #include #include #include "newmat.h" #include "newimage/newimageall.h" #include "miscmaths/miscmaths.h" #include "EddyHelperClasses.h" #include "EddyUtils.h" using namespace EDDY; //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // // Class DiffPara (Diffusion Parameters) // // This class manages the diffusion parameters for a given // scan. // //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool DiffPara::operator==(const DiffPara& rhs) const { return(EddyUtils::AreInSameShell(*this,rhs) && EddyUtils::HaveSameDirection(*this,rhs)); } //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // // Class AcqPara (Acquisition Parameters) // // This class manages the acquisition parameters for a given // scan. // //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ AcqPara::AcqPara(const NEWMAT::ColumnVector& pevec, double rotime) : _pevec(pevec), _rotime(rotime) { if (pevec.Nrows() != 3) throw EddyException("AcqPara::AcqPara: Wrong dimension pe-vector"); if (rotime < 0.01 || rotime > 0.2) throw EddyException("AcqPara::AcqPara: Unrealistic read-out time"); int cc = 0; //Component count for (int i=0; i<3; i++) { if (fabs(pevec(i+1)) > 1e-6) cc++; } if (!cc) throw EddyException("AcqPara::AcqPara: Zero Phase-encode vector"); if (cc > 1) throw EddyException("AcqPara::AcqPara: Oblique pe-vectors not yet implemented"); } bool AcqPara::operator==(const AcqPara& rh) const { if (fabs(this->_rotime-rh._rotime) > 1e-6) return(false); for (int i=0; i<3; i++) { if (fabs(this->_pevec(i+1)-rh._pevec(i+1)) > 1e-6) return(false); } return(true); } DiffStats::DiffStats(const NEWIMAGE::volume& diff, const NEWIMAGE::volume& mask) : _md(diff.zsize(),0.0), _msd(diff.zsize(),0.0), _n(mask.zsize(),0) { for (int k=0; k > DiffStatsVector::GetOutliers(double nstdev, // # of std to qualify as outlier unsigned int minn) const // Min # of voxels to be considered { std::vector > rvv(NSlice()); for (unsigned int sl=0; sl DiffStatsVector::GetOutliersInSlice(unsigned int sl, double nstdev, // # of std to qualify as outlier unsigned int minn) const // Min # of voxels to be considered { std::vector rv; double mv = slice_mean_mean_diff(sl,minn); double stdev = slice_stdev_mean_diff(sl,minn); // printf("ds.GetOutliersInSlice: Slice %d has a mean diff of %f and an stdev of%f\n",sl,mv,stdev); for (unsigned int s=0; s= minn && // If enough voxels to give reliable estimate std::fabs(_ds[s].MeanDifference(int(sl))-mv) > nstdev*stdev) { // If outlier rv.push_back(s); } } return(rv); } std::vector DiffStatsVector::GetNoOfStdevInSlice(unsigned int sl, unsigned int minn) const // Min # of voxels to be considered { std::vector rv(NScan(),0.0); double mv = slice_mean_mean_diff(sl,minn); double stdev = slice_stdev_mean_diff(sl,minn); // printf("ds.GetOutliersInSlice: Slice %d has a mean diff of %f and an stdev of%f\n",sl,mv,stdev); for (unsigned int s=0; s= minn) { // If enough voxels to give reliable estimate rv[s] = (_ds[s].MeanDifference(int(sl))-mv)/stdev; } } return(rv); } double DiffStatsVector::slice_mean_mean_diff(unsigned int sl, unsigned int minn) const // Min # of voxels to be considered { double mv = 0.0; unsigned int nsl = 0; for (unsigned int s=0; s= minn) { mv += _ds[s].MeanDifference(int(sl)); nsl++; } } mv = (nsl) ? mv/double(nsl) : 0.0; return(mv); } double DiffStatsVector::slice_stdev_mean_diff(unsigned int sl, unsigned int minn) const // Min # of voxels to be considered { double stdev = 0.0; double mv = slice_mean_mean_diff(sl,minn); unsigned int nsl = 0; for (unsigned int s=0; s= minn) { stdev += MISCMATHS::Sqr(mv - _ds[s].MeanDifference(int(sl))); nsl++; } } stdev = (nsl>1) ? std::sqrt(stdev/double(nsl-1)) : 0.0; return(stdev); } ReplacementManager::ReplacementManager(const DiffStatsVector& dsv, double nstdev, unsigned int minn) : _nstdev(nstdev), _minn(minn), _ovv(dsv.NSlice()), _nsv(dsv.NSlice()) { for (unsigned int sl=0; sl oisl = dsv.GetOutliersInSlice(sl,_nstdev,_minn); for (unsigned int i=0; i oisl = dsv.GetOutliersInSlice(sl,_nstdev,_minn); // printf("rm.Update(): slice %d has %d outliers\n",sl,oisl.size()); for (unsigned int i=0; i ReplacementManager::OutliersInScan(unsigned int scan) const { scan_oor(scan); std::vector ol; for (unsigned int sl=0; sl& i2i, const std::string& fname) const { std::ofstream fout; fout.open(fname.c_str(),ios::out|ios::trunc); if (fout.fail()) { cout << "Failed to open outlier report file " << fname << endl; return; } unsigned int nsl = _ovv.size(); unsigned int nscan = _ovv[0].size(); for (unsigned int sl=0; sl