MRArbGrad 3.0.1__tar.gz → 3.1.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-3.1.0/MRArbGrad.egg-info}/PKG-INFO +8 -7
  2. {mrarbgrad-3.0.1/MRArbGrad.egg-info → mrarbgrad-3.1.0}/PKG-INFO +8 -7
  3. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/README.md +7 -6
  4. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/example/example_BuiltInTraj.py +2 -2
  5. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/Function.py +30 -1
  6. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/__init__.py +1 -1
  7. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/ext/mag/Mag.cpp +31 -25
  8. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/ext/mag/Mag.h +41 -25
  9. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/ext/main.cpp +28 -14
  10. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/ext/traj/Cones.h +12 -18
  11. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/ext/traj/MrTraj.h +36 -35
  12. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/ext/traj/MrTraj_2D.h +11 -17
  13. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/ext/traj/Rosette.h +2 -5
  14. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/ext/traj/Seiffert.h +4 -13
  15. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/ext/traj/Shell3d.h +12 -19
  16. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/ext/traj/Spiral.h +1 -1
  17. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/ext/traj/VDSpiral.h +23 -48
  18. mrarbgrad-3.1.0/mrarbgrad_src/ext/traj/Yarnball.h +140 -0
  19. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/ext/utility/Intp.h +19 -18
  20. mrarbgrad-3.1.0/mrarbgrad_src/ext/utility/LinIntp.h +73 -0
  21. mrarbgrad-3.1.0/mrarbgrad_src/ext/utility/SplineIntp.h +136 -0
  22. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/ext/utility/global.h +4 -3
  23. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/ext/utility/v3.cpp +4 -0
  24. {mrarbgrad-3.0.1 → mrarbgrad-3.1.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-3.1.0}/LICENSE +0 -0
  29. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/MANIFEST.in +0 -0
  30. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/MRArbGrad.egg-info/SOURCES.txt +0 -0
  31. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/MRArbGrad.egg-info/dependency_links.txt +0 -0
  32. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/MRArbGrad.egg-info/requires.txt +0 -0
  33. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/MRArbGrad.egg-info/top_level.txt +0 -0
  34. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/example/example_ExternalFunction2D.py +0 -0
  35. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/example/example_ExternalSamples2D.py +0 -0
  36. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/example/example_ExternalSamples3D.py +0 -0
  37. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/Utility.py +0 -0
  38. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/ext/traj/TrajFunc.h +0 -0
  39. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/ext/utility/global.cpp +0 -0
  40. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/ext/utility/v3.h +0 -0
  41. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/trajfunc/__init__.py +0 -0
  42. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/mrarbgrad_src/trajfunc/main.py +0 -0
  43. {mrarbgrad-3.0.1 → mrarbgrad-3.1.0}/setup.cfg +0 -0
  44. {mrarbgrad-3.0.1 → mrarbgrad-3.1.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: 3.1.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`).
@@ -42,6 +42,7 @@ You can also install via `pip install .` but remember to delete `*.egg-info` or
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
44
  ## Citation
45
- If this project helps you, please cite [our paper](https://arxiv.org/abs/2507.21625):
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: 3.1.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`).
@@ -42,6 +42,7 @@ You can also install via `pip install .` but remember to delete `*.egg-info` or
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
44
  ## Citation
