|
@@ -218,6 +218,10 @@ namespace Lemma {
|
218
|
218
|
EMEarths[tx]->SetHankelTransformMethod(HankelType);
|
219
|
219
|
EMEarths[tx]->SetTxRxMode(TX);
|
220
|
220
|
TxRx[tx]->SetCurrent(1.);
|
|
221
|
+
|
|
222
|
+ // calculate df TODO, fix for multiple tx frequencies
|
|
223
|
+ df = TxRx[tx]->GetFrequency(0) - Larmor/(2.*PI);
|
|
224
|
+ std::cout << "df=" << df << std::endl;
|
221
|
225
|
}
|
222
|
226
|
for (auto rx : Rx) {
|
223
|
227
|
if (EMEarths.count(rx)) {
|
|
@@ -482,9 +486,35 @@ namespace Lemma {
|
482
|
486
|
// Calcuate vector of all responses
|
483
|
487
|
VectorXcr F = VectorXcr::Zero( PulseI.size() );
|
484
|
488
|
for (int iq=0; iq<PulseI.size(); ++iq) {
|
485
|
|
- // Compute the tipping angle
|
|
489
|
+
|
|
490
|
+ /////////////////////////////////////////////////////////////////////////////
|
|
491
|
+ // Compute the tipping angle for on-resonance
|
|
492
|
+ // Weichman formulation
|
|
493
|
+ /*
|
486
|
494
|
Real sintheta = std::sin(0.5*GAMMA*PulseI(iq)*Taup*(EBT.alpha-EBT.beta));
|
487
|
495
|
F(iq) = -volume*Complex(0,Larmor)*Mn0Abs*(EBR.alpha+EBR.beta)*ejztr*sintheta*PhaseTerm;
|
|
496
|
+ */
|
|
497
|
+
|
|
498
|
+ /////////////////////////////////////////////////////////////////////////////
|
|
499
|
+ // compute tipping ange for off-resonance, from MRSMatlab (Mueller, et. al)
|
|
500
|
+ // but based on seperate works by Grombacher and Walbrecher.
|
|
501
|
+ //theta = atan2(0.5*gamma*pm_vec(n)/taup*(Bcomps.alpha - Bcomps.beta),(2*pi*df));
|
|
502
|
+ //flip_eff = sqrt((0.5*gamma*pm_vec(n)*(Bcomps.alpha - Bcomps.beta)).^2 + ...
|
|
503
|
+ // (2*pi*df*taup).^2 );
|
|
504
|
+ //m = sin(flip_eff) .* sin(theta) + ...
|
|
505
|
+ // 1i*(-1)*sin(theta).*cos(theta) .* (cos(flip_eff) - 1);
|
|
506
|
+ //kern = gamma * earth.erdt^2 * 3.29e-3 * Px .* Bcomps.e_zeta.^2 .* ...
|
|
507
|
+ // (Bcomps.alpha + Bcomps.beta) .* m;
|
|
508
|
+ //K(n,:) = sum(sum(kern.*dh*dz));
|
|
509
|
+ // TODO, benchmark calls to pow below...modern compilers should optimize this
|
|
510
|
+ // Real df = 25; // Hz? df is a class data member
|
|
511
|
+ Real theta = std::atan2( 0.5*GAMMA*PulseI(iq)*(EBT.alpha-EBT.beta), 2*PI*df );
|
|
512
|
+ Real flip_eff = std::sqrt( std::pow(0.5*GAMMA*PulseI(iq)*Taup*(EBT.alpha-EBT.beta),2) +
|
|
513
|
+ std::pow(2*PI*df*Taup,2));
|
|
514
|
+ Complex m = std::sin(flip_eff)*std::sin(theta) +
|
|
515
|
+ Complex(0,-1)*std::sin(theta)*std::cos(theta) * (std::cos(flip_eff) - 1.);
|
|
516
|
+
|
|
517
|
+ F(iq) = -volume*Complex(0,Larmor)*Mn0Abs*(EBR.alpha+EBR.beta)*ejztr*m*PhaseTerm;
|
488
|
518
|
}
|
489
|
519
|
return F;
|
490
|
520
|
}
|