From 556ee87ccfbe5bd312f23a86b003522d05b36e33 Mon Sep 17 00:00:00 2001 From: Evgueni Ovtchinnikov Date: Tue, 30 Nov 2021 16:33:20 +0000 Subject: [PATCH 01/14] implemented PETAcquisitionData::get_subset() --- .../include/sirf/STIR/stir_data_containers.h | 30 ++++++++++++++++--- src/xSTIR/cSTIR/stir_data_containers.cpp | 16 ++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h b/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h index 32861e435..fa0aba257 100644 --- a/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h +++ b/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h @@ -160,6 +160,8 @@ namespace sirf { return false; } + virtual std::unique_ptr get_subset(const std::vector& views) const = 0; + //! rebin the data to lower resolution by adding /*! \param num_segments_to_combine combines multiple oblique 'segments' together. If set to the @@ -401,6 +403,8 @@ namespace sirf { void binary_op_(const DataContainer& a_x, const DataContainer& a_y, int job); }; + //class PETAcquisitionDataInMemory; + /*! \ingroup PET \brief In-file implementation of PETAcquisitionData. @@ -485,6 +489,12 @@ namespace sirf { (_template->same_acquisition_data(this->get_exam_info_sptr(), this->get_proj_data_info_sptr()->create_shared_clone())); } + virtual std::unique_ptr get_subset(const std::vector& views) const; +// { +// auto uptr_sub = _data->get_subset(views); +// auto ptr_ad = new PETAcquisitionDataInMemory(uptr_sub); +// return std::unique_ptr(ptr_ad); +// } private: bool _owns_file; @@ -528,6 +538,10 @@ namespace sirf { ptr->fill(0.0f); _data.reset(ptr); } + PETAcquisitionDataInMemory(std::unique_ptr uptr_pd) + { + _data = std::move(uptr_pd); + } /// Constructor for PETAcquisitionDataInMemory from filename PETAcquisitionDataInMemory(const char* filename) { @@ -548,10 +562,10 @@ namespace sirf { (new stir::ProjDataInMemory(*pd_sptr)); } - static void init() - { - PETAcquisitionDataInFile::init(); - } + static void init(); +// { +// PETAcquisitionDataInFile::init(); +// } static void set_as_template() { init(); @@ -584,6 +598,14 @@ namespace sirf { (this->get_exam_info_sptr(), this->get_proj_data_info_sptr()->create_shared_clone())); } + virtual std::unique_ptr get_subset(const std::vector& views) const + { + //auto uptr_sub = std::move(_data->get_subset(views)); + //auto ptr_ad = new PETAcquisitionDataInMemory(uptr_sub); + auto ptr_ad = new PETAcquisitionDataInMemory(std::move(_data->get_subset(views))); + return std::unique_ptr(ptr_ad); + } + /// fill with single value virtual void fill(const float v) { diff --git a/src/xSTIR/cSTIR/stir_data_containers.cpp b/src/xSTIR/cSTIR/stir_data_containers.cpp index b930cf54c..487ca89c1 100644 --- a/src/xSTIR/cSTIR/stir_data_containers.cpp +++ b/src/xSTIR/cSTIR/stir_data_containers.cpp @@ -245,6 +245,22 @@ PETAcquisitionData::binary_op_( } } +std::unique_ptr +PETAcquisitionDataInFile::get_subset(const std::vector& views) const +{ +// auto uptr_sub = _data->get_subset(views); +// auto ptr_ad = new PETAcquisitionDataInMemory(uptr_sub); + auto ptr_ad = new PETAcquisitionDataInMemory(std::move(_data->get_subset(views))); + return std::unique_ptr(ptr_ad); +} + +void +PETAcquisitionDataInMemory::init() +{ + PETAcquisitionDataInFile::init(); +} + + STIRImageData::STIRImageData(const ImageData& id) { throw std::runtime_error("TODO - create STIRImageData from general SIRFImageData."); From c5e2261e42b560a3952a482eb847aec46f066533 Mon Sep 17 00:00:00 2001 From: Evgueni Ovtchinnikov Date: Tue, 30 Nov 2021 16:40:07 +0000 Subject: [PATCH 02/14] removed commented-out buggy lines --- src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h | 8 +------- src/xSTIR/cSTIR/stir_data_containers.cpp | 6 ++---- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h b/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h index fa0aba257..96398c80a 100644 --- a/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h +++ b/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h @@ -403,8 +403,6 @@ namespace sirf { void binary_op_(const DataContainer& a_x, const DataContainer& a_y, int job); }; - //class PETAcquisitionDataInMemory; - /*! \ingroup PET \brief In-file implementation of PETAcquisitionData. @@ -563,9 +561,7 @@ namespace sirf { } static void init(); -// { -// PETAcquisitionDataInFile::init(); -// } + static void set_as_template() { init(); @@ -600,8 +596,6 @@ namespace sirf { } virtual std::unique_ptr get_subset(const std::vector& views) const { - //auto uptr_sub = std::move(_data->get_subset(views)); - //auto ptr_ad = new PETAcquisitionDataInMemory(uptr_sub); auto ptr_ad = new PETAcquisitionDataInMemory(std::move(_data->get_subset(views))); return std::unique_ptr(ptr_ad); } diff --git a/src/xSTIR/cSTIR/stir_data_containers.cpp b/src/xSTIR/cSTIR/stir_data_containers.cpp index 487ca89c1..f11b84ec8 100644 --- a/src/xSTIR/cSTIR/stir_data_containers.cpp +++ b/src/xSTIR/cSTIR/stir_data_containers.cpp @@ -248,16 +248,14 @@ PETAcquisitionData::binary_op_( std::unique_ptr PETAcquisitionDataInFile::get_subset(const std::vector& views) const { -// auto uptr_sub = _data->get_subset(views); -// auto ptr_ad = new PETAcquisitionDataInMemory(uptr_sub); auto ptr_ad = new PETAcquisitionDataInMemory(std::move(_data->get_subset(views))); return std::unique_ptr(ptr_ad); } void PETAcquisitionDataInMemory::init() -{ - PETAcquisitionDataInFile::init(); +{ + PETAcquisitionDataInFile::init(); } From 4f83f35dd3881f7aacc9028e8331fbee0355d9dd Mon Sep 17 00:00:00 2001 From: Evgueni Ovtchinnikov Date: Wed, 1 Dec 2021 09:10:06 +0000 Subject: [PATCH 03/14] [ci skip] implemented C interface to PETAcquisitionData::get_subset --- src/xSTIR/cSTIR/cstir.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/xSTIR/cSTIR/cstir.cpp b/src/xSTIR/cSTIR/cstir.cpp index 503f96684..db274aed0 100644 --- a/src/xSTIR/cSTIR/cstir.cpp +++ b/src/xSTIR/cSTIR/cstir.cpp @@ -19,6 +19,8 @@ limitations under the License. */ +#include + #include "sirf/common/iequals.h" #include "sirf/STIR/stir_types.h" #include "sirf/iUtilities/DataHandle.h" @@ -850,6 +852,19 @@ void* cSTIR_get_ProjDataInfo(void* ptr_acq) CATCH; } +extern "C" +void* cSTIR_get_subset(void* ptr_acq, int nv, size_t ptr_views) +{ + try { + SPTR_FROM_HANDLE(PETAcquisitionData, sptr_ad, ptr_acq); + int* ptr_v = (int*)ptr_views; + std::vector v(ptr_v, ptr_v + nv); + std::shared_ptr sptr = std::move(sptr_ad->get_subset(v)); + return newObjectHandle(sptr); + } + CATCH; +} + extern "C" void* cSTIR_setupFBP2DReconstruction(void* ptr_r, void* ptr_i) { From 1e83a6674ce6a7c5da4b0530014625356fb9c36e Mon Sep 17 00:00:00 2001 From: Evgueni Ovtchinnikov Date: Wed, 1 Dec 2021 09:36:38 +0000 Subject: [PATCH 04/14] [ci skip] implemented Python interface to PETAcquisitionData::get_subset --- examples/Python/PET/acquisition_data.py | 8 ++++++++ src/xSTIR/cSTIR/include/sirf/STIR/cstir.h | 1 + src/xSTIR/pSTIR/STIR.py | 12 +++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/examples/Python/PET/acquisition_data.py b/examples/Python/PET/acquisition_data.py index 5720b08e5..580c202cc 100644 --- a/examples/Python/PET/acquisition_data.py +++ b/examples/Python/PET/acquisition_data.py @@ -86,6 +86,14 @@ def main(): acq_data.show(range(dim[1]//4)) acq_array = acq_data.as_array() + nv = dim[2]//2 + views = numpy.arange(nv) + acq_subset = acq_data.get_subset(views) + dim_subset = acq_subset.dimensions() + print('subset dimensions: %d x %d x %d x %d' % dim_subset) + if show_plot: + acq_subset.show(range(dim[1]//4), title='Sinograms of a subset of views') + # rebin the acquisition data new_acq_data = acq_data.rebin(3) rdim = new_acq_data.dimensions() diff --git a/src/xSTIR/cSTIR/include/sirf/STIR/cstir.h b/src/xSTIR/cSTIR/include/sirf/STIR/cstir.h index 04da62c45..84a51b0a6 100644 --- a/src/xSTIR/cSTIR/include/sirf/STIR/cstir.h +++ b/src/xSTIR/cSTIR/include/sirf/STIR/cstir.h @@ -111,6 +111,7 @@ extern "C" { (void* ptr_acq, const void * ptr_from); void* cSTIR_writeAcquisitionData(void* ptr_acq, const char* filename); void* cSTIR_get_ProjDataInfo(void* ptr_acq); + void* cSTIR_get_subset(void* ptr_acq, int nv, size_t ptr_views); // Reconstruction methods void* cSTIR_setupFBP2DReconstruction(void* ptr_r, void* ptr_i); diff --git a/src/xSTIR/pSTIR/STIR.py b/src/xSTIR/pSTIR/STIR.py index 967729799..413e2e8bc 100644 --- a/src/xSTIR/pSTIR/STIR.py +++ b/src/xSTIR/pSTIR/STIR.py @@ -983,7 +983,7 @@ def rebin(self, num_segments_to_combine, return ad def show(self, sino=None, tof=0, title=None): - '''Displays interactively selected sinograms.''' + '''Displays selected sinograms.''' if self.handle is None: raise AssertionError() if not HAVE_PYLAB: @@ -1053,6 +1053,16 @@ def get_info(self): pyiutil.deleteDataHandle(handle) return info + def get_subset(self, views): + """Returns the subset of self data formed by specified views + + views: numpy.int32 array of views + """ + n = len(views) + subset = AcquisitionData() + subset.handle = pystir.cSTIR_get_subset(self.handle, n, views.ctypes.data) + return subset + @property def shape(self): return self.dimensions() From ba54caa4a78799135a39f9cf9b4ac0e774d937ce Mon Sep 17 00:00:00 2001 From: Evgueni Ovtchinnikov Date: Wed, 9 Mar 2022 15:33:00 +0000 Subject: [PATCH 05/14] moved get_subset definition to PETAcquisitionData --- .../include/sirf/STIR/stir_data_containers.h | 15 ++------------- src/xSTIR/cSTIR/stir_data_containers.cpp | 2 +- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h b/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h index 96398c80a..5625d785a 100644 --- a/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h +++ b/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h @@ -160,7 +160,7 @@ namespace sirf { return false; } - virtual std::unique_ptr get_subset(const std::vector& views) const = 0; + virtual std::unique_ptr get_subset(const std::vector& views) const; //! rebin the data to lower resolution by adding /*! @@ -487,12 +487,6 @@ namespace sirf { (_template->same_acquisition_data(this->get_exam_info_sptr(), this->get_proj_data_info_sptr()->create_shared_clone())); } - virtual std::unique_ptr get_subset(const std::vector& views) const; -// { -// auto uptr_sub = _data->get_subset(views); -// auto ptr_ad = new PETAcquisitionDataInMemory(uptr_sub); -// return std::unique_ptr(ptr_ad); -// } private: bool _owns_file; @@ -536,7 +530,7 @@ namespace sirf { ptr->fill(0.0f); _data.reset(ptr); } - PETAcquisitionDataInMemory(std::unique_ptr uptr_pd) + PETAcquisitionDataInMemory(std::unique_ptr uptr_pd) { _data = std::move(uptr_pd); } @@ -594,11 +588,6 @@ namespace sirf { (this->get_exam_info_sptr(), this->get_proj_data_info_sptr()->create_shared_clone())); } - virtual std::unique_ptr get_subset(const std::vector& views) const - { - auto ptr_ad = new PETAcquisitionDataInMemory(std::move(_data->get_subset(views))); - return std::unique_ptr(ptr_ad); - } /// fill with single value virtual void fill(const float v) diff --git a/src/xSTIR/cSTIR/stir_data_containers.cpp b/src/xSTIR/cSTIR/stir_data_containers.cpp index f11b84ec8..240f3ab2a 100644 --- a/src/xSTIR/cSTIR/stir_data_containers.cpp +++ b/src/xSTIR/cSTIR/stir_data_containers.cpp @@ -246,7 +246,7 @@ PETAcquisitionData::binary_op_( } std::unique_ptr -PETAcquisitionDataInFile::get_subset(const std::vector& views) const +PETAcquisitionData::get_subset(const std::vector& views) const { auto ptr_ad = new PETAcquisitionDataInMemory(std::move(_data->get_subset(views))); return std::unique_ptr(ptr_ad); From 6a38b1ab74552d3711a117ba9055e55c8a91e2cc Mon Sep 17 00:00:00 2001 From: Evgueni Ovtchinnikov Date: Mon, 14 Mar 2022 10:13:35 +0000 Subject: [PATCH 06/14] added checking defined(USE_BOOST) before using handle->uses_boost_sptr() --- src/iUtilities/include/sirf/iUtilities/DataHandle.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/iUtilities/include/sirf/iUtilities/DataHandle.h b/src/iUtilities/include/sirf/iUtilities/DataHandle.h index 31dfd0dd4..0b6c65808 100644 --- a/src/iUtilities/include/sirf/iUtilities/DataHandle.h +++ b/src/iUtilities/include/sirf/iUtilities/DataHandle.h @@ -268,8 +268,10 @@ template void getObjectSptrFromHandle(const void* h, std::shared_ptr& sptr) { ObjectHandle* handle = (ObjectHandle*)h; +#if defined(USE_BOOST) if (handle->uses_boost_sptr()) THROW("cannot cast boost::shared_ptr to std::shared_ptr"); +#endif void* ptr = handle->data(); if (ptr == 0) THROW("zero data pointer cannot be dereferenced"); From 2d325f278358171fb398afd5d795d07537ef563f Mon Sep 17 00:00:00 2001 From: Evgueni Ovtchinnikov Date: Mon, 14 Mar 2022 10:17:35 +0000 Subject: [PATCH 07/14] tried handling in-file/in-memory ProjData subsets, in-file failed, tmp fix applied --- .../include/sirf/STIR/stir_data_containers.h | 39 ++++++++++++++++--- src/xSTIR/cSTIR/stir_data_containers.cpp | 10 ++++- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h b/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h index 5625d785a..2e57a07c1 100644 --- a/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h +++ b/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h @@ -94,7 +94,7 @@ namespace sirf { _filename(filename), _owns_file(owns_file) {} - ProjDataFile(stir::shared_ptr sptr_exam_info, + ProjDataFile(stir::shared_ptr sptr_exam_info, stir::shared_ptr sptr_proj_data_info, const std::string& filename, bool owns_file = true) : stir::ProjDataInterfile(SPTR_WRAP(sptr_exam_info), SPTR_WRAP(sptr_proj_data_info), @@ -160,7 +160,7 @@ namespace sirf { return false; } - virtual std::unique_ptr get_subset(const std::vector& views) const; + virtual std::unique_ptr get_subset(const std::vector& views) const = 0; //! rebin the data to lower resolution by adding /*! @@ -440,6 +440,22 @@ namespace sirf { ptr->fill(0.0f); _data.reset(ptr); } + PETAcquisitionDataInFile(std::unique_ptr uptr_pd) : _owns_file(true) + { + auto *pd_ptr = dynamic_cast(uptr_pd.get()); + if (pd_ptr) + _data = std::move(uptr_pd); + else { + stir::ProjData& pd = *uptr_pd; + stir::shared_ptr sptr_exam_info = + pd.get_exam_info_sptr(); + stir::shared_ptr sptr_proj_data_info = + pd.get_proj_data_info_sptr()->create_shared_clone(); + _data.reset(new ProjDataFile + (MAKE_SHARED(*sptr_exam_info), sptr_proj_data_info, + _filename = SIRFUtilities::scratch_file_name())); + } + } std::shared_ptr new_acquisition_data(std::string filename) { std::shared_ptr sptr_ad(new PETAcquisitionDataInFile); @@ -487,6 +503,7 @@ namespace sirf { (_template->same_acquisition_data(this->get_exam_info_sptr(), this->get_proj_data_info_sptr()->create_shared_clone())); } + virtual std::unique_ptr get_subset(const std::vector& views) const; private: bool _owns_file; @@ -530,9 +547,20 @@ namespace sirf { ptr->fill(0.0f); _data.reset(ptr); } - PETAcquisitionDataInMemory(std::unique_ptr uptr_pd) - { - _data = std::move(uptr_pd); + PETAcquisitionDataInMemory(std::unique_ptr uptr_pd) + { + auto *pd_ptr = dynamic_cast(uptr_pd.get()); + if (pd_ptr) + _data = std::move(uptr_pd); + else { + std::cout << "copying ProjData to ProjDataInMemory...\n"; + const stir::ProjData& pd = *uptr_pd; + auto exam_info_sptr = SPTR_WRAP(pd.get_exam_info_sptr()); + auto proj_data_info_sptr = + SPTR_WRAP(pd.get_proj_data_info_sptr()->create_shared_clone()); + _data.reset(new stir::ProjDataInMemory(exam_info_sptr, proj_data_info_sptr)); + _data->fill(pd); + } } /// Constructor for PETAcquisitionDataInMemory from filename PETAcquisitionDataInMemory(const char* filename) @@ -588,6 +616,7 @@ namespace sirf { (this->get_exam_info_sptr(), this->get_proj_data_info_sptr()->create_shared_clone())); } + virtual std::unique_ptr get_subset(const std::vector& views) const; /// fill with single value virtual void fill(const float v) diff --git a/src/xSTIR/cSTIR/stir_data_containers.cpp b/src/xSTIR/cSTIR/stir_data_containers.cpp index 240f3ab2a..571f91e18 100644 --- a/src/xSTIR/cSTIR/stir_data_containers.cpp +++ b/src/xSTIR/cSTIR/stir_data_containers.cpp @@ -246,7 +246,15 @@ PETAcquisitionData::binary_op_( } std::unique_ptr -PETAcquisitionData::get_subset(const std::vector& views) const +PETAcquisitionDataInFile::get_subset(const std::vector& views) const +{ +// auto ptr_ad = new PETAcquisitionDataInFile(std::move(_data->get_subset(views))); + auto ptr_ad = new PETAcquisitionDataInMemory(std::move(_data->get_subset(views))); + return std::unique_ptr(ptr_ad); +} + +std::unique_ptr +PETAcquisitionDataInMemory::get_subset(const std::vector& views) const { auto ptr_ad = new PETAcquisitionDataInMemory(std::move(_data->get_subset(views))); return std::unique_ptr(ptr_ad); From 73f677cb70163ac16bc94fee30d75547cb40282a Mon Sep 17 00:00:00 2001 From: Kris Thielemans Date: Fri, 8 Apr 2022 09:08:01 +0100 Subject: [PATCH 08/14] make get_subset() views argument safe we didn't check that it was a numpy.int32. now convert [ci skip] --- src/xSTIR/pSTIR/STIR.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/xSTIR/pSTIR/STIR.py b/src/xSTIR/pSTIR/STIR.py index 8967ed54d..b79b77be7 100644 --- a/src/xSTIR/pSTIR/STIR.py +++ b/src/xSTIR/pSTIR/STIR.py @@ -1098,11 +1098,20 @@ def get_info(self): def get_subset(self, views): """Returns the subset of self data formed by specified views - views: numpy.int32 array of views + views: numpy.int32 array of views (will be converted) """ + # Check if array is not already numpy ndarray + if not isinstance(views, numpy.ndarray): + views = numpy.array(views,dtype=numpy.int32) n = len(views) + if views.dtype is numpy.dtype('int32'): + v = views + else: + v = views.astype(numpy.int32) + if not v.flags['C_CONTIGUOUS']: + v = numpy.ascontiguousarray(v) subset = AcquisitionData() - subset.handle = pystir.cSTIR_get_subset(self.handle, n, views.ctypes.data) + subset.handle = pystir.cSTIR_get_subset(self.handle, n, v.ctypes.data) return subset @property From ca16410828f5a6910d6f019a1406adea7e9c8e72 Mon Sep 17 00:00:00 2001 From: Evgueni Ovtchinnikov Date: Tue, 12 Apr 2022 14:44:36 +0100 Subject: [PATCH 09/14] implemented C++ compatibility check/conversion for Python int arrays --- src/common/Utilities.py | 17 ++++++++++++++++- .../include/sirf/iUtilities/iutilities.h | 1 + src/iUtilities/iutilities.cpp | 5 +++++ src/xSTIR/pSTIR/STIR.py | 16 +++++----------- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/common/Utilities.py b/src/common/Utilities.py index 0dc2dc231..d758d456c 100644 --- a/src/common/Utilities.py +++ b/src/common/Utilities.py @@ -31,6 +31,21 @@ RE_PYEXT = re.compile(r"\.(py[co]?)$") +def cpp_int_bytes(): + return pyiutil.intBytes() + + +def cpp_int_array(v): + dt = numpy.dtype('int%s' % cpp_int_bytes()) + if not isinstance(v, numpy.ndarray): + v = numpy.array(v, dtype=dt) + elif dt != v.dtype: + v = v.astype(dt) + if not v.flags['C_CONTIGUOUS']: + v = numpy.ascontiguousarray(v) + return v + + @deprecated( deprecated_in="2.0.0", removed_in="4.0", current_version=sirf.__version__, details="use examples_data_path() instead") @@ -889,4 +904,4 @@ def test_sapyb_mixed(self): out.fill(-arr) image1.sapyb(a, out, b, out=out) numpy.testing.assert_allclose(out.as_array(), gold) - numpy.testing.assert_allclose(image1.as_array(), arr) \ No newline at end of file + numpy.testing.assert_allclose(image1.as_array(), arr) diff --git a/src/iUtilities/include/sirf/iUtilities/iutilities.h b/src/iUtilities/include/sirf/iUtilities/iutilities.h index db5a213e7..ab8aba7f6 100644 --- a/src/iUtilities/include/sirf/iUtilities/iutilities.h +++ b/src/iUtilities/include/sirf/iUtilities/iutilities.h @@ -24,6 +24,7 @@ limitations under the License. #ifndef IUTILITIES_FOR_MATLAB extern "C" { #endif + int intBytes(); void* newDataHandle(); void deleteDataHandle(void* ptr); void* charDataHandle(const char* s); diff --git a/src/iUtilities/iutilities.cpp b/src/iUtilities/iutilities.cpp index 47d313096..140aa3122 100644 --- a/src/iUtilities/iutilities.cpp +++ b/src/iUtilities/iutilities.cpp @@ -36,6 +36,11 @@ Defines C functions handling DataHandle objects. extern "C" { + int intBytes() + { + return 8*sizeof(int); + } + void* newDataHandle() // C constructor { return (void*)new DataHandle; diff --git a/src/xSTIR/pSTIR/STIR.py b/src/xSTIR/pSTIR/STIR.py index b79b77be7..a3727d994 100644 --- a/src/xSTIR/pSTIR/STIR.py +++ b/src/xSTIR/pSTIR/STIR.py @@ -33,7 +33,7 @@ from deprecation import deprecated from sirf.Utilities import show_2D_array, show_3D_array, error, check_status, \ - try_calling, assert_validity, \ + try_calling, assert_validity, cpp_int_array, \ examples_data_path, existing_filepath, pTest from sirf import SIRF from sirf.SIRF import DataContainer @@ -1098,18 +1098,12 @@ def get_info(self): def get_subset(self, views): """Returns the subset of self data formed by specified views - views: numpy.int32 array of views (will be converted) + views: array of views (will be converted to numpy ndarray) """ - # Check if array is not already numpy ndarray - if not isinstance(views, numpy.ndarray): - views = numpy.array(views,dtype=numpy.int32) + '''Ensure the array passed to C++ is a contiguous array of C++ int's + ''' + v = cpp_int_array(views) n = len(views) - if views.dtype is numpy.dtype('int32'): - v = views - else: - v = views.astype(numpy.int32) - if not v.flags['C_CONTIGUOUS']: - v = numpy.ascontiguousarray(v) subset = AcquisitionData() subset.handle = pystir.cSTIR_get_subset(self.handle, n, v.ctypes.data) return subset From d6fad5d633af0d7ef44eb0e67d73568fa8a60cd3 Mon Sep 17 00:00:00 2001 From: Evgueni Ovtchinnikov Date: Wed, 20 Apr 2022 15:53:06 +0000 Subject: [PATCH 10/14] correction: intBytes->intBits etc. [ci skip] --- src/common/Utilities.py | 6 +++--- src/iUtilities/include/sirf/iUtilities/iutilities.h | 2 +- src/iUtilities/iutilities.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/common/Utilities.py b/src/common/Utilities.py index d758d456c..66ec85537 100644 --- a/src/common/Utilities.py +++ b/src/common/Utilities.py @@ -31,12 +31,12 @@ RE_PYEXT = re.compile(r"\.(py[co]?)$") -def cpp_int_bytes(): - return pyiutil.intBytes() +def cpp_int_bits(): + return pyiutil.intBits() def cpp_int_array(v): - dt = numpy.dtype('int%s' % cpp_int_bytes()) + dt = numpy.dtype('int%s' % cpp_int_bits()) if not isinstance(v, numpy.ndarray): v = numpy.array(v, dtype=dt) elif dt != v.dtype: diff --git a/src/iUtilities/include/sirf/iUtilities/iutilities.h b/src/iUtilities/include/sirf/iUtilities/iutilities.h index ab8aba7f6..acdfe78fd 100644 --- a/src/iUtilities/include/sirf/iUtilities/iutilities.h +++ b/src/iUtilities/include/sirf/iUtilities/iutilities.h @@ -24,7 +24,7 @@ limitations under the License. #ifndef IUTILITIES_FOR_MATLAB extern "C" { #endif - int intBytes(); + int intBits(); void* newDataHandle(); void deleteDataHandle(void* ptr); void* charDataHandle(const char* s); diff --git a/src/iUtilities/iutilities.cpp b/src/iUtilities/iutilities.cpp index 140aa3122..072691290 100644 --- a/src/iUtilities/iutilities.cpp +++ b/src/iUtilities/iutilities.cpp @@ -36,7 +36,7 @@ Defines C functions handling DataHandle objects. extern "C" { - int intBytes() + int intBits() { return 8*sizeof(int); } From 6330b6717a0d4be1a2351ca97901f20de2bebcfd Mon Sep 17 00:00:00 2001 From: Evgueni Ovtchinnikov Date: Thu, 21 Apr 2022 16:29:00 +0000 Subject: [PATCH 11/14] fixed conflicts with master --- src/common/Utilities.py | 8 ++++++++ src/iUtilities/iutilities.cpp | 2 +- src/xSTIR/pSTIR/STIR.py | 3 ++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/common/Utilities.py b/src/common/Utilities.py index 66ec85537..094220b11 100644 --- a/src/common/Utilities.py +++ b/src/common/Utilities.py @@ -32,10 +32,18 @@ def cpp_int_bits(): + """Returns the number of bits in a C++ integer.""" return pyiutil.intBits() +def cpp_int_dtype(): + """Returns numpy dtype corresponding to a C++ int.""" + dt = 'int%s' % cpp_int_bits() + return numpy.dtype(dt) + + def cpp_int_array(v): + """Converts the input into numpy.ndarray compatible with C++ int array.""" dt = numpy.dtype('int%s' % cpp_int_bits()) if not isinstance(v, numpy.ndarray): v = numpy.array(v, dtype=dt) diff --git a/src/iUtilities/iutilities.cpp b/src/iUtilities/iutilities.cpp index 072691290..a8df5a235 100644 --- a/src/iUtilities/iutilities.cpp +++ b/src/iUtilities/iutilities.cpp @@ -38,7 +38,7 @@ extern "C" { int intBits() { - return 8*sizeof(int); + return 8 * sizeof(int); } void* newDataHandle() // C constructor diff --git a/src/xSTIR/pSTIR/STIR.py b/src/xSTIR/pSTIR/STIR.py index a3727d994..def1b278a 100644 --- a/src/xSTIR/pSTIR/STIR.py +++ b/src/xSTIR/pSTIR/STIR.py @@ -33,7 +33,8 @@ from deprecation import deprecated from sirf.Utilities import show_2D_array, show_3D_array, error, check_status, \ - try_calling, assert_validity, cpp_int_array, \ + try_calling, assert_validity, \ + cpp_int_dtype, cpp_int_array, \ examples_data_path, existing_filepath, pTest from sirf import SIRF from sirf.SIRF import DataContainer From 1f0064380e5e0ef016bcbc3cbbacf5aef7ac2ea3 Mon Sep 17 00:00:00 2001 From: Evgueni Ovtchinnikov Date: Mon, 6 Jun 2022 16:03:02 +0000 Subject: [PATCH 12/14] small corrections on STIR side --- src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h | 7 +++++-- src/xSTIR/cSTIR/stir_data_containers.cpp | 4 ++-- src/xSTIR/pSTIR/STIR.py | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h b/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h index 7b314a0ed..3ee137ec3 100644 --- a/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h +++ b/src/xSTIR/cSTIR/include/sirf/STIR/stir_data_containers.h @@ -442,7 +442,8 @@ namespace sirf { } PETAcquisitionDataInFile(std::unique_ptr uptr_pd) : _owns_file(true) { - auto *pd_ptr = dynamic_cast(uptr_pd.get()); +// auto *pd_ptr = dynamic_cast(uptr_pd.get()); + auto pd_ptr = dynamic_cast(uptr_pd.get()); if (pd_ptr) _data = std::move(uptr_pd); else { @@ -454,6 +455,7 @@ namespace sirf { _data.reset(new ProjDataFile (MAKE_SHARED(*sptr_exam_info), sptr_proj_data_info, _filename = SIRFUtilities::scratch_file_name())); + _data->fill(pd); } } std::shared_ptr new_acquisition_data(std::string filename) @@ -549,7 +551,8 @@ namespace sirf { } PETAcquisitionDataInMemory(std::unique_ptr uptr_pd) { - auto *pd_ptr = dynamic_cast(uptr_pd.get()); +// auto *pd_ptr = dynamic_cast(uptr_pd.get()); + auto pd_ptr = dynamic_cast(uptr_pd.get()); if (pd_ptr) _data = std::move(uptr_pd); else { diff --git a/src/xSTIR/cSTIR/stir_data_containers.cpp b/src/xSTIR/cSTIR/stir_data_containers.cpp index 571f91e18..e7682a9ad 100644 --- a/src/xSTIR/cSTIR/stir_data_containers.cpp +++ b/src/xSTIR/cSTIR/stir_data_containers.cpp @@ -248,8 +248,8 @@ PETAcquisitionData::binary_op_( std::unique_ptr PETAcquisitionDataInFile::get_subset(const std::vector& views) const { -// auto ptr_ad = new PETAcquisitionDataInFile(std::move(_data->get_subset(views))); - auto ptr_ad = new PETAcquisitionDataInMemory(std::move(_data->get_subset(views))); + auto ptr_ad = new PETAcquisitionDataInFile(std::move(_data->get_subset(views))); +// auto ptr_ad = new PETAcquisitionDataInMemory(std::move(_data->get_subset(views))); return std::unique_ptr(ptr_ad); } diff --git a/src/xSTIR/pSTIR/STIR.py b/src/xSTIR/pSTIR/STIR.py index def1b278a..672a7c28c 100644 --- a/src/xSTIR/pSTIR/STIR.py +++ b/src/xSTIR/pSTIR/STIR.py @@ -1107,6 +1107,7 @@ def get_subset(self, views): n = len(views) subset = AcquisitionData() subset.handle = pystir.cSTIR_get_subset(self.handle, n, v.ctypes.data) + check_status(subset.handle) return subset @property From e9ab9927a0eab0d8497b8e114a01662cd618d9f8 Mon Sep 17 00:00:00 2001 From: Evgueni Ovtchinnikov Date: Mon, 6 Jun 2022 16:14:22 +0000 Subject: [PATCH 13/14] restricted subset demo to memory storage scheme pending #1111 fix --- examples/Python/PET/acquisition_data.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/examples/Python/PET/acquisition_data.py b/examples/Python/PET/acquisition_data.py index 580c202cc..075a9ee61 100644 --- a/examples/Python/PET/acquisition_data.py +++ b/examples/Python/PET/acquisition_data.py @@ -86,13 +86,14 @@ def main(): acq_data.show(range(dim[1]//4)) acq_array = acq_data.as_array() - nv = dim[2]//2 - views = numpy.arange(nv) - acq_subset = acq_data.get_subset(views) - dim_subset = acq_subset.dimensions() - print('subset dimensions: %d x %d x %d x %d' % dim_subset) - if show_plot: - acq_subset.show(range(dim[1]//4), title='Sinograms of a subset of views') + if storage[0] == 'm': + nv = dim[2]//2 + views = numpy.arange(nv) + acq_subset = acq_data.get_subset(views) + dim_subset = acq_subset.dimensions() + print('subset dimensions: %d x %d x %d x %d' % dim_subset) + if show_plot: + acq_subset.show(range(dim[1]//4), title='Sinograms of a subset of views') # rebin the acquisition data new_acq_data = acq_data.rebin(3) From 112526ba91c7eaa8c6a09d9c418bac3766fb3099 Mon Sep 17 00:00:00 2001 From: Kris Thielemans Date: Thu, 1 Sep 2022 09:53:33 +0100 Subject: [PATCH 14/14] minor changes in Python comments Co-authored-by: Ashley Gillman --- examples/Python/PET/acquisition_data.py | 2 +- src/xSTIR/pSTIR/STIR.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/Python/PET/acquisition_data.py b/examples/Python/PET/acquisition_data.py index 075a9ee61..95369a2c6 100644 --- a/examples/Python/PET/acquisition_data.py +++ b/examples/Python/PET/acquisition_data.py @@ -86,7 +86,7 @@ def main(): acq_data.show(range(dim[1]//4)) acq_array = acq_data.as_array() - if storage[0] == 'm': + if storage[0] == 'm': # for now, we can only subset acquisition data stored in memory nv = dim[2]//2 views = numpy.arange(nv) acq_subset = acq_data.get_subset(views) diff --git a/src/xSTIR/pSTIR/STIR.py b/src/xSTIR/pSTIR/STIR.py index 672a7c28c..5252b919a 100644 --- a/src/xSTIR/pSTIR/STIR.py +++ b/src/xSTIR/pSTIR/STIR.py @@ -1101,8 +1101,7 @@ def get_subset(self, views): views: array of views (will be converted to numpy ndarray) """ - '''Ensure the array passed to C++ is a contiguous array of C++ int's - ''' + # Ensure the array passed to C++ is a contiguous array of C++ int's v = cpp_int_array(views) n = len(views) subset = AcquisitionData()