45
- If this project helps you, please cite [our paper](https://arxiv.org/abs/2507.21625):
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`).
@@ -28,6 +28,7 @@ You can also install via `pip install .` but remember to delete `*.egg-info` or
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
30
  ## Citation
31
- If this project helps you, please cite [our paper](https://arxiv.org/abs/2507.21625):
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,7 @@ 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,
145
+ nAcq: int64 = 128,
146
146
  ) -> tuple[list[NDArray], list[NDArray]]:
147
147
  '''
148
148
  :return: list of trajectory start, list of gradient waveforms
@@ -285,6 +285,35 @@ def getG_Yarnball\
285
285
  float64(kRhoPhi),
286
286
  )
287
287
 
288
+ def getG_Yarnball_RT\
289
+ (
290
+ fov: float64 = 0.256,
291
+ nPix: int64 = 256,
292
+
293
+ sLim: float64 = 50 * 42.5756e6 * 0.256 / 256,
294
+ gLim: float64 = 50e-3 * 42.5756e6 * 0.256 / 256,
295
+ dt: float64 = 10e-6,
296
+
297
+ kRhoPhi: float64 = 0.5 / (2 * pi),
298
+ nAcq: int64 = 16384,
299
+ ) -> tuple[list[NDArray], list[NDArray]]:
300
+ '''
301
+ :return: list of trajectory start, list of gradient waveforms
302
+ :rtype: tuple[list[NDArray], list[NDArray]]
303
+ '''
304
+ return ext.getG_Yarnball_RT\
305
+ (
306
+ float64(fov),
307
+ int64(nPix),
308
+
309
+ float64(sLim),
310
+ float64(gLim),
311
+ float64(dt),
312
+
313
+ float64(kRhoPhi),
314
+ int64(nAcq),
315
+ )
316
+
288
317
  def getG_Seiffert\
289
318
  (
290
319
  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);
@@ -557,6 +553,25 @@ PyObject* getG_Yarnball(PyObject* self, PyObject* const* args, Py_ssize_t narg)
557
553
  return Py_BuildValue("OO", cvtVv3toList(vv3K0), cvtVvv3toList(vvv3G));
558
554
  }
559
555
 
556
+ PyObject* getG_Yarnball_RT(PyObject* self, PyObject* const* args, Py_ssize_t narg)
557
+ {
558
+ checkNarg(narg, 7);
559
+
560
+ MrTraj::GeoPara objGeoPara;
561
+ MrTraj::GradPara objGradPara;
562
+ getGeoGradPara(args, &objGeoPara, &objGradPara);
563
+
564
+ f64 kRhoPhi = (f64)PyFloat_AsDouble(args[5]);
565
+ i64 nAcq = (i64)PyLong_AsLong(args[6]);
566
+ Yarnball_RT traj(objGeoPara, objGradPara, kRhoPhi, nAcq);
567
+
568
+ vv3 vv3K0;
569
+ vvv3 vvv3G;
570
+ getG(&traj, &vv3K0, &vvv3G);
571
+
572
+ return Py_BuildValue("OO", cvtVv3toList(vv3K0), cvtVvv3toList(vvv3G));
573
+ }
574
+
560
575
  PyObject* getG_Seiffert(PyObject* self, PyObject* const* args, Py_ssize_t narg)
561
576
  {
562
577
  checkNarg(narg, 7);
@@ -634,7 +649,6 @@ PyObject* setMaxG0(PyObject* self, PyObject* const* args, Py_ssize_t narg)
634
649
  bool enMaxG0 = PyLong_AsLong(args[0]);
635
650
  if (enMaxG0) gMrTraj_g0Norm = 1e6;
636
651
  else gMrTraj_g0Norm = 0e0;
637
- PRINT(gMrTraj_g0Norm); // test
638
652
  Py_INCREF(Py_None);
639
653
  return Py_None;
640
654
  }
@@ -646,7 +660,6 @@ PyObject* setMaxG1(PyObject* self, PyObject* const* args, Py_ssize_t narg)
646
660
  bool enMaxG1 = PyLong_AsLong(args[0]);
647
661
  if (enMaxG1) gMrTraj_g1Norm = 1e6;
648
662
  else gMrTraj_g1Norm = 0e0;
649
- PRINT(gMrTraj_g1Norm); // test
650
663
  Py_INCREF(Py_None);
651
664
  return Py_None;
652
665
  }
@@ -714,6 +727,7 @@ static PyMethodDef aMeth[] =
714
727
  {"getG_Rosette_Trad", (PyCFunction)getG_Rosette_Trad, METH_FASTCALL, ""},
715
728
  {"getG_Shell3d", (PyCFunction)getG_Shell3d, METH_FASTCALL, ""},
716
729
  {"getG_Yarnball", (PyCFunction)getG_Yarnball, METH_FASTCALL, ""},
730
+ {"getG_Yarnball_RT", (PyCFunction)getG_Yarnball_RT, METH_FASTCALL, ""},
717
731
  {"getG_Seiffert", (PyCFunction)getG_Seiffert, METH_FASTCALL, ""},
718
732
  {"getG_Cones", (PyCFunction)getG_Cones, METH_FASTCALL, ""},
719
733
  {"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
  }