MRArbGrad 3.0.1__tar.gz → 4.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0/MRArbGrad.egg-info}/PKG-INFO +9 -8
  2. {mrarbgrad-3.0.1/MRArbGrad.egg-info → mrarbgrad-4.0.0}/PKG-INFO +9 -8
  3. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/README.md +8 -7
  4. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/example/example_BuiltInTraj.py +2 -2
  5. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/Function.py +28 -4
  6. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/__init__.py +1 -1
  7. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/ext/mag/Mag.cpp +31 -25
  8. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/ext/mag/Mag.h +41 -25
  9. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/ext/main.cpp +29 -17
  10. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/ext/traj/Cones.h +12 -18
  11. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/ext/traj/MrTraj.h +36 -35
  12. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/ext/traj/MrTraj_2D.h +11 -17
  13. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/ext/traj/Rosette.h +2 -5
  14. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/ext/traj/Seiffert.h +4 -13
  15. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/ext/traj/Shell3d.h +14 -21
  16. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/ext/traj/Spiral.h +1 -1
  17. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/ext/traj/VDSpiral.h +24 -48
  18. mrarbgrad-4.0.0/mrarbgrad_src/ext/traj/Yarnball.h +146 -0
  19. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/ext/utility/Intp.h +19 -18
  20. mrarbgrad-4.0.0/mrarbgrad_src/ext/utility/LinIntp.h +73 -0
  21. mrarbgrad-4.0.0/mrarbgrad_src/ext/utility/SplineIntp.h +136 -0
  22. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/ext/utility/global.h +4 -3
  23. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/ext/utility/v3.cpp +4 -0
  24. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/pyproject.toml +1 -1
  25. mrarbgrad-3.0.1/mrarbgrad_src/ext/traj/Yarnball.h +0 -195
  26. mrarbgrad-3.0.1/mrarbgrad_src/ext/utility/LinIntp.h +0 -62
  27. mrarbgrad-3.0.1/mrarbgrad_src/ext/utility/SplineIntp.h +0 -104
  28. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/LICENSE +0 -0
  29. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/MANIFEST.in +0 -0
  30. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/MRArbGrad.egg-info/SOURCES.txt +0 -0
  31. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/MRArbGrad.egg-info/dependency_links.txt +0 -0
  32. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/MRArbGrad.egg-info/requires.txt +0 -0
  33. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/MRArbGrad.egg-info/top_level.txt +0 -0
  34. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/example/example_ExternalFunction2D.py +0 -0
  35. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/example/example_ExternalSamples2D.py +0 -0
  36. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/example/example_ExternalSamples3D.py +0 -0
  37. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/Utility.py +0 -0
  38. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/ext/traj/TrajFunc.h +0 -0
  39. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/ext/utility/global.cpp +0 -0
  40. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/ext/utility/v3.h +0 -0
  41. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/trajfunc/__init__.py +0 -0
  42. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/mrarbgrad_src/trajfunc/main.py +0 -0
  43. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/setup.cfg +0 -0
  44. {mrarbgrad-3.0.1 → mrarbgrad-4.0.0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MRArbGrad
3
- Version: 3.0.1
3
+ Version: 4.0.0
4
4
  Summary: Gradient waveform design tool for arbitrary k-space trajectories.
5
5
  Author-email: Ryan <ryan_shanghaitech@proton.me>
6
6
  License-Expression: MIT
@@ -27,13 +27,13 @@ $ conda install python==3.12 -y
27
27
 
28
28
  This package is **NOT** restricted to use `Python 3.12`. Feel free to adjust at your convenience, just if the package works.
29
29
 
30
- To install the pip package of the proposed algorithm (including the trajectory library built on it):
30
+ To install this package from PyPI:
31
31
  ```bash
32
- $ bash install.bash
32
+ $ pip install mrarbgrad
33
33
  ```
34
- or
34
+ To install this package from a local repository:
35
35
  ```bash
36
- $ pip install mrarbgrad
36
+ $ bash install.bash
37
37
  ```
38
38
 
39
39
  You can also install via `pip install .` but remember to delete `*.egg-info` or pip will run into bug when uninstalling this package in current folder (see comments in `install.bash`).
@@ -41,7 +41,8 @@ You can also install via `pip install .` but remember to delete `*.egg-info` or
41
41
  ## Examples & Usages
42
42
  Examples for generating gradient waveforms for either built-in trajectory (trajectory library) or external trajectory (expressed by trajectory function or trajectory samples) can be found in the `example` folder.
43
43
 
44
- ## Citation
45
- If this project helps you, please cite [our paper](https://arxiv.org/abs/2507.21625):
44
+ ## Reference
45
+ If this project helps you, please cite [our paper](https://ieeexplore.ieee.org/document/11352950):
46
+
47
+ [1] Luo R, Huang H, Miao Q, Xu J, Hu P, Qi H. Real-Time Gradient Waveform Design for Arbitrary k-Space Trajectories. IEEE Transactions on Biomedical Engineering. 2026;1–12.
46
48
 
47
- [1] R. Luo, H. Huang, Q. Miao, J. Xu, P. Hu, and H. Qi, “Real-Time Gradient Waveform Design for Arbitrary k-Space Trajectories,” Sep 9, 2025, arXiv preprint arXiv:2507.21625.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MRArbGrad
3
- Version: 3.0.1
3
+ Version: 4.0.0
4
4
  Summary: Gradient waveform design tool for arbitrary k-space trajectories.
5
5
  Author-email: Ryan <ryan_shanghaitech@proton.me>
6
6
  License-Expression: MIT
@@ -27,13 +27,13 @@ $ conda install python==3.12 -y
27
27
 
28
28
  This package is **NOT** restricted to use `Python 3.12`. Feel free to adjust at your convenience, just if the package works.
29
29
 
30
- To install the pip package of the proposed algorithm (including the trajectory library built on it):
30
+ To install this package from PyPI:
31
31
  ```bash
32
- $ bash install.bash
32
+ $ pip install mrarbgrad
33
33
  ```
34
- or
34
+ To install this package from a local repository:
35
35
  ```bash
36
- $ pip install mrarbgrad
36
+ $ bash install.bash
37
37
  ```
38
38
 
39
39
  You can also install via `pip install .` but remember to delete `*.egg-info` or pip will run into bug when uninstalling this package in current folder (see comments in `install.bash`).
@@ -41,7 +41,8 @@ You can also install via `pip install .` but remember to delete `*.egg-info` or
41
41
  ## Examples & Usages
42
42
  Examples for generating gradient waveforms for either built-in trajectory (trajectory library) or external trajectory (expressed by trajectory function or trajectory samples) can be found in the `example` folder.
43
43
 
44
- ## Citation
45
- If this project helps you, please cite [our paper](https://arxiv.org/abs/2507.21625):
44
+ ## Reference
45
+ If this project helps you, please cite [our paper](https://ieeexplore.ieee.org/document/11352950):
46
+
47
+ [1] Luo R, Huang H, Miao Q, Xu J, Hu P, Qi H. Real-Time Gradient Waveform Design for Arbitrary k-Space Trajectories. IEEE Transactions on Biomedical Engineering. 2026;1–12.
46
48
 
47
- [1] R. Luo, H. Huang, Q. Miao, J. Xu, P. Hu, and H. Qi, “Real-Time Gradient Waveform Design for Arbitrary k-Space Trajectories,” Sep 9, 2025, arXiv preprint arXiv:2507.21625.
@@ -13,13 +13,13 @@ $ conda install python==3.12 -y
13
13
 
14
14
  This package is **NOT** restricted to use `Python 3.12`. Feel free to adjust at your convenience, just if the package works.
15
15
 
16
- To install the pip package of the proposed algorithm (including the trajectory library built on it):
16
+ To install this package from PyPI:
17
17
  ```bash
18
- $ bash install.bash
18
+ $ pip install mrarbgrad
19
19
  ```
20
- or
20
+ To install this package from a local repository:
21
21
  ```bash
22
- $ pip install mrarbgrad
22
+ $ bash install.bash
23
23
  ```
24
24
 
25
25
  You can also install via `pip install .` but remember to delete `*.egg-info` or pip will run into bug when uninstalling this package in current folder (see comments in `install.bash`).
@@ -27,7 +27,8 @@ You can also install via `pip install .` but remember to delete `*.egg-info` or
27
27
  ## Examples & Usages
28
28
  Examples for generating gradient waveforms for either built-in trajectory (trajectory library) or external trajectory (expressed by trajectory function or trajectory samples) can be found in the `example` folder.
29
29
 
30
- ## Citation
31
- If this project helps you, please cite [our paper](https://arxiv.org/abs/2507.21625):
30
+ ## Reference
31
+ If this project helps you, please cite [our paper](https://ieeexplore.ieee.org/document/11352950):
32
+
33
+ [1] Luo R, Huang H, Miao Q, Xu J, Hu P, Qi H. Real-Time Gradient Waveform Design for Arbitrary k-Space Trajectories. IEEE Transactions on Biomedical Engineering. 2026;1–12.
32
34
 
33
- [1] R. Luo, H. Huang, Q. Miao, J. Xu, P. Hu, and H. Qi, “Real-Time Gradient Waveform Design for Arbitrary k-Space Trajectories,” Sep 9, 2025, arXiv preprint arXiv:2507.21625.
@@ -29,10 +29,10 @@ mag.setDbgPrint(1) # enable debug info (for benchmark purpose)
29
29
  # lstArrK0, lstArrGrad = mag.getG_Spiral(**argCom); nAx = 2
30
30
  # lstArrK0, lstArrGrad = mag.getG_VDSpiral(**argCom); nAx = 2
31
31
  # lstArrK0, lstArrGrad = mag.getG_VDSpiral_RT(**argCom); nAx = 2
32
- lstArrK0, lstArrGrad = mag.getG_Rosette(**argCom); nAx = 2
32
+ # lstArrK0, lstArrGrad = mag.getG_Rosette(**argCom); nAx = 2
33
33
  # lstArrK0, lstArrGrad = mag.getG_Rosette_Trad(**argCom); nAx = 2
34
34
  # lstArrK0, lstArrGrad = mag.getG_Shell3d(**argCom); nAx = 3
35
- # lstArrK0, lstArrGrad = mag.getG_Yarnball(**argCom); nAx = 3
35
+ lstArrK0, lstArrGrad = mag.getG_Yarnball(**argCom); nAx = 3
36
36
  # lstArrK0, lstArrGrad = mag.getG_Seiffert(**argCom); nAx = 3
37
37
  # lstArrK0, lstArrGrad = mag.getG_Cones(**argCom); nAx = 3
38
38
 
@@ -142,7 +142,6 @@ def getG_VDSpiral_RT\
142
142
 
143
143
  kRhoPhi0: float64 = 0.5 / (8 * pi),
144
144
  kRhoPhi1: float64 = 0.5 / (2 * pi),
145
- nAcq: int64 = 1000,
146
145
  ) -> tuple[list[NDArray], list[NDArray]]:
147
146
  '''
148
147
  :return: list of trajectory start, list of gradient waveforms
@@ -158,9 +157,7 @@ def getG_VDSpiral_RT\
158
157
  float64(dt),
159
158
 
160
159
  float64(kRhoPhi0),
161
- float64(kRhoPhi1),
162
-
163
- int64(nAcq)
160
+ float64(kRhoPhi1)
164
161
  )
165
162
 
166
163
  def getG_Rosette\
@@ -285,6 +282,33 @@ def getG_Yarnball\
285
282
  float64(kRhoPhi),
286
283
  )
287
284
 
285
+ def getG_Yarnball_RT\
286
+ (
287
+ fov: float64 = 0.256,
288
+ nPix: int64 = 256,
289
+
290
+ sLim: float64 = 50 * 42.5756e6 * 0.256 / 256,
291
+ gLim: float64 = 50e-3 * 42.5756e6 * 0.256 / 256,
292
+ dt: float64 = 10e-6,
293
+
294
+ kRhoPhi: float64 = 0.5 / (2 * pi)
295
+ ) -> tuple[list[NDArray], list[NDArray]]:
296
+ '''
297
+ :return: list of trajectory start, list of gradient waveforms
298
+ :rtype: tuple[list[NDArray], list[NDArray]]
299
+ '''
300
+ return ext.getG_Yarnball_RT\
301
+ (
302
+ float64(fov),
303
+ int64(nPix),
304
+
305
+ float64(sLim),
306
+ float64(gLim),
307
+ float64(dt),
308
+
309
+ float64(kRhoPhi)
310
+ )
311
+
288
312
  def getG_Seiffert\
289
313
  (
290
314
  fov: float64 = 0.256,
@@ -1,5 +1,5 @@
1
1
  from .Function import calGrad4ExFunc, calGrad4ExSamp
2
- from .Function import getG_Cones, getG_Rosette, getG_Rosette_Trad, getG_Seiffert, getG_Shell3d, getG_Spiral, getG_VDSpiral, getG_VDSpiral_RT, getG_Yarnball
2
+ from .Function import getG_Cones, getG_Rosette, getG_Rosette_Trad, getG_Seiffert, getG_Shell3d, getG_Spiral, getG_VDSpiral, getG_VDSpiral_RT, getG_Yarnball, getG_Yarnball_RT
3
3
  from .Function import setSolverMtg, setTrajRev, setGoldAng, setShuf, setMaxG0, setMaxG1, setMagOverSamp, setMagSFS, setMagGradRep, setMagTrajRep, setDbgPrint
4
4
  from .Utility import _calDiaphony, rotate, _calJacElip, _calCompElipInt, _calSphFibPt, cvtGrad2Traj, getGoldang, getGoldrat, rand3d, gradClip
5
5
 
@@ -2,9 +2,7 @@
2
2
  #include <algorithm>
3
3
  #include <cstdio>
4
4
  #include "../utility/global.h"
5
- #include "../utility/LinIntp.h"
6
5
  #include "Mag.h"
7
- #include "../utility/SplineIntp.h"
8
6
 
9
7
  i64 gMag_oversamp = -1; // oversample ratio, overwrite the set value
10
8
  bool gMag_enSFS = false; // Single Forward Sweep flag
@@ -14,18 +12,28 @@ i64 gMag_nTrajSamp = 1000; // num. of samp. when doing Traj. Rep.
14
12
 
15
13
  Mag::Mag()
16
14
  {
15
+ // for solver
17
16
  m_dt = 10e-6; m_oversamp = 8;
18
- i64 nSampReserve = i64(100e-3/m_dt*m_oversamp); // reserve for 100ms
17
+ i64 nSampReserve = i64(100e-3/m_dt); // reserve for 100ms
19
18
 
20
- m_vf64P_Bac.reserve(nSampReserve);
21
- m_vv3G_Bac.reserve(nSampReserve);
22
- m_vf64GNorm_Bac.reserve(nSampReserve);
19
+ m_vf64P_Bac.reserve(nSampReserve*m_oversamp);
20
+ m_vv3G_Bac.reserve(nSampReserve*m_oversamp);
21
+ m_vf64GNorm_Bac.reserve(nSampReserve*m_oversamp);
23
22
 
24
- m_vf64P_For.reserve(nSampReserve);
25
- m_vv3G_For.reserve(nSampReserve);
23
+ m_vf64P_For.reserve(nSampReserve*m_oversamp);
24
+ m_vv3G_For.reserve(nSampReserve*m_oversamp);
25
+
26
+ m_vf64P.reserve(nSampReserve);
27
+ m_vv3G.reserve(nSampReserve);
28
+
29
+ // for trajectory reparameterization
30
+ m_vv3TrajSamp.resize(gMag_nTrajSamp);
31
+
32
+ m_intp.init(nSampReserve*m_oversamp);
33
+ m_intp.m_eSearchMode = Intp::ECached;
26
34
  }
27
35
 
28
- bool Mag::setup
36
+ bool Mag::init
29
37
  (
30
38
  TrajFunc* ptTraj,
31
39
  f64 sLim, f64 gLim,
@@ -42,15 +50,14 @@ bool Mag::setup
42
50
 
43
51
  if (gMag_enTrajRep)
44
52
  {
45
- vv3 vv3TrajSamp(gMag_nTrajSamp);
46
53
  f64 p0 = ptTraj->getP0();
47
54
  f64 p1 = ptTraj->getP1();
48
55
  for (i64 i = 0; i < gMag_nTrajSamp; ++i)
49
56
  {
50
57
  f64 p = p0 + (p1-p0) * (i)/f64(gMag_nTrajSamp-1);
51
- ptTraj->getK(&vv3TrajSamp[i], p);
58
+ ptTraj->getK(&m_vv3TrajSamp[i], p);
52
59
  }
53
- m_sptfTraj = Spline_TrajFunc(vv3TrajSamp);
60
+ m_sptfTraj = Spline_TrajFunc(m_vv3TrajSamp);
54
61
  m_ptfTraj = &m_sptfTraj;
55
62
  }
56
63
  else
@@ -61,7 +68,7 @@ bool Mag::setup
61
68
  return true;
62
69
  }
63
70
 
64
- bool Mag::setup
71
+ bool Mag::init
65
72
  (
66
73
  const vv3& vv3TrajSamp,
67
74
  f64 sLim, f64 gLim,
@@ -166,8 +173,8 @@ bool Mag::solve(vv3* pvv3G, vf64* pvf64P)
166
173
  bool ret = true;
167
174
  f64 p0 = m_ptfTraj->getP0();
168
175
  f64 p1 = m_ptfTraj->getP1();
169
- vv3 vv3G; if (!pvv3G) pvv3G = &vv3G;
170
- vf64 vf64P; if (!pvf64P) pvf64P = &vf64P;
176
+ m_vv3G.clear(); if (!pvv3G) pvv3G = &m_vv3G;
177
+ m_vf64P.clear(); if (!pvf64P) pvf64P = &m_vf64P;
171
178
  bool isQDESucc = true; (void)isQDESucc;
172
179
  i64 nIter = 0;
173
180
 
@@ -217,10 +224,7 @@ bool Mag::solve(vv3* pvv3G, vf64* pvf64P)
217
224
  std::reverse(m_vf64P_Bac.begin(), m_vf64P_Bac.end());
218
225
  std::reverse(m_vf64GNorm_Bac.begin(), m_vf64GNorm_Bac.end());
219
226
 
220
- LinIntp intp;
221
- // SplineIntp intp;
222
- intp.m_eSearchMode = Intp::ECached;
223
- if (!gMag_enSFS) intp.fit(m_vf64P_Bac, m_vf64GNorm_Bac);
227
+ if (!gMag_enSFS) m_intp.fit(m_vf64P_Bac, m_vf64GNorm_Bac);
224
228
 
225
229
  nIter += m_vf64P_Bac.size();
226
230
 
@@ -231,7 +235,7 @@ bool Mag::solve(vv3* pvv3G, vf64* pvf64P)
231
235
  f64 g0Norm = m_g0Norm;
232
236
  g0Norm = std::min(g0Norm, m_gLim);
233
237
  g0Norm = std::min(g0Norm, std::sqrt(m_sLim*getCurRad(p0)));
234
- g0Norm = std::min(g0Norm, gMag_enSFS?1e15:intp.eval(p0));
238
+ g0Norm = std::min(g0Norm, gMag_enSFS?1e15:m_intp.eval(p0));
235
239
  v3 g0 = g0Unit * g0Norm;
236
240
 
237
241
  m_vf64P_For.clear(); m_vf64P_For.push_back(p0);
@@ -252,7 +256,7 @@ bool Mag::solve(vv3* pvv3G, vf64* pvf64P)
252
256
  }
253
257
  else
254
258
  {
255
- f64 gNormBac = intp.eval(p);
259
+ f64 gNormBac = m_intp.eval(p);
256
260
  gNorm = std::min(gNorm, gNormBac);
257
261
  if (gNormBac<=0)
258
262
  {
@@ -410,17 +414,19 @@ f64 Mag::ramp_back(vv3* pvv3GRamp, const v3& g1, const v3& g1Des, i64 nSamp, f64
410
414
  bool Mag::revGrad(v3* pv3M0Dst, vv3* pvv3Dst, const v3& v3M0Src, const vv3& vv3Src, f64 dt)
411
415
  {
412
416
  bool ret = true;
417
+ i64 nSamp = vv3Src.size();
413
418
 
414
- if(vv3Src.size() <= 1) ret = false;
419
+ ASSERT(nSamp > 1);
420
+ ASSERT((i64)pvv3Dst->capacity() >= nSamp);
415
421
 
416
422
  // derive Total M0
417
423
  *pv3M0Dst = v3M0Src + calM0(vv3Src, dt);
418
424
 
419
425
  // reverse gradient
420
- *pvv3Dst = vv3(vv3Src.rbegin(), vv3Src.rend());
421
- for (int64_t i = 0; i < (i64)pvv3Dst->size(); ++i)
426
+ pvv3Dst->resize(nSamp);
427
+ for (int64_t i = 0; i < nSamp; ++i)
422
428
  {
423
- (*pvv3Dst)[i] *= -1;
429
+ (*pvv3Dst)[i] = vv3Src[nSamp-1-i]*(-1);
424
430
  }
425
431
 
426
432
  return ret;
@@ -10,45 +10,58 @@
10
10
  #include "../utility/v3.h"
11
11
  #include "../traj/TrajFunc.h"
12
12
  #include "../utility/SplineIntp.h"
13
+ #include "../utility/LinIntp.h"
14
+
15
+ extern i64 gMag_oversamp;
16
+ extern bool gMag_enSFS;
17
+ extern bool gMag_enGradRep;
18
+ extern bool gMag_enTrajRep;
19
+ extern i64 gMag_nTrajSamp;
13
20
 
14
21
  // virtual TrajFunc, take in discrete samples and construct a Segmentied Cubic Polynomial function
15
22
  class Spline_TrajFunc: public TrajFunc
16
23
  {
17
24
  public:
18
25
  Spline_TrajFunc():
19
- TrajFunc(0,0)
26
+ TrajFunc(0,0),
27
+ m_intpX(gMag_nTrajSamp),
28
+ m_intpY(gMag_nTrajSamp),
29
+ m_intpZ(gMag_nTrajSamp)
20
30
  {}
21
31
 
22
32
  Spline_TrajFunc(const vv3& vv3K):
23
- TrajFunc(0,0)
33
+ TrajFunc(0,0),
34
+ m_intpX(vv3K.size()),
35
+ m_intpY(vv3K.size()),
36
+ m_intpZ(vv3K.size())
24
37
  {
25
38
  i64 lNTrajSamp = vv3K.size();
26
39
 
27
- vf64 vdP(lNTrajSamp);
28
- vdP[0] = 0;
40
+ vf64 vf64P(lNTrajSamp);
41
+ vf64P[0] = 0;
29
42
  for (i64 i = 1; i < lNTrajSamp; ++i)
30
43
  {
31
- vdP[i] = vdP[i-1] + v3::norm(vv3K[i] - vv3K[i-1]);
44
+ vf64P[i] = vf64P[i-1] + v3::norm(vv3K[i] - vv3K[i-1]);
32
45
  }
33
46
 
34
- vf64 vdX(lNTrajSamp), vdY(lNTrajSamp), vdZ(lNTrajSamp);
47
+ vf64 vf64X(lNTrajSamp), vf64Y(lNTrajSamp), vf64Z(lNTrajSamp);
35
48
  for (i64 i = 0; i < lNTrajSamp; ++i)
36
49
  {
37
- vdX[i] = vv3K[i].x;
38
- vdY[i] = vv3K[i].y;
39
- vdZ[i] = vv3K[i].z;
50
+ vf64X[i] = vv3K[i].x;
51
+ vf64Y[i] = vv3K[i].y;
52
+ vf64Z[i] = vv3K[i].z;
40
53
  }
41
54
 
42
55
  m_intpX.m_eSearchMode = Intp::ECached;
43
56
  m_intpY.m_eSearchMode = Intp::ECached;
44
57
  m_intpZ.m_eSearchMode = Intp::ECached;
45
58
 
46
- m_intpX.fit(vdP, vdX);
47
- m_intpY.fit(vdP, vdY);
48
- m_intpZ.fit(vdP, vdZ);
59
+ m_intpX.fit(vf64P, vf64X);
60
+ m_intpY.fit(vf64P, vf64Y);
61
+ m_intpZ.fit(vf64P, vf64Z);
49
62
 
50
- m_p0 = *vdP.begin();
51
- m_p1 = *vdP.rbegin();
63
+ m_p0 = *vf64P.begin();
64
+ m_p1 = *vf64P.rbegin();
52
65
  }
53
66
 
54
67
  bool getK(v3* k, f64 p)
@@ -60,20 +73,20 @@ public:
60
73
  return true;
61
74
  }
62
75
 
63
- bool getDkDp(v3* pv3K, f64 p) const
76
+ bool getDkDp(v3* dkdp, f64 p) const
64
77
  {
65
- pv3K->x = m_intpX.eval(p, 1);
66
- pv3K->y = m_intpY.eval(p, 1);
67
- pv3K->z = m_intpZ.eval(p, 1);
78
+ dkdp->x = m_intpX.eval(p, 1);
79
+ dkdp->y = m_intpY.eval(p, 1);
80
+ dkdp->z = m_intpZ.eval(p, 1);
68
81
 
69
82
  return true;
70
83
  }
71
84
 
72
- bool getD2kDp2(v3* pv3K, f64 p) const
85
+ bool getD2kDp2(v3* d2kdp2, f64 p) const
73
86
  {
74
- pv3K->x = m_intpX.eval(p, 2);
75
- pv3K->y = m_intpY.eval(p, 2);
76
- pv3K->z = m_intpZ.eval(p, 2);
87
+ d2kdp2->x = m_intpX.eval(p, 2);
88
+ d2kdp2->y = m_intpY.eval(p, 2);
89
+ d2kdp2->z = m_intpZ.eval(p, 2);
77
90
 
78
91
  return true;
79
92
  }
@@ -85,14 +98,14 @@ class Mag
85
98
  {
86
99
  public:
87
100
  Mag();
88
- bool setup
101
+ bool init
89
102
  (
90
103
  TrajFunc* ptTraj,
91
104
  f64 sLim, f64 gLim,
92
105
  f64 dt=10e-6, i64 oversamp=10,
93
106
  f64 dG0Norm=0e0, f64 dG1Norm=0e0
94
107
  );
95
- bool setup
108
+ bool init
96
109
  (
97
110
  const vv3& vv3TrajSamp,
98
111
  f64 sLim, f64 gLim,
@@ -129,9 +142,12 @@ private:
129
142
  vf64 m_vf64P_Bac;
130
143
  vv3 m_vv3G_Bac;
131
144
  vf64 m_vf64GNorm_Bac;
132
-
133
145
  vf64 m_vf64P_For;
134
146
  vv3 m_vv3G_For;
147
+ vf64 m_vf64P;
148
+ vv3 m_vv3G;
149
+ vv3 m_vv3TrajSamp;
150
+ LinIntp m_intp; // SplineIntp m_intp;
135
151
 
136
152
  bool sovQDE(f64* psol0, f64* psol1, f64 a, f64 b, f64 c);
137
153
  f64 getCurRad(f64 p);
@@ -304,15 +304,10 @@ public:
304
304
  }
305
305
  }
306
306
 
307
- virtual bool getGRO(vv3* pvv3G, i64 iAcq)
307
+ virtual bool getGrad(v3* pv3M0PE, vv3* pvv3G, i64 iAcq)
308
308
  {
309
- *pvv3G = m_vv3G;
310
- return true;
311
- }
312
-
313
- virtual bool getM0PE(v3* pv3M0PE, i64 iAcq)
314
- {
315
- ptfTrajFunc->getK0(pv3M0PE);
309
+ if (pv3M0PE) ptfTrajFunc->getK0(pv3M0PE);
310
+ if (pvv3G) *pvv3G = m_vv3G;
316
311
  return true;
317
312
  }
318
313
 
@@ -347,7 +342,7 @@ PyObject* calGrad4ExFunc(PyObject* self, PyObject* const* args, Py_ssize_t narg)
347
342
  );
348
343
 
349
344
  vv3 vv3G;
350
- traj.getGRO(&vv3G, 0);
345
+ traj.getGrad(NULL, &vv3G, 0);
351
346
  vf64 vf64P;
352
347
  traj.getPRO(&vf64P, 0);
353
348
 
@@ -373,7 +368,7 @@ PyObject* calGrad4ExSamp(PyObject* self, PyObject* const* args, Py_ssize_t narg)
373
368
  );
374
369
 
375
370
  vv3 vv3G;
376
- traj.getGRO(&vv3G, 0);
371
+ traj.getGrad(NULL, &vv3G, 0);
377
372
  vf64 vf64P;
378
373
  traj.getPRO(&vf64P, 0);
379
374
 
@@ -400,8 +395,9 @@ bool getG(MrTraj* pmt, vv3* pvv3M0PE, vvv3* pvvv3GRO)
400
395
  i64 _i = enShuf?vi64ShufSeq[i]:i;
401
396
 
402
397
  // get M0PE and GRO
403
- vv3 vv3GRO; ret &= pmt->getGRO(&vv3GRO, _i);
404
- v3 v3M0PE; ret &= pmt->getM0PE(&v3M0PE, _i);
398
+ vv3 vv3GRO;
399
+ v3 v3M0PE;
400
+ ret &= pmt->getGrad(&v3M0PE, &vv3GRO, _i);
405
401
 
406
402
  // reverse gradient if needed
407
403
  if (gMain_enTrajRev) ret &= Mag::revGrad(&v3M0PE, &vv3GRO, v3M0PE, vv3GRO, dt);
@@ -455,7 +451,7 @@ PyObject* getG_VDSpiral(PyObject* self, PyObject* const* args, Py_ssize_t narg)
455
451
 
456
452
  PyObject* getG_VDSpiral_RT(PyObject* self, PyObject* const* args, Py_ssize_t narg)
457
453
  {
458
- checkNarg(narg, 8);
454
+ checkNarg(narg, 7);
459
455
 
460
456
  MrTraj::GeoPara objGeoPara;
461
457
  MrTraj::GradPara objGradPara;
@@ -463,8 +459,7 @@ PyObject* getG_VDSpiral_RT(PyObject* self, PyObject* const* args, Py_ssize_t nar
463
459
 
464
460
  f64 kRhoPhi0 = (f64)PyFloat_AsDouble(args[5]);
465
461
  f64 kRhoPhi1 = (f64)PyFloat_AsDouble(args[6]);
466
- i64 nAcq = (i64)PyLong_AsLong(args[7]);
467
- VDSpiral_RT traj(objGeoPara, objGradPara, kRhoPhi0, kRhoPhi1, nAcq);
462
+ VDSpiral_RT traj(objGeoPara, objGradPara, kRhoPhi0, kRhoPhi1);
468
463
 
469
464
  vv3 vv3K0;
470
465
  vvv3 vvv3G;
@@ -557,6 +552,24 @@ PyObject* getG_Yarnball(PyObject* self, PyObject* const* args, Py_ssize_t narg)
557
552
  return Py_BuildValue("OO", cvtVv3toList(vv3K0), cvtVvv3toList(vvv3G));
558
553
  }
559
554
 
555
+ PyObject* getG_Yarnball_RT(PyObject* self, PyObject* const* args, Py_ssize_t narg)
556
+ {
557
+ checkNarg(narg, 6);
558
+
559
+ MrTraj::GeoPara objGeoPara;
560
+ MrTraj::GradPara objGradPara;
561
+ getGeoGradPara(args, &objGeoPara, &objGradPara);
562
+
563
+ f64 kRhoPhi = (f64)PyFloat_AsDouble(args[5]);
564
+ Yarnball_RT traj(objGeoPara, objGradPara, kRhoPhi);
565
+
566
+ vv3 vv3K0;
567
+ vvv3 vvv3G;
568
+ getG(&traj, &vv3K0, &vvv3G);
569
+
570
+ return Py_BuildValue("OO", cvtVv3toList(vv3K0), cvtVvv3toList(vvv3G));
571
+ }
572
+
560
573
  PyObject* getG_Seiffert(PyObject* self, PyObject* const* args, Py_ssize_t narg)
561
574
  {
562
575
  checkNarg(narg, 7);
@@ -634,7 +647,6 @@ PyObject* setMaxG0(PyObject* self, PyObject* const* args, Py_ssize_t narg)
634
647
  bool enMaxG0 = PyLong_AsLong(args[0]);
635
648
  if (enMaxG0) gMrTraj_g0Norm = 1e6;
636
649
  else gMrTraj_g0Norm = 0e0;
637
- PRINT(gMrTraj_g0Norm); // test
638
650
  Py_INCREF(Py_None);
639
651
  return Py_None;
640
652
  }
@@ -646,7 +658,6 @@ PyObject* setMaxG1(PyObject* self, PyObject* const* args, Py_ssize_t narg)
646
658
  bool enMaxG1 = PyLong_AsLong(args[0]);
647
659
  if (enMaxG1) gMrTraj_g1Norm = 1e6;
648
660
  else gMrTraj_g1Norm = 0e0;
649
- PRINT(gMrTraj_g1Norm); // test
650
661
  Py_INCREF(Py_None);
651
662
  return Py_None;
652
663
  }
@@ -714,6 +725,7 @@ static PyMethodDef aMeth[] =
714
725
  {"getG_Rosette_Trad", (PyCFunction)getG_Rosette_Trad, METH_FASTCALL, ""},
715
726
  {"getG_Shell3d", (PyCFunction)getG_Shell3d, METH_FASTCALL, ""},
716
727
  {"getG_Yarnball", (PyCFunction)getG_Yarnball, METH_FASTCALL, ""},
728
+ {"getG_Yarnball_RT", (PyCFunction)getG_Yarnball_RT, METH_FASTCALL, ""},
717
729
  {"getG_Seiffert", (PyCFunction)getG_Seiffert, METH_FASTCALL, ""},
718
730
  {"getG_Cones", (PyCFunction)getG_Cones, METH_FASTCALL, ""},
719
731
  {"setSolverMtg", (PyCFunction)setSolverMtg, METH_FASTCALL, ""},
@@ -55,7 +55,7 @@ public:
55
55
  {
56
56
  f64 tht0 = getTht0_Cones(i, m_nSet);
57
57
  m_vptfBaseTraj[i] = new Cones_TrajFun(kRhoPhi, tht0);
58
- if(!m_vptfBaseTraj[i]) throw std::runtime_error("out of memory");
58
+ ASSERT(m_vptfBaseTraj[i]!=NULL);
59
59
 
60
60
  calGrad(&m_vv3BaseM0PE[i], &m_vvv3BaseGRO[i], NULL, *m_vptfBaseTraj[i], m_objGradPara);
61
61
  m_nSampMax = std::max(m_nSampMax, (i64)m_vvv3BaseGRO[i].size());
@@ -95,7 +95,7 @@ public:
95
95
  }
96
96
  }
97
97
 
98
- virtual bool getGRO(vv3* pvv3GRO, i64 iAcq)
98
+ virtual bool getGrad(v3* pv3M0PE, vv3* pvv3GRO, i64 iAcq)
99
99
  {
100
100
  bool ret = true;
101
101
  iAcq %= m_nAcq;
@@ -103,22 +103,16 @@ public:
103
103
  i64 iRot = m_vi64RotIdx[iAcq];
104
104
  f64 phiStep = calRotAng(m_vi64NRot[iSet]);
105
105
 
106
- *pvv3GRO = m_vvv3BaseGRO[iSet];
107
- ret &= v3::rotate(pvv3GRO, 2, phiStep*iRot, *pvv3GRO);
108
-
109
- return ret;
110
- }
111
-
112
- virtual bool getM0PE(v3* pv3M0PE, i64 iAcq)
113
- {
114
- bool ret = true;
115
- iAcq %= m_nAcq;
116
- i64 iSet = m_vi64SetIdx[iAcq];
117
- i64 iRot = m_vi64RotIdx[iAcq];
118
- f64 phiStep = calRotAng(m_vi64NRot[iSet]);
119
-
120
- *pv3M0PE = m_vv3BaseM0PE[iSet];
121
- ret &= v3::rotate(pv3M0PE, 2, phiStep*iRot, *pv3M0PE);
106
+ if (pv3M0PE)
107
+ {
108
+ *pv3M0PE = m_vv3BaseM0PE[iSet];
109
+ ret &= v3::rotate(pv3M0PE, 2, phiStep * iRot, *pv3M0PE);
110
+ }
111
+ if (pvv3GRO)
112
+ {
113
+ *pvv3GRO = m_vvv3BaseGRO[iSet];
114
+ ret &= v3::rotate(pvv3GRO, 2, phiStep * iRot, *pvv3GRO);
115
+ }
122
116
 
123
117
  return ret;
124
118
  }