|
@@ -6,6 +6,49 @@ namespace mri {
|
|
|
// ********************************************************************** //
|
|
|
// ********************************************************************** //
|
|
|
// ********************************************************************** //
|
|
|
+ void GeneratorRF::EvaluateApproximateDemodulated(std::vector<double> &mag_sin,
|
|
|
+ std::vector<double> &mag_cos) {
|
|
|
+ std::random_device rd;
|
|
|
+ std::mt19937_64 om;
|
|
|
+ om.seed(rd());
|
|
|
+ double lbound = 0.0, ubound = 1.0;
|
|
|
+ std::uniform_real_distribution<double> rand(lbound, ubound);
|
|
|
+
|
|
|
+ mag_sin.resize(total_samples_);
|
|
|
+ mag_cos.resize(total_samples_);
|
|
|
+ for (unsigned long i = 0; i < total_samples_; ++i) {
|
|
|
+ mag_sin[i] = 0.0;
|
|
|
+ mag_cos[i] = 0.0;
|
|
|
+ double time = timesteps_[i];
|
|
|
+ for (unsigned int voxel = 0; voxel < voxel_num_; ++voxel) {
|
|
|
+ mag_sin[i] +=
|
|
|
+ amplitudes_[voxel]
|
|
|
+ * std::sin(phases_[voxel]
|
|
|
+ )
|
|
|
+ * ApproxExp(1,-time/
|
|
|
+ (T2s_decays_norm_[voxel]*T2s_scale_
|
|
|
+ )
|
|
|
+ )
|
|
|
+ + (rand(om)-0.5)*noise_amplitude_
|
|
|
+
|
|
|
+ ;
|
|
|
+ mag_cos[i] +=
|
|
|
+ amplitudes_[voxel]
|
|
|
+ * std::cos(phases_[voxel]
|
|
|
+ )
|
|
|
+ * ApproxExp(1,-time/
|
|
|
+ (T2s_decays_norm_[voxel]*T2s_scale_
|
|
|
+ )
|
|
|
+ )
|
|
|
+ + (rand(om)-0.5)*noise_amplitude_
|
|
|
+
|
|
|
+ ;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ // ********************************************************************** //
|
|
|
+ // ********************************************************************** //
|
|
|
+ // ********************************************************************** //
|
|
|
void GeneratorRF::EvaluateDemodulated(std::vector<double> &mag_sin,
|
|
|
std::vector<double> &mag_cos) {
|
|
|
std::random_device rd;
|
|
@@ -150,6 +193,45 @@ namespace mri {
|
|
|
// ********************************************************************** //
|
|
|
// ********************************************************************** //
|
|
|
// ********************************************************************** //
|
|
|
+ double GeneratorRF::ApproxExp(int terms, double x){
|
|
|
+ if (terms % 2 == 0)
|
|
|
+ throw std::invalid_argument
|
|
|
+ ("Exponential approximation is only available for even terms!");
|
|
|
+
|
|
|
+ double result = 1.0;
|
|
|
+ for (int i = 1; i < terms+1; ++i) {
|
|
|
+ result += 1.0*std::pow(x,i)/std::tgamma(i+1);
|
|
|
+ // std::cout << " %% " << std::tgamma(i+1)<< " "<< i <<" -> "<<result;
|
|
|
+ }
|
|
|
+ if (result < 0) return 0.0;
|
|
|
+ return result;
|
|
|
+ };
|
|
|
+ // ********************************************************************** //
|
|
|
+ // ********************************************************************** //
|
|
|
+ // ********************************************************************** //
|
|
|
+ double GeneratorRF::TryApproximateFit(const std::vector<double> &values) {
|
|
|
+ SetVoxels(values);
|
|
|
+ double diff = 0.0;
|
|
|
+ std::vector<double> mag_sin, mag_cos;
|
|
|
+ EvaluateApproximateDemodulated(mag_sin, mag_cos);
|
|
|
+
|
|
|
+ for (unsigned long i = 0; i < mag_sin.size(); ++i) {
|
|
|
+ diff += std::abs((base_mag_sin_[i] - mag_sin[i]));
|
|
|
+ diff += std::abs((base_mag_cos_[i] - mag_cos[i]));
|
|
|
+
|
|
|
+ // diff += std::abs((base_mag_sin_[i] - mag_sin[i])
|
|
|
+ // / base_mag_sin_[i]);
|
|
|
+ // diff += std::abs((base_mag_cos_[i] - mag_cos[i])
|
|
|
+ // / base_mag_cos_[i]);
|
|
|
+ // diff += std::abs(
|
|
|
+ // (base_mag_sin_[i]/base_mag_cos_[i] - mag_sin[i]/mag_cos[i])
|
|
|
+ // );
|
|
|
+ }
|
|
|
+ return diff;
|
|
|
+ };
|
|
|
+ // ********************************************************************** //
|
|
|
+ // ********************************************************************** //
|
|
|
+ // ********************************************************************** //
|
|
|
double GeneratorRF::TryFit(const std::vector<double> &values) {
|
|
|
SetVoxels(values);
|
|
|
std::vector<double> mag_sin, mag_cos;
|
|
@@ -159,10 +241,26 @@ namespace mri {
|
|
|
// diff += std::abs((base_mag_sin_[i] - mag_sin[i]));
|
|
|
// diff += std::abs((base_mag_cos_[i] - mag_cos[i]));
|
|
|
|
|
|
- diff += std::abs((base_mag_sin_[i] - mag_sin[i])/mag_sin[i]);
|
|
|
- diff += std::abs((base_mag_cos_[i] - mag_cos[i])/mag_cos[i]);
|
|
|
-
|
|
|
- diff += std::abs(base_mag_sin_[i]/base_mag_cos_[i] - mag_sin[i]/mag_cos[i]);
|
|
|
+ diff += std::abs((base_mag_sin_[i] - mag_sin[i])
|
|
|
+ / //(pow2(
|
|
|
+ base_mag_sin_[i]
|
|
|
+ // )+
|
|
|
+ // pow2(base_mag_cos_[i])
|
|
|
+ // )
|
|
|
+ );
|
|
|
+ diff += std::abs((base_mag_cos_[i] - mag_cos[i])
|
|
|
+ / //(pow2(base_mag_sin_[i])+
|
|
|
+ //pow2(
|
|
|
+ base_mag_cos_[i]
|
|
|
+ // )
|
|
|
+ // )
|
|
|
+ );
|
|
|
+ diff += std::abs(
|
|
|
+ (base_mag_sin_[i]/base_mag_cos_[i] - mag_sin[i]/mag_cos[i])
|
|
|
+ // /((base_mag_sin_[i])+
|
|
|
+ // (base_mag_cos_[i])
|
|
|
+ // )
|
|
|
+ );
|
|
|
}
|
|
|
return diff;
|
|
|
};
|
|
@@ -189,6 +287,15 @@ namespace mri {
|
|
|
// ********************************************************************** //
|
|
|
// ********************************************************************** //
|
|
|
// ********************************************************************** //
|
|
|
+ void GeneratorRF::InitApproximation() {
|
|
|
+ exp_terms_.resize(voxel_num_);
|
|
|
+ for (auto &term:exp_terms_) {
|
|
|
+ term = 1;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ // ********************************************************************** //
|
|
|
+ // ********************************************************************** //
|
|
|
+ // ********************************************************************** //
|
|
|
void GeneratorRF::InitVoxels(unsigned int voxel_num, double phase_init,
|
|
|
double phase_range, double T2s_scale) {
|
|
|
T2s_scale_ = T2s_scale;
|
|
@@ -202,8 +309,8 @@ namespace mri {
|
|
|
double phase_step = phase_range_/(voxel_num_ - 1);
|
|
|
phases_.resize(voxel_num);
|
|
|
for (unsigned int i =0; i< voxel_num_; ++i) {
|
|
|
- //phases_[i] = phase_init_ + i*phase_step;
|
|
|
- phases_[i] = phase_init_ + std::sin(1.0*i/voxel_num_);
|
|
|
+ phases_[i] = phase_init_ + i*phase_step;
|
|
|
+ //phases_[i] = phase_init_ + std::sin(1.0*i/voxel_num_);
|
|
|
std::cout<<phases_[i]<<std::endl;
|
|
|
}
|
|
|
};
|