-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathC_sigRMN.cpp
147 lines (131 loc) · 3.98 KB
/
C_sigRMN.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include "C_sigRMN.h"
C_sigRMN::C_sigRMN()
{
}
void C_sigRMN::frameToFix(double t00)//TODO fix the continuity pb due to frame change
{
double tmpX, tmpY;
for(int i=0 ; i<MU.getNbRow() ; i++)
{
//std::cout << T(i,0)+t00 << std::endl;
tmpX = cos(omega*(T(i,0)+t00))*MU(i,0)-sin(omega*(T(i,0)+t00))*MU(i,1);
tmpY = sin(omega*(T(i,0)+t00))*MU(i,0)+cos(omega*(T(i,0)+t00))*MU(i,1);
MU(i,0) = tmpX;
MU(i,1) = tmpY;
}
return;
}
void C_sigRMN::frameToRotating(double t00)
{
double tmpX, tmpY;
for(int i=0 ; i<MU.getNbRow() ; i++)
{
tmpX = cos(omega*(T(i,0)+t00))*MU(i,0)+sin(omega*(T(i,0)+t00))*MU(i,1);
tmpY = -sin(omega*(T(i,0)+t00))*MU(i,0)+cos(omega*(T(i,0)+t00))*MU(i,1);
MU(i,0) = tmpX;
MU(i,1) = tmpY;
}
return;
}
double C_sigRMN::generateRMNsignal(double mx0, double my0, double mz0, double dt, double dw)
{
//init the arrays
MU.resize(sigLength,3);
T.resize(sigLength,1);
MU(0,0)=mx0; MU(0,1)=my0; MU(0,2)=mz0;
double t=0.0;
T(0,0) = 0.0;
//the constant of the problem
double A, B, phi;
//double Bxy = sqrt(Bx*Bx+By*By);
double omega1 = gamma*Bxy;
double wd = sqrt(SQR(omega1) + SQR(dw));
if(ABS(omega1)<SMALL_NUM_F)
{
//the amplitude of the perturbating field is to small to account for any effect of RMN
if(dw<SMALL_NUM_F)
{
//all components of the momentum are set to the initial value, it is a steady state
for(int i=1 ; i<sigLength ; i++)
{
t += dt;
T(i,0)=t;
MU(i,0) = mx0;
MU(i,1) = my0;
MU(i,2) = mz0;
}
return t;
}
else
{
//the rotating frame is not well synchronized with the Larmor frequency imposedd by the magnetic field
A=sqrt(SQR(mx0)+SQR(my0));
phi = atan2(my0,mx0);
for(int i=1 ; i<sigLength ; i++)
{
t += dt;
T(i,0)=t;
MU(i,0) = A*cos(dw*t+phi);
MU(i,1) = A*sin(dw*t+phi);
MU(i,2) = mz0;
}
return t;
}
}
//sample the signal for the general case
A=sqrt(SQR((dw/wd)*mx0 - (omega1/wd)*mz0)+SQR(my0));
phi=atan2(my0,(dw/wd)*mx0 - (omega1/wd)*mz0);
B=(mx0+(dw/omega1)*mz0)/(1+SQR(dw/omega1));
//std::cout << "A " << A << " B " << B << " phi " << phi << std::endl;
for(int i=1 ; i<sigLength ; i++)
{
t += dt;
T(i,0)=t;
MU(i,0) = (dw/wd)*A*cos(wd*t+phi) + B;
MU(i,1) = A*sin(wd*t+phi);
MU(i,2) = -(omega1/wd)*A*cos(wd*t+phi) + (dw/omega1)*B;
}
return t;
}
double C_sigRMN::generateFIDsignal(double mx0, double my0, double mz0, double dt, double dw)
{
//init the arrays
MU.resize(sigLength,3);
T.resize(sigLength,1);
MU(0,0)=mx0; MU(0,1)=my0; MU(0,2)=mz0;
double t=0.0;
T(0,0) = 0.0;
//sample the signal for the general case
double A = sqrt(SQR(mx0)+SQR(my0));
double phi = atan2(my0,mx0);
for(int i=1 ; i<sigLength ; i++)
{
t += dt;
T(i,0)=t;
MU(i,0) = A*exp(-t/T2)*cos(dw*t+phi);
MU(i,1) = A*exp(-t/T2)*sin(dw*t+phi);
MU(i,2) = muz0 + (mz0-muz0)*exp(-t/T1);
}
return t;
}
double C_sigRMN::generateFIDsignalWithDiffusion(double mx0, double my0, double mz0, double dt, double dw)
{
//init the arrays
MU.resize(sigLength,3);
T.resize(sigLength,1);
MU(0,0)=mx0; MU(0,1)=my0; MU(0,2)=mz0;
double t=0.0;
T(0,0) = 0.0;
//sample the signal for the general case
double A = sqrt(SQR(mx0)+SQR(my0));
double phi = atan2(my0,mx0);
for(int i=1 ; i<sigLength ; i++)
{
t += dt;
T(i,0)=t;
MU(i,0) = A*exp(-((t/T2) +(SQR(gamma*G)*D*t*t*t)) )*cos(dw*t+phi);
MU(i,1) = A*exp(-((t/T2) +(SQR(gamma*G)*D*t*t*t)) )*sin(dw*t+phi);
MU(i,2) = muz0 + (mz0-muz0)*exp(-t/T1);
}
return t;
}