MRArbGrad 4.1.0__tar.gz → 4.2.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 (41) hide show
  1. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0/MRArbGrad.egg-info}/PKG-INFO +1 -1
  2. {mrarbgrad-4.1.0/MRArbGrad.egg-info → mrarbgrad-4.2.0}/PKG-INFO +1 -1
  3. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/Function.py +34 -4
  4. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/__init__.py +1 -1
  5. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/mag/Mag.cpp +20 -18
  6. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/mag/Mag.h +7 -7
  7. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/main.cpp +134 -59
  8. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/traj/MrTraj.h +7 -3
  9. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/utility/LinIntp.h +0 -2
  10. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/utility/SplineIntp.h +0 -2
  11. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/utility/v3.cpp +27 -19
  12. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/pyproject.toml +1 -1
  13. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/setup.py +0 -2
  14. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/LICENSE +0 -0
  15. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/MANIFEST.in +0 -0
  16. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/MRArbGrad.egg-info/SOURCES.txt +0 -0
  17. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/MRArbGrad.egg-info/dependency_links.txt +0 -0
  18. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/MRArbGrad.egg-info/requires.txt +0 -0
  19. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/MRArbGrad.egg-info/top_level.txt +0 -0
  20. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/README.md +0 -0
  21. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/example/example_BuiltInTraj.py +0 -0
  22. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/example/example_ExternalFunction2D.py +0 -0
  23. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/example/example_ExternalSamples2D.py +0 -0
  24. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/example/example_ExternalSamples3D.py +0 -0
  25. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/Utility.py +0 -0
  26. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/traj/Cones.h +0 -0
  27. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/traj/MrTraj_2D.h +0 -0
  28. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/traj/Rosette.h +0 -0
  29. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/traj/Seiffert.h +0 -0
  30. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/traj/Shell3d.h +0 -0
  31. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/traj/Spiral.h +0 -0
  32. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/traj/TrajFunc.h +0 -0
  33. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/traj/VDSpiral.h +0 -0
  34. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/traj/Yarnball.h +0 -0
  35. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/utility/Intp.h +0 -0
  36. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/utility/global.cpp +0 -0
  37. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/utility/global.h +0 -0
  38. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/ext/utility/v3.h +0 -0
  39. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/trajfunc/__init__.py +0 -0
  40. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/mrarbgrad_src/trajfunc/main.py +0 -0
  41. {mrarbgrad-4.1.0 → mrarbgrad-4.2.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MRArbGrad
3
- Version: 4.1.0
3
+ Version: 4.2.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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MRArbGrad
3
- Version: 4.1.0
3
+ Version: 4.2.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
@@ -371,15 +371,31 @@ def setGoldAng(x): ext.setGoldAng(x)
371
371
  def setShuf(x): ext.setShuf(x)
372
372
  def setMaxG0(x): ext.setMaxG0(x)
373
373
  def setMaxG1(x): ext.setMaxG1(x)
374
+ def setMagGradSamp(x): ext.setMagGradSamp(x)
375
+ def setMagTrajSamp(x): ext.setMagTrajSamp(x)
374
376
  def setMagOverSamp(x): ext.setMagOverSamp(x)
375
377
  def setMagSFS(x): ext.setMagSFS(x)
376
378
  def setMagGradRep(x): ext.setMagGradRep(x)
377
379
  def setMagTrajRep(x): ext.setMagTrajRep(x)
378
380
  def setDbgPrint(x): ext.setDbgPrint(x)
379
381
 
380
- def loadF64(hdr:str, bin:str) -> list[NDArray]:
382
+ def saveF64(hdr:str, bin:str, arr:NDArray) -> bool:
381
383
  """
382
- load saved vector file (float64)
384
+ save vector file (float64)
385
+
386
+ Args:
387
+ hdr (str): header (hdr) file path
388
+ bin (str): bin file path
389
+ arr (NDarray): array to be saved
390
+
391
+ Returns:
392
+ bool: True for success
393
+ """
394
+ return ext.saveF64(str(hdr), str(bin), arr)
395
+
396
+ def loadF64(hdr:str, bin:str) -> list[NDArray]|None:
397
+ """
398
+ load vector file (float64)
383
399
 
384
400
  Args:
385
401
  hdr (str): header (hdr) file path
@@ -390,9 +406,23 @@ def loadF64(hdr:str, bin:str) -> list[NDArray]:
390
406
  """
391
407
  return ext.loadF64(str(hdr), str(bin))
392
408
 
393
- def loadF32(hdr:str, bin:str) -> list[NDArray]:
409
+ def saveF32(hdr:str, bin:str, arr:NDArray) -> bool:
410
+ """
411
+ save vector file (float32)
412
+
413
+ Args:
414
+ hdr (str): header (hdr) file path
415
+ bin (str): bin file path
416
+ arr (NDarray): array to be saved
417
+
418
+ Returns:
419
+ bool: True for success
420
+ """
421
+ return ext.saveF32(str(hdr), str(bin), arr)
422
+
423
+ def loadF32(hdr:str, bin:str) -> list[NDArray]|None:
394
424
  """
395
- load saved vector file (float32)
425
+ load vector file (float32)
396
426
 
397
427
  Args:
398
428
  hdr (str): header (hdr) file path
@@ -1,6 +1,6 @@
1
1
  from .Function import calGrad4ExFunc, calGrad4ExSamp
2
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
- from .Function import setSolverMtg, setTrajRev, setGoldAng, setShuf, setMaxG0, setMaxG1, setMagOverSamp, setMagSFS, setMagGradRep, setMagTrajRep, setDbgPrint, loadF64, loadF32
3
+ from .Function import setSolverMtg, setTrajRev, setGoldAng, setShuf, setMaxG0, setMaxG1, setMagGradSamp, setMagTrajSamp, setMagOverSamp, setMagSFS, setMagGradRep, setMagTrajRep, setDbgPrint, saveF64, loadF64, saveF32, loadF32
4
4
  from .Utility import _calDiaphony, rotate, _calJacElip, _calCompElipInt, _calSphFibPt, cvtGrad2Traj, getGoldang, getGoldrat, rand3d, gradClip
5
5
 
6
6
  from . import trajfunc
@@ -8,29 +8,31 @@ i64 gMag_oversamp = -1; // oversample ratio, overwrite the set value
8
8
  bool gMag_enSFS = false; // Single Forward Sweep flag
9
9
  bool gMag_enGradRep = true; // Gradient Reparameterization
10
10
  bool gMag_enTrajRep = true; // use trajectory reparameterization for MAG solver
11
- i64 gMag_nTrajSamp = 1000; // num. of samp. when doing Traj. Rep.
12
11
 
13
- Mag::Mag()
12
+ Mag::Mag(i64 nGradSampRsv, i64 nTrajSampRsv)
14
13
  {
15
14
  // for solver
16
- m_dt = 10e-6; m_oversamp = 8;
17
- i64 nSampReserve = i64(100e-3/m_dt); // reserve for 100ms
15
+ if (nGradSampRsv)
16
+ {
17
+ m_vf64P_Bac.reserve(nGradSampRsv * 8);
18
+ m_vv3G_Bac.reserve(nGradSampRsv * 8);
19
+ m_vf64GNorm_Bac.reserve(nGradSampRsv * 8);
18
20
 
19
- m_vf64P_Bac.reserve(nSampReserve*m_oversamp);
20
- m_vv3G_Bac.reserve(nSampReserve*m_oversamp);
21
- m_vf64GNorm_Bac.reserve(nSampReserve*m_oversamp);
21
+ m_vf64P_For.reserve(nGradSampRsv * 8);
22
+ m_vv3G_For.reserve(nGradSampRsv * 8);
22
23
 
23
- m_vf64P_For.reserve(nSampReserve*m_oversamp);
24
- m_vv3G_For.reserve(nSampReserve*m_oversamp);
24
+ m_vf64P.reserve(nGradSampRsv);
25
+ m_vv3G.reserve(nGradSampRsv);
25
26
 
26
- m_vf64P.reserve(nSampReserve);
27
- m_vv3G.reserve(nSampReserve);
28
-
29
- // for trajectory reparameterization
30
- m_vv3TrajSamp.resize(gMag_nTrajSamp);
27
+ m_intp.init(nGradSampRsv * 8);
28
+ m_intp.m_eSearchMode = Intp::ECached;
29
+ }
31
30
 
32
- m_intp.init(nSampReserve*m_oversamp);
33
- m_intp.m_eSearchMode = Intp::ECached;
31
+ // for trajectory reparameterization
32
+ if (gMrTraj_nTrajSampRsv)
33
+ {
34
+ m_vv3TrajSamp.resize(gMrTraj_nTrajSampRsv);
35
+ }
34
36
  }
35
37
 
36
38
  bool Mag::init
@@ -52,9 +54,9 @@ bool Mag::init
52
54
  {
53
55
  f64 p0 = ptTraj->getP0();
54
56
  f64 p1 = ptTraj->getP1();
55
- for (i64 i = 0; i < gMag_nTrajSamp; ++i)
57
+ for (i64 i = 0; i < gMrTraj_nTrajSampRsv; ++i)
56
58
  {
57
- f64 p = p0 + (p1-p0) * (i)/f64(gMag_nTrajSamp-1);
59
+ f64 p = p0 + (p1-p0) * (i)/f64(gMrTraj_nTrajSampRsv-1);
58
60
  ptTraj->getK(&m_vv3TrajSamp[i], p);
59
61
  }
60
62
  m_sptfTraj = Spline_TrajFunc(m_vv3TrajSamp);
@@ -16,7 +16,7 @@ extern i64 gMag_oversamp;
16
16
  extern bool gMag_enSFS;
17
17
  extern bool gMag_enGradRep;
18
18
  extern bool gMag_enTrajRep;
19
- extern i64 gMag_nTrajSamp;
19
+ extern i64 gMrTraj_nTrajSampRsv;
20
20
 
21
21
  // virtual TrajFunc, take in discrete samples and construct a Segmentied Cubic Polynomial function
22
22
  class Spline_TrajFunc: public TrajFunc
@@ -24,9 +24,9 @@ class Spline_TrajFunc: public TrajFunc
24
24
  public:
25
25
  Spline_TrajFunc():
26
26
  TrajFunc(0,0),
27
- m_intpX(gMag_nTrajSamp),
28
- m_intpY(gMag_nTrajSamp),
29
- m_intpZ(gMag_nTrajSamp)
27
+ m_intpX(gMrTraj_nTrajSampRsv),
28
+ m_intpY(gMrTraj_nTrajSampRsv),
29
+ m_intpZ(gMrTraj_nTrajSampRsv)
30
30
  {}
31
31
 
32
32
  Spline_TrajFunc(const vv3& vv3K):
@@ -97,19 +97,19 @@ protected:
97
97
  class Mag
98
98
  {
99
99
  public:
100
- Mag();
100
+ Mag(i64 nSampReserve=0, i64 nTrajSampRsv=0);
101
101
  bool init
102
102
  (
103
103
  TrajFunc* ptTraj,
104
104
  f64 sLim, f64 gLim,
105
- f64 dt=10e-6, i64 oversamp=10,
105
+ f64 dt=10e-6, i64 oversamp=8,
106
106
  f64 dG0Norm=0e0, f64 dG1Norm=0e0
107
107
  );
108
108
  bool init
109
109
  (
110
110
  const vv3& vv3TrajSamp,
111
111
  f64 sLim, f64 gLim,
112
- f64 dt=10e-6, i64 oversamp=10,
112
+ f64 dt=10e-6, i64 oversamp=8,
113
113
  f64 dG0Norm=0e0, f64 dG1Norm=0e0
114
114
  );
115
115
  ~Mag();
@@ -17,6 +17,8 @@
17
17
  #include "traj/Cones.h"
18
18
  #include "utility/SplineIntp.h"
19
19
 
20
+ typedef std::list<vv3> lvv3;
21
+
20
22
  bool gMain_enTrajRev (0);
21
23
  bool gMain_enGoldAng (0);
22
24
  bool gMain_enShuffle (0);
@@ -133,14 +135,9 @@ bool cvtNpa2Vf64(PyObject* pNumpyArray, vf64* pvf64Out)
133
135
  return true;
134
136
  }
135
137
 
136
- bool inline checkNarg(i64 nArg, i64 nArgExp)
138
+ bool inline chkNarg(i64 nArg, i64 nArgExp)
137
139
  {
138
- if (nArg != nArgExp)
139
- {
140
- printf("wrong num. of arg, narg=%ld, %ld expected\n", (long)nArg, (long)nArgExp);
141
- abort();
142
- return false;
143
- }
140
+ ASSERT (nArg == nArgExp);
144
141
  return true;
145
142
  }
146
143
 
@@ -187,18 +184,13 @@ public:
187
184
  PyObject* _pPyObj_v3 = pPyObj_v3;
188
185
  pPyObj_v3 = PyArray_FROM_OTF(pPyObj_v3, NPY_FLOAT64, NPY_ARRAY_CARRAY);
189
186
  Py_DECREF(_pPyObj_v3);
190
- if (PyArray_SIZE((PyArrayObject*)pPyObj_v3) != 3)
191
- {
192
- PyErr_SetString(PyExc_RuntimeError, "the return value of getK / getDkDp / getD2kDp2 must be size-3.\n");
193
- PyErr_PrintEx(-1);
194
- std::abort();
195
- return false;
196
- }
187
+ ASSERT (PyArray_SIZE((PyArrayObject*)pPyObj_v3) == 3);
197
188
 
198
189
  k->x = *(f64*)PyArray_GETPTR1((PyArrayObject*)pPyObj_v3, 0);
199
190
  k->y = *(f64*)PyArray_GETPTR1((PyArrayObject*)pPyObj_v3, 1);
200
191
  k->z = *(f64*)PyArray_GETPTR1((PyArrayObject*)pPyObj_v3, 2);
201
-
192
+
193
+ Py_DECREF(pPyObj_v3);
202
194
  return true;
203
195
  }
204
196
 
@@ -215,18 +207,13 @@ public:
215
207
  PyObject* _pPyObj_v3 = pPyObj_v3;
216
208
  pPyObj_v3 = PyArray_FROM_OTF(pPyObj_v3, NPY_FLOAT64, NPY_ARRAY_CARRAY);
217
209
  Py_DECREF(_pPyObj_v3);
218
- if (PyArray_SIZE((PyArrayObject*)pPyObj_v3) != 3)
219
- {
220
- PyErr_SetString(PyExc_RuntimeError, "the return value of getK / getDkDp / getD2kDp2 must be size-3.\n");
221
- PyErr_PrintEx(-1);
222
- std::abort();
223
- return false;
224
- }
210
+ ASSERT (PyArray_SIZE((PyArrayObject*)pPyObj_v3) == 3);
225
211
 
226
212
  k->x = *(f64*)PyArray_GETPTR1((PyArrayObject*)pPyObj_v3, 0);
227
213
  k->y = *(f64*)PyArray_GETPTR1((PyArrayObject*)pPyObj_v3, 1);
228
214
  k->z = *(f64*)PyArray_GETPTR1((PyArrayObject*)pPyObj_v3, 2);
229
215
 
216
+ Py_DECREF(pPyObj_v3);
230
217
  return true;
231
218
  }
232
219
 
@@ -243,18 +230,13 @@ public:
243
230
  PyObject* _pPyObj_v3 = pPyObj_v3;
244
231
  pPyObj_v3 = PyArray_FROM_OTF(pPyObj_v3, NPY_FLOAT64, NPY_ARRAY_CARRAY);
245
232
  Py_DECREF(_pPyObj_v3);
246
- if (PyArray_SIZE((PyArrayObject*)pPyObj_v3) != 3)
247
- {
248
- PyErr_SetString(PyExc_RuntimeError, "the return value of getK / getDkDp / getD2kDp2 must be size-3.\n");
249
- PyErr_PrintEx(-1);
250
- std::abort();
251
- return false;
252
- }
233
+ ASSERT (PyArray_SIZE((PyArrayObject*)pPyObj_v3) != 3);
253
234
 
254
235
  k->x = *(f64*)PyArray_GETPTR1((PyArrayObject*)pPyObj_v3, 0);
255
236
  k->y = *(f64*)PyArray_GETPTR1((PyArrayObject*)pPyObj_v3, 1);
256
237
  k->z = *(f64*)PyArray_GETPTR1((PyArrayObject*)pPyObj_v3, 2);
257
238
 
239
+ Py_DECREF(pPyObj_v3);
258
240
  return true;
259
241
  }
260
242
  protected:
@@ -325,7 +307,7 @@ private:
325
307
 
326
308
  PyObject* calGrad4ExFunc(PyObject* self, PyObject* const* args, Py_ssize_t narg)
327
309
  {
328
- checkNarg(narg, 10);
310
+ chkNarg(narg, 10);
329
311
 
330
312
  MrTraj::GeoPara objGeoPara;
331
313
  MrTraj::GradPara objGradPara;
@@ -353,7 +335,7 @@ PyObject* calGrad4ExSamp(PyObject* self, PyObject* const* args, Py_ssize_t narg)
353
335
  {
354
336
  try
355
337
  {
356
- checkNarg(narg, 6);
338
+ chkNarg(narg, 6);
357
339
 
358
340
  MrTraj::GeoPara objGeoPara;
359
341
  MrTraj::GradPara objGradPara;
@@ -410,7 +392,7 @@ bool getG(MrTraj* pmt, vv3* pvv3M0PE, vvv3* pvvv3GRO)
410
392
 
411
393
  PyObject* getG_Spiral(PyObject* self, PyObject* const* args, Py_ssize_t narg)
412
394
  {
413
- checkNarg(narg, 7);
395
+ chkNarg(narg, 7);
414
396
 
415
397
  MrTraj::GeoPara objGeoPara;
416
398
  MrTraj::GradPara objGradPara;
@@ -430,7 +412,7 @@ PyObject* getG_Spiral(PyObject* self, PyObject* const* args, Py_ssize_t narg)
430
412
 
431
413
  PyObject* getG_VDSpiral(PyObject* self, PyObject* const* args, Py_ssize_t narg)
432
414
  {
433
- checkNarg(narg, 8);
415
+ chkNarg(narg, 8);
434
416
 
435
417
  MrTraj::GeoPara objGeoPara;
436
418
  MrTraj::GradPara objGradPara;
@@ -451,7 +433,7 @@ PyObject* getG_VDSpiral(PyObject* self, PyObject* const* args, Py_ssize_t narg)
451
433
 
452
434
  PyObject* getG_VDSpiral_RT(PyObject* self, PyObject* const* args, Py_ssize_t narg)
453
435
  {
454
- checkNarg(narg, 7);
436
+ chkNarg(narg, 7);
455
437
 
456
438
  MrTraj::GeoPara objGeoPara;
457
439
  MrTraj::GradPara objGradPara;
@@ -470,7 +452,7 @@ PyObject* getG_VDSpiral_RT(PyObject* self, PyObject* const* args, Py_ssize_t nar
470
452
 
471
453
  PyObject* getG_Rosette(PyObject* self, PyObject* const* args, Py_ssize_t narg)
472
454
  {
473
- checkNarg(narg, 9);
455
+ chkNarg(narg, 9);
474
456
 
475
457
  MrTraj::GeoPara objGeoPara;
476
458
  MrTraj::GradPara objGradPara;
@@ -494,7 +476,7 @@ PyObject* getG_Rosette(PyObject* self, PyObject* const* args, Py_ssize_t narg)
494
476
 
495
477
  PyObject* getG_Rosette_Trad(PyObject* self, PyObject* const* args, Py_ssize_t narg)
496
478
  {
497
- checkNarg(narg, 10);
479
+ chkNarg(narg, 10);
498
480
 
499
481
  MrTraj::GeoPara objGeoPara;
500
482
  MrTraj::GradPara objGradPara;
@@ -518,7 +500,7 @@ PyObject* getG_Rosette_Trad(PyObject* self, PyObject* const* args, Py_ssize_t na
518
500
 
519
501
  PyObject* getG_Shell3d(PyObject* self, PyObject* const* args, Py_ssize_t narg)
520
502
  {
521
- checkNarg(narg, 6);
503
+ chkNarg(narg, 6);
522
504
 
523
505
  MrTraj::GeoPara objGeoPara;
524
506
  MrTraj::GradPara objGradPara;
@@ -536,7 +518,7 @@ PyObject* getG_Shell3d(PyObject* self, PyObject* const* args, Py_ssize_t narg)
536
518
 
537
519
  PyObject* getG_Yarnball(PyObject* self, PyObject* const* args, Py_ssize_t narg)
538
520
  {
539
- checkNarg(narg, 6);
521
+ chkNarg(narg, 6);
540
522
 
541
523
  MrTraj::GeoPara objGeoPara;
542
524
  MrTraj::GradPara objGradPara;
@@ -554,7 +536,7 @@ PyObject* getG_Yarnball(PyObject* self, PyObject* const* args, Py_ssize_t narg)
554
536
 
555
537
  PyObject* getG_Yarnball_RT(PyObject* self, PyObject* const* args, Py_ssize_t narg)
556
538
  {
557
- checkNarg(narg, 6);
539
+ chkNarg(narg, 6);
558
540
 
559
541
  MrTraj::GeoPara objGeoPara;
560
542
  MrTraj::GradPara objGradPara;
@@ -572,7 +554,7 @@ PyObject* getG_Yarnball_RT(PyObject* self, PyObject* const* args, Py_ssize_t nar
572
554
 
573
555
  PyObject* getG_Seiffert(PyObject* self, PyObject* const* args, Py_ssize_t narg)
574
556
  {
575
- checkNarg(narg, 7);
557
+ chkNarg(narg, 7);
576
558
 
577
559
  MrTraj::GeoPara objGeoPara;
578
560
  MrTraj::GradPara objGradPara;
@@ -591,7 +573,7 @@ PyObject* getG_Seiffert(PyObject* self, PyObject* const* args, Py_ssize_t narg)
591
573
 
592
574
  PyObject* getG_Cones(PyObject* self, PyObject* const* args, Py_ssize_t narg)
593
575
  {
594
- checkNarg(narg, 6);
576
+ chkNarg(narg, 6);
595
577
 
596
578
  MrTraj::GeoPara objGeoPara;
597
579
  MrTraj::GradPara objGradPara;
@@ -610,7 +592,7 @@ PyObject* getG_Cones(PyObject* self, PyObject* const* args, Py_ssize_t narg)
610
592
  PyObject* setSolverMtg(PyObject* self, PyObject* const* args, Py_ssize_t narg)
611
593
  {
612
594
  extern bool gMrTraj_enMtg;
613
- checkNarg(narg, 1);
595
+ chkNarg(narg, 1);
614
596
  gMrTraj_enMtg = PyLong_AsLong(args[0]);
615
597
  Py_INCREF(Py_None);
616
598
  return Py_None;
@@ -618,7 +600,7 @@ PyObject* setSolverMtg(PyObject* self, PyObject* const* args, Py_ssize_t narg)
618
600
 
619
601
  PyObject* setTrajRev(PyObject* self, PyObject* const* args, Py_ssize_t narg)
620
602
  {
621
- checkNarg(narg, 1);
603
+ chkNarg(narg, 1);
622
604
  gMain_enTrajRev = PyLong_AsLong(args[0]);
623
605
  Py_INCREF(Py_None);
624
606
  return Py_None;
@@ -626,7 +608,7 @@ PyObject* setTrajRev(PyObject* self, PyObject* const* args, Py_ssize_t narg)
626
608
 
627
609
  PyObject* setGoldAng(PyObject* self, PyObject* const* args, Py_ssize_t narg)
628
610
  {
629
- checkNarg(narg, 1);
611
+ chkNarg(narg, 1);
630
612
  gMain_enGoldAng = PyLong_AsLong(args[0]);
631
613
  Py_INCREF(Py_None);
632
614
  return Py_None;
@@ -634,7 +616,7 @@ PyObject* setGoldAng(PyObject* self, PyObject* const* args, Py_ssize_t narg)
634
616
 
635
617
  PyObject* setShuf(PyObject* self, PyObject* const* args, Py_ssize_t narg)
636
618
  {
637
- checkNarg(narg, 1);
619
+ chkNarg(narg, 1);
638
620
  gMain_enShuffle = PyLong_AsLong(args[0]);
639
621
  Py_INCREF(Py_None);
640
622
  return Py_None;
@@ -643,7 +625,7 @@ PyObject* setShuf(PyObject* self, PyObject* const* args, Py_ssize_t narg)
643
625
  PyObject* setMaxG0(PyObject* self, PyObject* const* args, Py_ssize_t narg)
644
626
  {
645
627
  extern f64 gMrTraj_g0Norm;
646
- checkNarg(narg, 1);
628
+ chkNarg(narg, 1);
647
629
  bool enMaxG0 = PyLong_AsLong(args[0]);
648
630
  if (enMaxG0) gMrTraj_g0Norm = 1e6;
649
631
  else gMrTraj_g0Norm = 0e0;
@@ -654,7 +636,7 @@ PyObject* setMaxG0(PyObject* self, PyObject* const* args, Py_ssize_t narg)
654
636
  PyObject* setMaxG1(PyObject* self, PyObject* const* args, Py_ssize_t narg)
655
637
  {
656
638
  extern f64 gMrTraj_g1Norm;
657
- checkNarg(narg, 1);
639
+ chkNarg(narg, 1);
658
640
  bool enMaxG1 = PyLong_AsLong(args[0]);
659
641
  if (enMaxG1) gMrTraj_g1Norm = 1e6;
660
642
  else gMrTraj_g1Norm = 0e0;
@@ -662,10 +644,28 @@ PyObject* setMaxG1(PyObject* self, PyObject* const* args, Py_ssize_t narg)
662
644
  return Py_None;
663
645
  }
664
646
 
647
+ PyObject* setMagGradSamp(PyObject* self, PyObject* const* args, Py_ssize_t narg)
648
+ {
649
+ extern i64 gMrTraj_nGradSampRsv;
650
+ chkNarg(narg, 1);
651
+ gMrTraj_nGradSampRsv = PyLong_AsLong(args[0]);
652
+ Py_INCREF(Py_None);
653
+ return Py_None;
654
+ }
655
+
656
+ PyObject* setMagTrajSamp(PyObject* self, PyObject* const* args, Py_ssize_t narg)
657
+ {
658
+ extern i64 gMrTraj_nTrajSampRsv;
659
+ chkNarg(narg, 1);
660
+ gMrTraj_nTrajSampRsv = PyLong_AsLong(args[0]);
661
+ Py_INCREF(Py_None);
662
+ return Py_None;
663
+ }
664
+
665
665
  PyObject* setMagOverSamp(PyObject* self, PyObject* const* args, Py_ssize_t narg)
666
666
  {
667
667
  extern i64 gMag_oversamp;
668
- checkNarg(narg, 1);
668
+ chkNarg(narg, 1);
669
669
  gMag_oversamp = PyLong_AsLong(args[0]);
670
670
  Py_INCREF(Py_None);
671
671
  return Py_None;
@@ -674,7 +674,7 @@ PyObject* setMagOverSamp(PyObject* self, PyObject* const* args, Py_ssize_t narg)
674
674
  PyObject* setMagSFS(PyObject* self, PyObject* const* args, Py_ssize_t narg)
675
675
  {
676
676
  extern bool gMag_enSFS;
677
- checkNarg(narg, 1);
677
+ chkNarg(narg, 1);
678
678
  gMag_enSFS = PyLong_AsLong(args[0]);
679
679
  Py_INCREF(Py_None);
680
680
  return Py_None;
@@ -683,7 +683,7 @@ PyObject* setMagSFS(PyObject* self, PyObject* const* args, Py_ssize_t narg)
683
683
  PyObject* setMagGradRep(PyObject* self, PyObject* const* args, Py_ssize_t narg)
684
684
  {
685
685
  extern bool gMag_enGradRep;
686
- checkNarg(narg, 1);
686
+ chkNarg(narg, 1);
687
687
  gMag_enGradRep = PyLong_AsLong(args[0]);
688
688
  Py_INCREF(Py_None);
689
689
  return Py_None;
@@ -692,7 +692,7 @@ PyObject* setMagGradRep(PyObject* self, PyObject* const* args, Py_ssize_t narg)
692
692
  PyObject* setMagTrajRep(PyObject* self, PyObject* const* args, Py_ssize_t narg)
693
693
  {
694
694
  extern bool gMag_enTrajRep;
695
- checkNarg(narg, 1);
695
+ chkNarg(narg, 1);
696
696
  gMag_enTrajRep = PyLong_AsLong(args[0]);
697
697
  Py_INCREF(Py_None);
698
698
  return Py_None;
@@ -701,20 +701,53 @@ PyObject* setMagTrajRep(PyObject* self, PyObject* const* args, Py_ssize_t narg)
701
701
  PyObject* setDbgPrint(PyObject* self, PyObject* const* args, Py_ssize_t narg)
702
702
  {
703
703
  extern bool glob_enDbgPrint;
704
- checkNarg(narg, 1);
704
+ chkNarg(narg, 1);
705
705
  glob_enDbgPrint = PyLong_AsLong(args[0]);
706
706
  Py_INCREF(Py_None);
707
707
  return Py_None;
708
708
  }
709
709
 
710
+ PyObject* saveF64(PyObject* self, PyObject* const* args, Py_ssize_t narg)
711
+ {
712
+ chkNarg(narg, 3);
713
+ const char* strHdr = PyUnicode_AsUTF8(args[0]);
714
+ const char* strBin = PyUnicode_AsUTF8(args[1]);
715
+ FILE* fHdr = fopen(strHdr, "w");
716
+ FILE* fBin = fopen(strBin, "wb");
717
+ if (fHdr==NULL || fBin==NULL)
718
+ {
719
+ if (fHdr) fclose(fHdr);
720
+ if (fBin) fclose(fBin);
721
+ Py_INCREF(Py_False);
722
+ return Py_False;
723
+ }
724
+
725
+ vv3 vv3Data;
726
+ i64 n = PyList_GET_SIZE(args[2]);
727
+ for (i64 i=0; i<n; ++i)
728
+ {
729
+ cvtNpa2Vv3(PyList_GET_ITEM(args[2], i), &vv3Data);
730
+ v3::saveF64(fHdr, fBin, vv3Data);
731
+ }
732
+
733
+ Py_INCREF(Py_True);
734
+ return Py_True;
735
+ }
736
+
710
737
  PyObject* loadF64(PyObject* self, PyObject* const* args, Py_ssize_t narg)
711
738
  {
712
- checkNarg(narg, 2);
739
+ chkNarg(narg, 2);
713
740
  const char* strHdr = PyUnicode_AsUTF8(args[0]);
714
741
  const char* strBin = PyUnicode_AsUTF8(args[1]);
715
- typedef std::list<vv3> lvv3;
716
742
  FILE* fHdr = fopen(strHdr, "r");
717
- FILE* fBin = fopen(strHdr, "rb");
743
+ FILE* fBin = fopen(strBin, "rb");
744
+ if (fHdr==NULL || fBin==NULL)
745
+ {
746
+ if (fHdr) fclose(fHdr);
747
+ if (fBin) fclose(fBin);
748
+ Py_INCREF(Py_None);
749
+ return Py_None;
750
+ }
718
751
 
719
752
  lvv3 lvv3Data;
720
753
  bool ret; vv3 vv3Data;
@@ -724,18 +757,54 @@ PyObject* loadF64(PyObject* self, PyObject* const* args, Py_ssize_t narg)
724
757
  if (vv3Data.empty() || !ret) break;
725
758
  lvv3Data.push_back(vv3Data);
726
759
  }
760
+ if (fHdr) fclose(fHdr);
761
+ if (fBin) fclose(fBin);
727
762
  vvv3 vvv3Data(lvv3Data.begin(), lvv3Data.end());
728
- Py_BuildValue("%O", cvtVvv3toList(vvv3Data));
763
+ return cvtVvv3toList(vvv3Data);
764
+ }
765
+
766
+ PyObject* saveF32(PyObject* self, PyObject* const* args, Py_ssize_t narg)
767
+ {
768
+ chkNarg(narg, 3);
769
+ const char* strHdr = PyUnicode_AsUTF8(args[0]);
770
+ const char* strBin = PyUnicode_AsUTF8(args[1]);
771
+ FILE* fHdr = fopen(strHdr, "w");
772
+ FILE* fBin = fopen(strBin, "wb");
773
+ if (fHdr==NULL || fBin==NULL)
774
+ {
775
+ if (fHdr) fclose(fHdr);
776
+ if (fBin) fclose(fBin);
777
+ Py_INCREF(Py_False);
778
+ return Py_False;
779
+ }
780
+
781
+ vv3 vv3Data;
782
+ i64 n = PyList_GET_SIZE(args[2]);
783
+ for (i64 i=0; i<n; ++i)
784
+ {
785
+ cvtNpa2Vv3(PyList_GET_ITEM(args[2], i), &vv3Data);
786
+ v3::saveF32(fHdr, fBin, vv3Data);
787
+ }
788
+
789
+ Py_INCREF(Py_True);
790
+ return Py_True;
729
791
  }
730
792
 
731
793
  PyObject* loadF32(PyObject* self, PyObject* const* args, Py_ssize_t narg)
732
794
  {
733
- checkNarg(narg, 2);
795
+ chkNarg(narg, 2);
734
796
  const char* strHdr = PyUnicode_AsUTF8(args[0]);
735
797
  const char* strBin = PyUnicode_AsUTF8(args[1]);
736
798
  typedef std::list<vv3> lvv3;
737
799
  FILE* fHdr = fopen(strHdr, "r");
738
- FILE* fBin = fopen(strHdr, "rb");
800
+ FILE* fBin = fopen(strBin, "rb");
801
+ if (fHdr==NULL || fBin==NULL)
802
+ {
803
+ if (fHdr) fclose(fHdr);
804
+ if (fBin) fclose(fBin);
805
+ Py_INCREF(Py_None);
806
+ return Py_None;
807
+ }
739
808
 
740
809
  lvv3 lvv3Data;
741
810
  bool ret; vv3 vv3Data;
@@ -745,8 +814,10 @@ PyObject* loadF32(PyObject* self, PyObject* const* args, Py_ssize_t narg)
745
814
  if (vv3Data.empty() || !ret) break;
746
815
  lvv3Data.push_back(vv3Data);
747
816
  }
817
+ if (fHdr) fclose(fHdr);
818
+ if (fBin) fclose(fBin);
748
819
  vvv3 vvv3Data(lvv3Data.begin(), lvv3Data.end());
749
- Py_BuildValue("%O", cvtVvv3toList(vvv3Data));
820
+ return cvtVvv3toList(vvv3Data);
750
821
  }
751
822
 
752
823
  static PyMethodDef aMeth[] =
@@ -769,12 +840,16 @@ static PyMethodDef aMeth[] =
769
840
  {"setShuf", (PyCFunction)setShuf, METH_FASTCALL, ""},
770
841
  {"setMaxG0", (PyCFunction)setMaxG0, METH_FASTCALL, ""},
771
842
  {"setMaxG1", (PyCFunction)setMaxG1, METH_FASTCALL, ""},
843
+ {"setMagGradSamp", (PyCFunction)setMagGradSamp, METH_FASTCALL, ""},
844
+ {"setMagTrajSamp", (PyCFunction)setMagTrajSamp, METH_FASTCALL, ""},
772
845
  {"setMagOverSamp", (PyCFunction)setMagOverSamp, METH_FASTCALL, ""},
773
846
  {"setMagSFS", (PyCFunction)setMagSFS, METH_FASTCALL, ""},
774
847
  {"setMagGradRep", (PyCFunction)setMagGradRep, METH_FASTCALL, ""},
775
848
  {"setMagTrajRep", (PyCFunction)setMagTrajRep, METH_FASTCALL, ""},
776
849
  {"setDbgPrint", (PyCFunction)setDbgPrint, METH_FASTCALL, ""},
850
+ {"saveF64", (PyCFunction)saveF64, METH_FASTCALL, ""},
777
851
  {"loadF64", (PyCFunction)loadF64, METH_FASTCALL, ""},
852
+ {"saveF32", (PyCFunction)saveF32, METH_FASTCALL, ""},
778
853
  {"loadF32", (PyCFunction)loadF32, METH_FASTCALL, ""},
779
854
  {NULL, NULL, 0, NULL} /* Sentinel */
780
855
  };
@@ -13,6 +13,8 @@
13
13
  bool gMrTraj_enMtg = false; // whether to use Lustig's minTimeGrad solver
14
14
  f64 gMrTraj_g0Norm = 0e0; // initial gradient amplitude
15
15
  f64 gMrTraj_g1Norm = 0e0; // final gradient amplitude
16
+ i64 gMrTraj_nGradSampRsv = 10000; // buffer size of mag solver
17
+ i64 gMrTraj_nTrajSampRsv = 10000; // num. of samp. when doing Traj. Rep.
16
18
 
17
19
  /*
18
20
  * A set of trajectories sufficient to fully-sample the k-space
@@ -51,7 +53,11 @@ public:
51
53
  m_nAcq(m_nAcq),
52
54
  m_nSampMax(m_nSampMax)
53
55
  {
54
- m_mag = Mag();
56
+ m_mag = Mag
57
+ (
58
+ gMrTraj_nGradSampRsv,
59
+ gMrTraj_nTrajSampRsv
60
+ );
55
61
  m_vv3GRampFront.reserve(1000);
56
62
  m_vv3GRampBack.reserve(1000);
57
63
  }
@@ -361,8 +367,6 @@ protected:
361
367
  bool calGrad(v3* pv3M0PE, vv3* pvv3GRO, vf64* pvf64P, TrajFunc& tfTraj, GradPara& objGradPara, i64 oversamp=8)
362
368
  {
363
369
  bool ret = true;
364
- const f64& sLim = objGradPara.sLim;
365
- const f64& dt = objGradPara.dt;
366
370
 
367
371
  // calculate GRO
368
372
  TIC;
@@ -27,8 +27,6 @@ public:
27
27
 
28
28
  virtual bool fit(const vf64& vf64X, const vf64& vf64Y)
29
29
  {
30
- ASSERT((i64)vf64X.size() <= m_sizCache);
31
- ASSERT((i64)vf64Y.size() <= m_sizCache);
32
30
  ASSERT(vf64X.size() == vf64Y.size());
33
31
  const i64 nSamp = vf64X.size();
34
32
  ASSERT(nSamp >= 2);
@@ -37,8 +37,6 @@ public:
37
37
 
38
38
  virtual bool fit(const vf64& vf64X, const vf64& vf64Y)
39
39
  {
40
- ASSERT((i64)vf64X.size() <= m_sizCache);
41
- ASSERT((i64)vf64Y.size() <= m_sizCache);
42
40
  ASSERT(vf64X.size() == vf64Y.size());
43
41
  const i64 nSamp = vf64X.size();
44
42
  ASSERT(nSamp >= 2);
@@ -1,6 +1,6 @@
1
1
  #include "v3.h"
2
2
  #include <array>
3
- #include <cinttypes>
3
+ #include <cstring> // test
4
4
 
5
5
  v3::v3() :x(0e0), y(0e0), z(0e0) {}
6
6
  v3::v3(f64 _) :x(_), y(_), z(_) {}
@@ -371,35 +371,39 @@ bool v3::saveF64(FILE* pfHdr, FILE* pfBin, const vv3& vv3Data)
371
371
  i64 lenData = vv3Data.size();
372
372
  fprintf(pfHdr, "float64[%ld][3];\n", (long)lenData);
373
373
 
374
- f64* bufFile = new f64[lenData*3];
374
+ f64* bufFile = (f64*)malloc(lenData*3*sizeof(f64));
375
375
  for(i64 i=0; i<(i64)lenData; ++i)
376
376
  {
377
377
  for(i64 j=0; j<3; ++j)
378
378
  { bufFile[3*i+j] = (f64)vv3Data[i][j]; }
379
379
  }
380
380
  ret &= (i64)fwrite(bufFile, sizeof(f64), lenData*3, pfBin)==lenData*3;
381
- delete[] bufFile;
381
+ free(bufFile);
382
382
  return ret;
383
383
  }
384
384
 
385
385
  bool v3::loadF64(FILE* pfHdr, FILE* pfBin, vv3* pvv3Data)
386
386
  {
387
387
  bool ret = true;
388
- i64 lenData = 0;
389
388
  pvv3Data->clear();
390
- int nRead = fscanf(pfHdr, "float64[%" SCNi64 "][3];\n", &lenData);
391
- if (nRead==EOF) return true; // EOF
392
- else if (nRead!=1) return false;
389
+ i64 lenData = 0;
390
+ {
391
+ long _;
392
+ int nRead = fscanf(pfHdr, "float64[%ld][3];\n", &_);
393
+ lenData = (i64)_;
394
+ if (nRead == EOF) return true; // EOF
395
+ else if (nRead != 1) return false;
396
+ }
393
397
  pvv3Data->resize(lenData);
394
398
 
395
- f64* bufFile = new f64[lenData*3];
399
+ f64* bufFile = (f64*)malloc(lenData*3*sizeof(f64));
396
400
  ret &= (i64)fread(bufFile, sizeof(f64), lenData*3, pfBin)==lenData*3;
397
- for(i64 i=0; i<(i64)pvv3Data->size(); ++i)
401
+ for(i64 i=0; i<lenData; ++i)
398
402
  {
399
403
  for(i64 j=0; j<3; ++j)
400
404
  { (*pvv3Data)[i][j] = (f64)bufFile[3*i+j]; }
401
405
  }
402
- delete[] bufFile;
406
+ free(bufFile);
403
407
  return ret;
404
408
  }
405
409
 
@@ -409,34 +413,38 @@ bool v3::saveF32(FILE* pfHdr, FILE* pfBin, const vv3& vv3Data)
409
413
  i64 lenData = vv3Data.size();
410
414
  fprintf(pfHdr, "float32[%ld][3];\n", (long)lenData);
411
415
 
412
- f32* bufFile = new f32[lenData*3];
416
+ f32* bufFile = (f32*)malloc(lenData*3*sizeof(f32));
413
417
  for(i64 i=0; i<(i64)lenData; ++i)
414
418
  {
415
419
  for(i64 j=0; j<3; ++j)
416
420
  { bufFile[3*i+j] = (f32)vv3Data[i][j]; }
417
421
  }
418
422
  ret &= (i64)fwrite(bufFile, sizeof(f32), lenData*3, pfBin)==lenData*3;
419
- delete[] bufFile;
423
+ free(bufFile);
420
424
  return ret;
421
425
  }
422
426
 
423
427
  bool v3::loadF32(FILE* pfHdr, FILE* pfBin, vv3* pvv3Data)
424
428
  {
425
429
  bool ret = true;
426
- i64 lenData = 0;
427
430
  pvv3Data->clear();
428
- int nRead = fscanf(pfHdr, "float32[%" SCNi64 "][3];\n", &lenData);
429
- if (nRead==EOF) return true; // EOF
430
- else if (nRead!=1) return false;
431
+ i64 lenData = 0;
432
+ {
433
+ long _;
434
+ int nRead = fscanf(pfHdr, "float32[%ld][3];\n", &_);
435
+ lenData = (i64)_;
436
+ if (nRead == EOF) return true; // EOF
437
+ else if (nRead != 1) return false;
438
+ }
431
439
  pvv3Data->resize(lenData);
432
440
 
433
- f32* bufFile = new f32[lenData*3];
441
+ f32* bufFile = (f32*)malloc(lenData*3*sizeof(f32));
434
442
  ret &= (i64)fread(bufFile, sizeof(f32), lenData*3, pfBin)==lenData*3;
435
- for(i64 i=0; i<(i64)pvv3Data->size(); ++i)
443
+ for(i64 i=0; i<lenData; ++i)
436
444
  {
437
445
  for(i64 j=0; j<3; ++j)
438
446
  { (*pvv3Data)[i][j] = (f64)bufFile[3*i+j]; }
439
447
  }
440
- delete[] bufFile;
448
+ free(bufFile);
441
449
  return ret;
442
450
  }
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "MRArbGrad"
7
- version = "4.1.0"
7
+ version = "4.2.0"
8
8
  dependencies = ["numpy"]
9
9
 
10
10
  description = "Gradient waveform design tool for arbitrary k-space trajectories."
@@ -4,7 +4,6 @@ from os.path import exists
4
4
  from ctypes.util import find_library
5
5
 
6
6
  useMtg = exists("./mrarbgrad_src/ext/mtg/")
7
- useJemalloc = find_library("jemalloc") is not None
8
7
 
9
8
  _sources = \
10
9
  [
@@ -23,7 +22,6 @@ modExt = Extension\
23
22
  (
24
23
  "mrarbgrad.ext",
25
24
  sources = _sources,
26
- libraries = ['jemalloc'] if useJemalloc else [],
27
25
  include_dirs = ["./mrarbgrad_src/ext/", numpy.get_include()],
28
26
  define_macros = [("USE_MTG", None)] if useMtg else None,
29
27
  language = 'c++'
File without changes
File without changes
File without changes
File without changes