SIRF  3.6.0
stir_data_containers.h
Go to the documentation of this file.
1 /*
2 SyneRBI Synergistic Image Reconstruction Framework (SIRF)
3 Copyright 2015 - 2019 Rutherford Appleton Laboratory STFC
4 Copyright 2018 - 2020 University College London
5 
6 This is software developed for the Collaborative Computational
7 Project in Synergistic Reconstruction for Biomedical Imaging (formerly CCP PETMR)
8 (http://www.ccpsynerbi.ac.uk/).
9 
10 Licensed under the Apache License, Version 2.0 (the "License");
11 you may not use this file except in compliance with the License.
12 You may obtain a copy of the License at
13 http://www.apache.org/licenses/LICENSE-2.0
14 Unless required by applicable law or agreed to in writing, software
15 distributed under the License is distributed on an "AS IS" BASIS,
16 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 See the License for the specific language governing permissions and
18 limitations under the License.
19 
20 */
21 
32 #ifndef STIR_DATA_CONTAINER_TYPES
33 #define STIR_DATA_CONTAINER_TYPES
34 
35 #include <stdlib.h>
36 
37 #include <chrono>
38 #include <fstream>
39 #include <exception>
40 #include <iterator>
41 #include "sirf/STIR/stir_types.h"
42 #include "sirf/iUtilities/LocalisedException.h"
44 #include "sirf/common/iequals.h"
45 #include "sirf/common/JacobiCG.h"
46 #include "sirf/common/DataContainer.h"
47 #include "sirf/common/ANumRef.h"
48 #include "sirf/common/ImageData.h"
49 #include "sirf/common/GeometricalInfo.h"
50 #include "stir/ZoomOptions.h"
51 
52 #if STIR_VERSION < 050000
53 #define SPTR_WRAP(X) X->create_shared_clone()
54 #else
55 #define SPTR_WRAP(X) X
56 #endif
57 
58 namespace sirf {
59 
60  class SIRFUtilities {
61  public:
62  static long long milliseconds()
63  {
64  auto now = std::chrono::system_clock::now();
65  auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
66  return (long long)ms.count();
67  }
68  static std::string scratch_file_name()
69  {
70  static int calls = 0;
71  char buff[32];
72  long long int ms = milliseconds();
73  calls++;
74  sprintf(buff, "tmp_%d_%lld", calls, ms);
75  return std::string(buff);
76  }
77  };
78 
87  class ProjDataFile : public stir::ProjDataInterfile {
88 
89  public:
90  ProjDataFile(const stir::ProjData& pd, const std::string& filename, bool owns_file = true) :
91  stir::ProjDataInterfile(pd.get_exam_info_sptr(),
92  pd.get_proj_data_info_sptr()->create_shared_clone(),
93  filename, std::ios::in | std::ios::out | std::ios::trunc),
94  _filename(filename),
95  _owns_file(owns_file)
96  {}
97  ProjDataFile(stir::shared_ptr<const stir::ExamInfo> sptr_exam_info,
98  stir::shared_ptr<stir::ProjDataInfo> sptr_proj_data_info,
99  const std::string& filename, bool owns_file = true) :
100  stir::ProjDataInterfile(SPTR_WRAP(sptr_exam_info), SPTR_WRAP(sptr_proj_data_info),
101  filename, std::ios::in | std::ios::out | std::ios::trunc),
102  _filename(filename),
103  _owns_file(owns_file)
104  {}
105  ~ProjDataFile()
106  {
107  close_stream();
108  clear_stream();
109  if (!_owns_file)
110  return;
111  int err;
112  err = std::remove((_filename + ".hs").c_str());
113  if (err)
114  std::cout << "deleting " << _filename << ".hs "
115  << "failed, please delete manually" << std::endl;
116  err = std::remove((_filename + ".s").c_str());
117  if (err)
118  std::cout << "deleting " << _filename << ".s "
119  << "failed, please delete manually" << std::endl;
120  }
121  stir::shared_ptr<std::iostream> sino_stream_sptr()
122  {
123  return sino_stream;
124  }
125  void close_stream()
126  {
127  ((std::fstream*)sino_stream.get())->close();
128  }
129  void clear_stream()
130  {
131  ((std::fstream*)sino_stream.get())->clear();
132  }
133  private:
134  bool _owns_file;
135  std::string _filename;
136  };
137 
149  public:
150  virtual ~STIRAcquisitionData() {}
151 
152  // virtual constructors
153  virtual STIRAcquisitionData* same_acquisition_data
154  (stir::shared_ptr<const stir::ExamInfo> sptr_exam_info,
155  stir::shared_ptr<stir::ProjDataInfo> sptr_proj_data_info) const = 0;
156  virtual std::shared_ptr<STIRAcquisitionData> new_acquisition_data() const = 0;
157 
158  virtual bool is_complex() const
159  {
160  return false;
161  }
162 
163  virtual std::unique_ptr<STIRAcquisitionData> get_subset(const std::vector<int>& views) const = 0;
164 
166 
180  std::shared_ptr<STIRAcquisitionData> single_slice_rebinned_data(
181  const int num_segments_to_combine,
182  const int num_views_to_combine = 1,
183  const int num_tang_poss_to_trim = 0,
184  const bool do_normalisation = true,
185  const int max_in_segment_num_to_process = -1,
186  const int num_tof_bins_to_combine = 1
187  )
188  {
189  stir::shared_ptr<stir::ProjDataInfo> out_proj_data_info_sptr(
190  stir::SSRB(*data()->get_proj_data_info_sptr(),
191  num_segments_to_combine,
192  num_views_to_combine,
193  num_tang_poss_to_trim,
194  max_in_segment_num_to_process,
195  num_tof_bins_to_combine
196  ));
197  std::shared_ptr<STIRAcquisitionData>
198  sptr(same_acquisition_data
199  (this->get_exam_info_sptr(), out_proj_data_info_sptr));
200  stir::SSRB(*sptr, *data(), do_normalisation);
201  return sptr;
202  }
203 
204  static std::string storage_scheme()
205  {
206  static bool initialized = false;
207  if (!initialized) {
208  _storage_scheme = "file";
209  initialized = true;
210  }
211  return _storage_scheme;
212  }
213  static std::shared_ptr<STIRAcquisitionData> storage_template()
214  {
215  return _template;
216  }
217 
218  stir::shared_ptr<stir::ProjData> data()
219  {
220  return _data;
221  }
222  const stir::shared_ptr<stir::ProjData> data() const
223  {
224  return _data;
225  }
226  void set_data(stir::shared_ptr<stir::ProjData> data)
227  {
228  _data = data;
229  }
230 
231  // data import/export
232  virtual void fill(const float v) { data()->fill(v); }
233  virtual void fill(const STIRAcquisitionData& ad)
234  {
235  if (ad.is_empty())
236  THROW("The source of STIRAcquisitionData::fill is empty");
237  stir::shared_ptr<stir::ProjData> sptr = ad.data();
238  data()->fill(*sptr);
239  }
240  virtual void fill_from(const float* d) { data()->fill_from(d); }
241  virtual void copy_to(float* d) const { data()->copy_to(d); }
242  std::unique_ptr<STIRAcquisitionData> clone() const
243  {
244  return std::unique_ptr<STIRAcquisitionData>(clone_impl());
245  }
246 
247  // data container methods
248  unsigned int items() const {
249  if (_is_empty != -1)
250  return _is_empty ? 0 : 1;
251  try {
252 #ifdef STIR_TOF
253  get_segment_by_sinogram(0,0);
254 #else
255  get_segment_by_sinogram(0);
256 #endif
257  }
258  catch (...) {
259  _is_empty = 1;
260  return 0; // no data found - this must be a template
261  }
262  _is_empty = 0;
263  return 1; // data ok
264  }
265  virtual float norm() const;
267  virtual void sum(void* ptr) const;
268  virtual void max(void* ptr) const;
269  virtual void dot(const DataContainer& a_x, void* ptr) const;
270  float dot(const DataContainer& a_x) const
271  {
272  float s;
273  dot(a_x, &s);
274  return s;
275  }
276  virtual void axpby(
277  const void* ptr_a, const DataContainer& a_x,
278  const void* ptr_b, const DataContainer& a_y);
279  virtual void xapyb(
280  const DataContainer& a_x, const void* ptr_a,
281  const DataContainer& a_y, const void* ptr_b);
282  virtual void xapyb(
283  const DataContainer& a_x, const DataContainer& a_a,
284  const DataContainer& a_y, const DataContainer& a_b);
285  virtual void xapyb(
286  const DataContainer& a_x, const void* ptr_a,
287  const DataContainer& a_y, const DataContainer& a_b);
288  virtual void abs(const DataContainer& x)
289  {
290  unary_op(x, std::abs);
291  }
292  virtual void exp(const DataContainer& x)
293  {
294  unary_op(x, std::exp);
295  }
296  virtual void log(const DataContainer& x)
297  {
298  unary_op(x, std::log);
299  }
300  virtual void sqrt(const DataContainer& x)
301  {
302  unary_op(x, std::sqrt);
303  }
304  virtual void sign(const DataContainer& x)
305  {
306  unary_op(x, DataContainer::sign);
307  }
308  virtual void multiply(const DataContainer& x, const void* ptr_y)
309  {
310  float y = *static_cast<const float*>(ptr_y);
311  semibinary_op(x, y, DataContainer::product<float>);
312  }
313  virtual void add(const DataContainer& x, const void* ptr_y)
314  {
315  float y = *static_cast<const float*>(ptr_y);
316  semibinary_op(x, y, DataContainer::sum<float>);
317  }
318  virtual void divide(const DataContainer& x, const void* ptr_y)
319  {
320  float y = *static_cast<const float*>(ptr_y);
321  semibinary_op(x, y, DataContainer::ratio<float>);
322  }
323  virtual void maximum(const DataContainer& x, const void* ptr_y)
324  {
325  float y = *static_cast<const float*>(ptr_y);
326  semibinary_op(x, y, DataContainer::maximum<float>);
327  }
328  virtual void minimum(const DataContainer& x, const void* ptr_y)
329  {
330  float y = *static_cast<const float*>(ptr_y);
331  semibinary_op(x, y, DataContainer::minimum<float>);
332  }
333  virtual void power(const DataContainer& x, const void* ptr_y)
334  {
335  float y = *static_cast<const float*>(ptr_y);
336  semibinary_op(x, y, std::pow);
337  }
338  virtual void multiply(const DataContainer& x, const DataContainer& y)
339  {
340  binary_op(x, y, DataContainer::product<float>);
341  }
342  virtual void divide(const DataContainer& x, const DataContainer& y)
343  {
344  binary_op(x, y, DataContainer::ratio<float>);
345  }
346  virtual void maximum(const DataContainer& x, const DataContainer& y)
347  {
348  binary_op(x, y, DataContainer::maximum<float>);
349  }
350  virtual void minimum(const DataContainer& x, const DataContainer& y)
351  {
352  binary_op(x, y, DataContainer::minimum<float>);
353  }
354  virtual void power(const DataContainer& x, const DataContainer& y)
355  {
356  binary_op(x, y, std::pow);
357  }
358  virtual void inv(float a, const DataContainer& x);
359  virtual void write(const std::string &filename) const
360  {
361  ProjDataFile pd(*data(), filename.c_str(), false);
362  pd.fill(*data());
363  }
364 
365  // ProjData methods
366  int get_num_tangential_poss()
367  {
368  return data()->get_num_tangential_poss();
369  }
370  int get_num_views()
371  {
372  return data()->get_num_views();
373  }
375 
378  int get_num_sinograms() const
379  {
380  return data()->get_num_sinograms();
381  }
383 
385  {
386  return data()->get_num_non_tof_sinograms();
387  }
388 
389  int get_num_TOF_bins()
390  {
391  return data()->get_num_tof_poss();
392  }
393 
394  int get_tof_mash_factor() const
395  {
396  return data()->get_proj_data_info_sptr()->get_tof_mash_factor();
397  }
398 
399  size_t get_dimensions(int* dim)
400  {
401  dim[0] = get_num_tangential_poss();
402  dim[1] = get_num_views();
403  dim[2] = get_num_non_TOF_sinograms();
404  dim[3] = get_num_TOF_bins();
405  return static_cast<size_t>(dim[0] * dim[1] * dim[2] * dim[3]);
406  }
407  int get_max_segment_num() const
408  {
409  return data()->get_max_segment_num();
410  }
411 #ifdef STIR_TOF
412  stir::SegmentBySinogram<float>
413  get_segment_by_sinogram(const int segment_num, const int timing_pos_num) const
414  {
415  return data()->get_segment_by_sinogram(segment_num, timing_pos_num);
416  }
417 #else
418  stir::SegmentBySinogram<float>
419  get_segment_by_sinogram(const int segment_num) const
420  {
421  return data()->get_segment_by_sinogram(segment_num);
422  }
423 #endif
424 #ifdef STIR_TOF
425  stir::SegmentBySinogram<float>
426  get_empty_segment_by_sinogram(const int segment_num, const int timing_pos_num) const
427  {
428  return data()->get_empty_segment_by_sinogram(segment_num, false, timing_pos_num);
429  }
430 #else
431  stir::SegmentBySinogram<float>
432  get_empty_segment_by_sinogram(const int segment_num) const
433  {
434  return data()->get_empty_segment_by_sinogram(segment_num);
435  }
436 #endif
437  void set_segment(const stir::SegmentBySinogram<float>& s)
438  {
439  if (data()->set_segment(s) != stir::Succeeded::yes)
440  THROW("stir::ProjData set segment failed");
441  }
442  stir::shared_ptr<const stir::ExamInfo> get_exam_info_sptr() const
443  {
444  return data()->get_exam_info_sptr();
445  }
446  stir::shared_ptr<const stir::ProjDataInfo> get_proj_data_info_sptr() const
447  {
448  return data()->get_proj_data_info_sptr();
449  }
450 
451  // ProjData casts
452  operator stir::ProjData&() { return *data(); }
453  operator const stir::ProjData&() const { return *data(); }
454  operator stir::shared_ptr<stir::ProjData>() { return data(); }
455 
456  static stir::shared_ptr<stir::ProjDataInfo>
457  proj_data_info_from_scanner(std::string scanner_name,
458  int span = 1, int max_ring_diff = -1, int view_mash_factor = 1)
459  {
460  stir::shared_ptr<stir::Scanner>
461  sptr_s(stir::Scanner::get_scanner_from_name(scanner_name));
462  //std::cout << "scanner: " << sptr_s->get_name().c_str() << '\n';
463  if (sirf::iequals(sptr_s->get_name(), "unknown")) {
464  throw LocalisedException("Unknown scanner", __FILE__, __LINE__);
465  }
466  int num_views = sptr_s->get_num_detectors_per_ring() / 2 / view_mash_factor;
467  int num_tang_pos = sptr_s->get_max_num_non_arccorrected_bins();
468  if (max_ring_diff < 0)
469  max_ring_diff = sptr_s->get_num_rings() - 1;
470  return std::move(stir::ProjDataInfo::construct_proj_data_info
471  (sptr_s, span, max_ring_diff, num_views, num_tang_pos, false));
472  }
473 
474  void unary_op(const DataContainer& a_x, float(*f)(float));
475  void semibinary_op(const DataContainer& a_x, float y, float(*f)(float, float));
476  void binary_op(const DataContainer& a_x, const DataContainer& a_y, float(*f)(float, float));
477 
478  protected:
479  static std::string _storage_scheme;
480  static std::shared_ptr<STIRAcquisitionData> _template;
481  stir::shared_ptr<stir::ProjData> _data;
482  virtual STIRAcquisitionData* clone_impl() const = 0;
483  STIRAcquisitionData* clone_base() const
484  {
485  stir::shared_ptr<stir::ProjDataInfo> sptr_pdi = this->get_proj_data_info_sptr()->create_shared_clone();
486  STIRAcquisitionData* ptr =
487  _template->same_acquisition_data(this->get_exam_info_sptr(), sptr_pdi);
488  if (!this->is_empty())
489  ptr->fill(*this);
490  return ptr;
491  }
492 
493  private:
494  mutable int _is_empty = -1;
495  };
496 
504  public:
505  STIRAcquisitionDataInFile() : _owns_file(false) {}
506  STIRAcquisitionDataInFile(const char* filename) : _owns_file(false)
507  {
508  _data = stir::ProjData::read_from_file(filename);
509  }
510  STIRAcquisitionDataInFile(stir::shared_ptr<const stir::ExamInfo> sptr_exam_info,
511  stir::shared_ptr<stir::ProjDataInfo> sptr_proj_data_info)
512  {
513  _data.reset(new ProjDataFile
514  (MAKE_SHARED<stir::ExamInfo>(*sptr_exam_info), sptr_proj_data_info,
515  _filename = SIRFUtilities::scratch_file_name()));
516  }
517  STIRAcquisitionDataInFile(const stir::ProjData& pd) : _owns_file(true)
518  {
519  _data.reset(new ProjDataFile
520  (pd, _filename = SIRFUtilities::scratch_file_name()));
521  }
523  (stir::shared_ptr<stir::ExamInfo> sptr_ei, std::string scanner_name,
524  int span = 1, int max_ring_diff = -1, int view_mash_factor = 1)
525  {
526  stir::shared_ptr<stir::ProjDataInfo> sptr_pdi =
527  STIRAcquisitionData::proj_data_info_from_scanner
528  (scanner_name, span, max_ring_diff, view_mash_factor);
529  ProjDataFile* ptr = new ProjDataFile(sptr_ei, sptr_pdi,
530  _filename = SIRFUtilities::scratch_file_name());
531  ptr->fill(0.0f);
532  _data.reset(ptr);
533  }
534  STIRAcquisitionDataInFile(std::unique_ptr<stir::ProjData> uptr_pd) : _owns_file(true)
535  {
536 // auto *pd_ptr = dynamic_cast<stir::ProjDataInterfile*>(uptr_pd.get());
537  auto pd_ptr = dynamic_cast<stir::ProjDataInterfile*>(uptr_pd.get());
538  if (pd_ptr)
539  _data = std::move(uptr_pd);
540  else {
541  stir::ProjData& pd = *uptr_pd;
542  stir::shared_ptr<const stir::ExamInfo> sptr_exam_info =
543  pd.get_exam_info_sptr();
544  stir::shared_ptr<stir::ProjDataInfo> sptr_proj_data_info =
545  pd.get_proj_data_info_sptr()->create_shared_clone();
546  _data.reset(new ProjDataFile
547  (MAKE_SHARED<stir::ExamInfo>(*sptr_exam_info), sptr_proj_data_info,
548  _filename = SIRFUtilities::scratch_file_name()));
549  _data->fill(pd);
550  }
551  }
552  std::shared_ptr<STIRAcquisitionData> new_acquisition_data(std::string filename)
553  {
554  std::shared_ptr<STIRAcquisitionDataInFile> sptr_ad(new STIRAcquisitionDataInFile);
555  sptr_ad->_data.reset(new ProjDataFile(*data(), filename, false));
556  return sptr_ad;
557  }
558 
559  static void init() {
560  static bool initialized = false;
561  if (!initialized) {
562  _storage_scheme = "file";
563  _template.reset(new STIRAcquisitionDataInFile());
564  initialized = true;
565  STIRAcquisitionData::storage_scheme();
566  }
567  }
568  static void set_as_template()
569  {
570  init();
571  _storage_scheme = "file";
572  _template.reset(new STIRAcquisitionDataInFile);
573  }
574 
575  virtual STIRAcquisitionData* same_acquisition_data
576  (stir::shared_ptr<const stir::ExamInfo> sptr_exam_info,
577  stir::shared_ptr<stir::ProjDataInfo> sptr_proj_data_info) const
578  {
579  STIRAcquisitionData* ptr_ad =
580  new STIRAcquisitionDataInFile(sptr_exam_info, sptr_proj_data_info);
581  return ptr_ad;
582  }
583  virtual ObjectHandle<DataContainer>* new_data_container_handle() const
584  {
585  init();
586  DataContainer* ptr = _template->same_acquisition_data(
587  this->get_exam_info_sptr(),
588  this->get_proj_data_info_sptr()->create_shared_clone());
589  return new ObjectHandle<DataContainer>
590  (std::shared_ptr<DataContainer>(ptr));
591  }
592  virtual std::shared_ptr<STIRAcquisitionData> new_acquisition_data() const
593  {
594  init();
595  return std::shared_ptr < STIRAcquisitionData >
596  (_template->same_acquisition_data(this->get_exam_info_sptr(),
597  this->get_proj_data_info_sptr()->create_shared_clone()));
598  }
599  virtual std::unique_ptr<STIRAcquisitionData> get_subset(const std::vector<int>& views) const;
600 
601  private:
602  bool _owns_file;
603  std::string _filename;
604  virtual STIRAcquisitionDataInFile* clone_impl() const
605  {
606  init();
607  return (STIRAcquisitionDataInFile*)clone_base();
608  }
609  };
610 
618  public:
620  STIRAcquisitionDataInMemory(stir::shared_ptr<const stir::ExamInfo> sptr_exam_info,
621  stir::shared_ptr<const stir::ProjDataInfo> sptr_proj_data_info)
622  {
623  _data = stir::shared_ptr<stir::ProjData>
624  (new stir::ProjDataInMemory(SPTR_WRAP(sptr_exam_info), SPTR_WRAP(sptr_proj_data_info)));
625  }
626  STIRAcquisitionDataInMemory(const stir::ProjData& templ)
627  {
628  _data = stir::shared_ptr<stir::ProjData>
629  (new stir::ProjDataInMemory(templ.get_exam_info_sptr(),
630  templ.get_proj_data_info_sptr()->create_shared_clone()));
631  }
633  (stir::shared_ptr<stir::ExamInfo> sptr_ei, std::string scanner_name,
634  int span = 1, int max_ring_diff = -1, int view_mash_factor = 1)
635  {
636  stir::shared_ptr<stir::ProjDataInfo> sptr_pdi =
637  STIRAcquisitionData::proj_data_info_from_scanner
638  (scanner_name, span, max_ring_diff, view_mash_factor);
639  stir::ProjDataInMemory* ptr = new stir::ProjDataInMemory(sptr_ei, sptr_pdi);
640  ptr->fill(0.0f);
641  _data.reset(ptr);
642  }
643  STIRAcquisitionDataInMemory(std::unique_ptr<stir::ProjData> uptr_pd)
644  {
645 // auto *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(uptr_pd.get());
646  auto pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(uptr_pd.get());
647  if (pd_ptr)
648  _data = std::move(uptr_pd);
649  else {
650  std::cout << "copying ProjData to ProjDataInMemory...\n";
651  const stir::ProjData& pd = *uptr_pd;
652  auto exam_info_sptr = SPTR_WRAP(pd.get_exam_info_sptr());
653  auto proj_data_info_sptr =
654  SPTR_WRAP(pd.get_proj_data_info_sptr()->create_shared_clone());
655  _data.reset(new stir::ProjDataInMemory(exam_info_sptr, proj_data_info_sptr));
656  _data->fill(pd);
657  }
658  }
660  STIRAcquisitionDataInMemory(const char* filename)
661  {
662  auto pd_sptr = stir::ProjData::read_from_file(filename);
663  bool is_empty = false;
664  try {
665  pd_sptr->get_segment_by_sinogram(0);
666  }
667  catch (...) {
668  is_empty = true;
669  }
670  if (is_empty)
671  _data = stir::shared_ptr<stir::ProjData>
672  (new stir::ProjDataInMemory(pd_sptr->get_exam_info_sptr(),
673  pd_sptr->get_proj_data_info_sptr()->create_shared_clone()));
674  else
675  _data = stir::shared_ptr<stir::ProjData>
676  (new stir::ProjDataInMemory(*pd_sptr));
677  }
678 
679  static void init();
680 
681  static void set_as_template()
682  {
683  init();
684  _storage_scheme = "memory";
685  _template.reset(new STIRAcquisitionDataInMemory);
686  }
687 
688  virtual STIRAcquisitionData* same_acquisition_data
689  (stir::shared_ptr<const stir::ExamInfo> sptr_exam_info,
690  stir::shared_ptr<stir::ProjDataInfo> sptr_proj_data_info) const
691  {
692  STIRAcquisitionData* ptr_ad =
693  new STIRAcquisitionDataInMemory(sptr_exam_info, sptr_proj_data_info);
694  return ptr_ad;
695  }
696  virtual ObjectHandle<DataContainer>* new_data_container_handle() const
697  {
698  init();
699  DataContainer* ptr = _template->same_acquisition_data
700  (this->get_exam_info_sptr(),
701  this->get_proj_data_info_sptr()->create_shared_clone());
702  return new ObjectHandle<DataContainer>
703  (std::shared_ptr<DataContainer>(ptr));
704  }
705  virtual std::shared_ptr<STIRAcquisitionData> new_acquisition_data() const
706  {
707  init();
708  return std::shared_ptr < STIRAcquisitionData >
709  (_template->same_acquisition_data
710  (this->get_exam_info_sptr(),
711  this->get_proj_data_info_sptr()->create_shared_clone()));
712  }
713  virtual std::unique_ptr<STIRAcquisitionData> get_subset(const std::vector<int>& views) const;
714 
716  virtual void fill(const float v)
717  {
718  stir::ProjDataInMemory *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(data().get());
719  // If cast failed, fall back to general method
720  if (is_null_ptr(pd_ptr))
721  return this->STIRAcquisitionData::fill(v);
722 
723  // do it
724  auto iter = pd_ptr->begin();
725  while (iter != pd_ptr->end())
726  *iter++ = v;
727  }
729  virtual void fill(const STIRAcquisitionData& ad)
730  {
731  // Can only do this if both are STIRAcquisitionDataInMemory
732  stir::ProjDataInMemory *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(data().get());
733  const stir::ProjDataInMemory *pd2_ptr = dynamic_cast<const stir::ProjDataInMemory*>(ad.data().get());
734  // If either cast failed, fall back to general method
735  if (is_null_ptr(pd_ptr) || is_null_ptr(pd2_ptr))
736  return this->STIRAcquisitionData::fill(ad);
737 
738  // do it
739  auto iter = pd_ptr->begin();
740  auto iter_other = pd2_ptr->begin();
741  while (iter != pd_ptr->end())
742  *iter++ = *iter_other++;
743  }
745  virtual void fill_from(const float* d)
746  {
747  stir::ProjDataInMemory *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(data().get());
748  // If cast failed, fall back to general method
749  if (is_null_ptr(pd_ptr))
750  return this->STIRAcquisitionData::fill_from(d);
751 
752  // do it
753  auto iter = pd_ptr->begin();
754  while (iter != pd_ptr->end())
755  *iter++ = *d++;
756  }
758  virtual void copy_to(float* d) const
759  {
760  const stir::ProjDataInMemory *pd_ptr = dynamic_cast<const stir::ProjDataInMemory*>(data().get());
761  // If cast failed, fall back to general method
762  if (is_null_ptr(pd_ptr))
763  return this->STIRAcquisitionData::copy_to(d);
764 
765  // do it
766  auto iter = pd_ptr->begin();
767  while (iter != pd_ptr->end())
768  *d++ = *iter++;
769  }
770  virtual float norm() const
771  {
772  const stir::ProjDataInMemory *pd_ptr = dynamic_cast<const stir::ProjDataInMemory*>(data().get());
773  // If cast failed, fall back to general method
774  if (is_null_ptr(pd_ptr))
775  return this->STIRAcquisitionData::norm();
776 
777  // do it
778  double t = 0.0;
779  auto iter = pd_ptr->begin();
780  for (; iter != pd_ptr->end(); ++iter)
781  t += (*iter) * (*iter);
782  return std::sqrt((float)t);
783  }
784  virtual void dot(const DataContainer& a_x, void* ptr) const
785  {
786  auto x = dynamic_cast<const STIRAcquisitionData*>(&a_x);
787  // Can only do this if both are STIRAcquisitionDataInMemory
788  stir::ProjDataInMemory *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(data().get());
789  const stir::ProjDataInMemory *pd2_ptr = dynamic_cast<const stir::ProjDataInMemory*>(x->data().get());
790  // If either cast failed, fall back to general method
791  if (is_null_ptr(pd_ptr) || is_null_ptr(pd2_ptr))
792  return this->STIRAcquisitionData::dot(a_x,ptr);
793 
794  // do it
795  double t = 0.0;
796  auto iter = pd_ptr->begin();
797  auto iter_other = pd2_ptr->begin();
798  while (iter != pd_ptr->end())
799  t += (*iter++) * double(*iter_other++);
800 
801  float* ptr_t = static_cast<float*>(ptr);
802  *ptr_t = (float)t;
803  }
804  virtual void multiply(const DataContainer& x, const DataContainer& y)
805  {
806  auto a_x = dynamic_cast<const STIRAcquisitionData*>(&x);
807  auto a_y = dynamic_cast<const STIRAcquisitionData*>(&y);
808 
809  // Can only do this if all are STIRAcquisitionDataInMemory
810  auto *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(data().get());
811  auto *pd_x_ptr = dynamic_cast<const stir::ProjDataInMemory*>(a_x->data().get());
812  auto *pd_y_ptr = dynamic_cast<const stir::ProjDataInMemory*>(a_y->data().get());
813 
814  // If either cast failed, fall back to general method
815  if (is_null_ptr(pd_ptr) || is_null_ptr(pd_x_ptr) || is_null_ptr(pd_x_ptr))
816  return this->STIRAcquisitionData::multiply(x,y);
817 
818  // do it
819  auto iter = pd_ptr->begin();
820  auto iter_x = pd_x_ptr->begin();
821  auto iter_y = pd_y_ptr->begin();
822  while (iter != pd_ptr->end())
823  *iter++ = (*iter_x++) * (*iter_y++);
824  }
825  virtual void divide(const DataContainer& x, const DataContainer& y)
826  {
827  auto a_x = dynamic_cast<const STIRAcquisitionData*>(&x);
828  auto a_y = dynamic_cast<const STIRAcquisitionData*>(&y);
829 
830  // Can only do this if all are STIRAcquisitionDataInMemory
831  auto *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(data().get());
832  auto *pd_x_ptr = dynamic_cast<const stir::ProjDataInMemory*>(a_x->data().get());
833  auto *pd_y_ptr = dynamic_cast<const stir::ProjDataInMemory*>(a_y->data().get());
834 
835  // If either cast failed, fall back to general method
836  if (is_null_ptr(pd_ptr) || is_null_ptr(pd_x_ptr) || is_null_ptr(pd_x_ptr))
837  return this->STIRAcquisitionData::divide(x,y);
838 
839  // do it
840  auto iter = pd_ptr->begin();
841  auto iter_x = pd_x_ptr->begin();
842  auto iter_y = pd_y_ptr->begin();
843  while (iter != pd_ptr->end())
844  *iter++ = (*iter_x++) / (*iter_y++);
845  }
846 
847  private:
848  virtual STIRAcquisitionDataInMemory* clone_impl() const
849  {
850  init();
851  return (STIRAcquisitionDataInMemory*)clone_base();
852  }
853  };
854 
855 #if SIRF_VERSION_MAJOR < 4
862 #endif
863 
864  typedef Image3DF::full_iterator Image3DFIterator;
865  typedef Image3DF::const_full_iterator Image3DFIterator_const;
866 
875  class STIRImageData : public ImageData {
876  public:
879  class Iterator : public BaseIter {
880  public:
882 
883  typedef Image3DFIterator::difference_type difference_type;
884  typedef Image3DFIterator::value_type value_type;
885  typedef Image3DFIterator::reference reference;
886  typedef Image3DFIterator::pointer pointer;
887  typedef std::forward_iterator_tag iterator_category;
889  Iterator(const Image3DFIterator& iter) : _iter(iter)
890  {}
891  Iterator& operator=(const Iterator& iter)
892  {
893  _iter = iter._iter;
894  _ref.copy(iter._ref);
895  _sptr_iter = iter._sptr_iter;
896  return *this;
897  }
898  virtual Iterator& operator++()
899  {
900  ++_iter;
901  return *this;
902  }
903  //virtual Iterator& operator++(int)
904  //{
905  // _sptr_iter.reset(new Iterator(_iter));
906  // ++_iter;
907  // return *_sptr_iter;
908  //}
909  virtual bool operator==(const BaseIter& an_iter) const
910  {
911  const Iterator& iter = (const Iterator&)an_iter;
912  return _iter == iter._iter;
913  }
914  virtual bool operator!=(const BaseIter& an_iter) const
915  {
916  const Iterator& iter = (const Iterator&)an_iter;
917  return _iter != iter._iter;
918  }
919  virtual FloatRef& operator*()
920  {
921  float& v = *_iter;
922  _ref.set_ptr(&v);
923  return _ref;
924  }
925  private:
926  Image3DFIterator _iter;
927  FloatRef _ref;
928  std::shared_ptr<Iterator> _sptr_iter;
929  };
931  public:
932  Iterator_const(const Image3DFIterator_const& iter) : _iter(iter)
933  {}
934  Iterator_const& operator=(const Iterator_const& iter)
935  {
936  _iter = iter._iter;
937  _ref.copy(iter._ref);
938  _sptr_iter = iter._sptr_iter;
939  return *this;
940  }
941  virtual Iterator_const& operator++()
942  {
943  ++_iter;
944  return *this;
945  }
946  //virtual Iterator_const& operator++(int)
947  //{
948  // _sptr_iter.reset(new Iterator_const(_iter));
949  // ++_iter;
950  // return *_sptr_iter;
951  //}
952  virtual bool operator==(const BaseIter_const& an_iter) const
953  {
954  const Iterator_const& iter = (const Iterator_const&)an_iter;
955  return _iter == iter._iter;
956  }
957  virtual bool operator!=(const BaseIter_const& an_iter) const
958  {
959  const Iterator_const& iter = (const Iterator_const&)an_iter;
960  return _iter != iter._iter;
961  }
962  virtual const FloatRef& operator*() const
963  {
964  const float& v = *_iter;
965  _ref.set_ptr((void*)&v);
966  return _ref;
967  }
968  private:
969  Image3DFIterator_const _iter;
970  mutable FloatRef _ref;
971  std::shared_ptr<Iterator_const> _sptr_iter;
972  };
973  STIRImageData() {}
974  STIRImageData(const ImageData& id);
975  STIRImageData(const STIRImageData& image)
976  {
977  _data.reset(image.data().clone());
978  this->set_up_geom_info();
979  }
980  STIRImageData(const STIRAcquisitionData& ad)
981  {
982  _data.reset(new Voxels3DF(MAKE_SHARED<stir::ExamInfo>(*ad.get_exam_info_sptr()), *ad.get_proj_data_info_sptr()));
983  this->set_up_geom_info();
984  }
985  STIRImageData(const Image3DF& image)
986  {
987  _data.reset(image.clone());
988  this->set_up_geom_info();
989  }
990  STIRImageData(const Voxels3DF& v)
991  {
992  _data.reset(v.clone());
993  this->set_up_geom_info();
994  }
995  STIRImageData(const stir::ProjDataInfo& pdi)
996  {
997  _data.reset(new Voxels3DF(pdi));
998  this->set_up_geom_info();
999  }
1000  STIRImageData(stir::shared_ptr<Image3DF> ptr)
1001  {
1002  _data = ptr;
1003  this->set_up_geom_info();
1004  }
1005  STIRImageData(std::string filename)
1006  {
1007  _data = stir::read_from_file<Image3DF>(filename);
1008  this->set_up_geom_info();
1009  }
1010  STIRImageData* same_image_data() const
1011  {
1012  STIRImageData* ptr_image = new STIRImageData;
1013  ptr_image->_data.reset(_data->get_empty_copy());
1014  ptr_image->set_up_geom_info();
1015  return ptr_image;
1016  }
1017  std::shared_ptr<STIRImageData> new_image_data()
1018  {
1019  return std::shared_ptr<STIRImageData>(same_image_data());
1020  }
1021  virtual ObjectHandle<DataContainer>* new_data_container_handle() const
1022  {
1023  return new ObjectHandle<DataContainer>
1024  (std::shared_ptr<DataContainer>(same_image_data()));
1025  }
1026  virtual bool is_complex() const
1027  {
1028  return false;
1029  }
1030  unsigned int items() const
1031  {
1032  return 1;
1033  }
1034 
1035  std::string modality() const
1036  {
1037  ExamInfo ex_info = data().get_exam_info();
1038  return ex_info.imaging_modality.get_name();
1039  }
1040  void set_modality(const std::string& mod)
1041  {
1042  ExamInfo ex_info = data().get_exam_info();
1043  ex_info.imaging_modality = ImagingModality(mod);
1044  data().set_exam_info(ex_info);
1045  }
1046 
1048  virtual void write(const std::string& filename) const;
1050 
1069  virtual void write(const std::string& filename, const std::string& format_file) const;
1070 
1071  virtual float norm() const;
1073  virtual void sum(void* ptr) const;
1074  virtual void max(void* ptr) const;
1075  virtual void dot(const DataContainer& a_x, void* ptr) const;
1076  virtual void axpby(
1077  const void* ptr_a, const DataContainer& a_x,
1078  const void* ptr_b, const DataContainer& a_y);
1079  virtual void xapyb(
1080  const DataContainer& a_x, const void* ptr_a,
1081  const DataContainer& a_y, const void* ptr_b);
1082  virtual void xapyb(
1083  const DataContainer& a_x, const DataContainer& a_a,
1084  const DataContainer& a_y, const DataContainer& a_b);
1085  virtual void xapyb(
1086  const DataContainer& a_x, const void* ptr_a,
1087  const DataContainer& a_y, const DataContainer& a_b);
1088  virtual void abs(const DataContainer& x)
1089  {
1090  unary_op(x, std::abs);
1091  }
1092  virtual void exp(const DataContainer& x)
1093  {
1094  unary_op(x, std::exp);
1095  }
1096  virtual void log(const DataContainer& x)
1097  {
1098  unary_op(x, std::log);
1099  }
1100  virtual void sqrt(const DataContainer& x)
1101  {
1102  unary_op(x, std::sqrt);
1103  }
1104  virtual void sign(const DataContainer& x)
1105  {
1106  unary_op(x, DataContainer::sign);
1107  }
1108  virtual void multiply(const DataContainer& x, const void* ptr_y)
1109  {
1110  float y = *static_cast<const float*>(ptr_y);
1111  semibinary_op(x, y, DataContainer::product<float>);
1112  }
1113  virtual void add(const DataContainer& x, const void* ptr_y)
1114  {
1115  float y = *static_cast<const float*>(ptr_y);
1116  semibinary_op(x, y, DataContainer::sum<float>);
1117  }
1118  virtual void divide(const DataContainer& x, const void* ptr_y)
1119  {
1120  float y = *static_cast<const float*>(ptr_y);
1121  semibinary_op(x, y, DataContainer::ratio<float>);
1122  }
1123  virtual void maximum(const DataContainer& x, const void* ptr_y)
1124  {
1125  float y = *static_cast<const float*>(ptr_y);
1126  semibinary_op(x, y, DataContainer::maximum<float>);
1127  }
1128  virtual void minimum(const DataContainer& x, const void* ptr_y)
1129  {
1130  float y = *static_cast<const float*>(ptr_y);
1131  semibinary_op(x, y, DataContainer::minimum<float>);
1132  }
1133  virtual void power(const DataContainer& x, const void* ptr_y)
1134  {
1135  float y = *static_cast<const float*>(ptr_y);
1136  semibinary_op(x, y, std::pow);
1137  }
1138  virtual void multiply(const DataContainer& x, const DataContainer& y)
1139  {
1140  binary_op(x, y, DataContainer::product<float>);
1141  }
1142  virtual void divide(const DataContainer& x, const DataContainer& y)
1143  {
1144  binary_op(x, y, DataContainer::ratio<float>);
1145  }
1146  virtual void maximum(const DataContainer& x, const DataContainer& y)
1147  {
1148  binary_op(x, y, DataContainer::maximum<float>);
1149  }
1150  virtual void minimum(const DataContainer& x, const DataContainer& y)
1151  {
1152  binary_op(x, y, DataContainer::minimum<float>);
1153  }
1154  virtual void power(const DataContainer& x, const DataContainer& y)
1155  {
1156  binary_op(x, y, std::pow);
1157  }
1158 
1159  Image3DF& data()
1160  {
1161  return *_data;
1162  }
1163  const Image3DF& data() const
1164  {
1165  return *_data;
1166  }
1167  Image3DF* data_ptr()
1168  {
1169  return _data.get();
1170  }
1171  const Image3DF* data_ptr() const
1172  {
1173  return _data.get();
1174  }
1175  stir::shared_ptr<Image3DF> data_sptr()
1176  {
1177  return _data;
1178  }
1179  stir::shared_ptr<const Image3DF> data_sptr() const
1180  {
1181  return _data;
1182  }
1183  void set_data_sptr(stir::shared_ptr<Image3DF> sptr_data)
1184  {
1185  _data = sptr_data;
1186  }
1187 
1188  void fill(float v)
1189  {
1190  _data->fill(v);
1191  }
1192  void scale(float s);
1193  float dot(const DataContainer& a_x) const
1194  {
1195  float s;
1196  dot(a_x, &s);
1197  return s;
1198  }
1199  void axpby(
1200  float a, const DataContainer& a_x,
1201  float b, const DataContainer& a_y)
1202  {
1203  axpby(&a, a_x, &b, a_y);
1204  }
1205  void xapyb(
1206  const DataContainer& a_x, float a,
1207  const DataContainer& a_y, float b)
1208  {
1209  xapyb(a_x, &a, a_y, &b);
1210  }
1211  size_t size() const
1212  {
1213  return _data->size_all();
1214  }
1215  virtual Dimensions dimensions() const
1216  {
1217  Dimensions dim;
1218  int d[4];
1219  get_dimensions(d);
1220  dim["z"] = d[0];
1221  dim["y"] = d[1];
1222  dim["x"] = d[2];
1223  return dim;
1224  }
1225  int get_dimensions(int* dim) const;
1226  void get_voxel_sizes(float* vsizes) const;
1227  virtual void get_data(float* data) const;
1228  virtual void set_data(const float* data);
1229  virtual Iterator& begin()
1230  {
1231  _begin.reset(new Iterator(data().begin_all()));
1232  return *_begin;
1233  }
1234  virtual Iterator_const& begin() const
1235  {
1236  _begin_const.reset(new Iterator_const(data().begin_all()));
1237  return *_begin_const;
1238  }
1239  virtual Iterator& end()
1240  {
1241  _end.reset(new Iterator(data().end_all()));
1242  return *_end;
1243  }
1244  virtual Iterator_const& end() const
1245  {
1246  _end_const.reset(new Iterator_const(data().end_all()));
1247  return *_end_const;
1248  }
1249 
1251  std::unique_ptr<STIRImageData> clone() const
1252  {
1253  return std::unique_ptr<STIRImageData>(this->clone_impl());
1254  }
1255 
1259  void zoom_image(const Coord3DF& zooms = { 1.f,1.f,1.f }, const Coord3DF& offsets_in_mm = { 0.f,0.f,0.f },
1260  const Coord3DI& new_sizes = { -1,-1,-1 }, const char* const zoom_options_str = "preserve_sum");
1261 
1265  void zoom_image(const Coord3DF& zooms = { 1.f,1.f,1.f }, const Coord3DF& offsets_in_mm = { 0.f,0.f,0.f },
1266  const Coord3DI& new_sizes = { -1,-1,-1 },
1267  const stir::ZoomOptions zoom_options = stir::ZoomOptions::preserve_sum);
1268 
1271  void move_to_scanner_centre(const STIRAcquisitionData&);
1272 
1274  virtual void set_up_geom_info();
1275 
1276  void unary_op(const DataContainer& a_x, float(*f)(float));
1277  void semibinary_op(const DataContainer& a_x, float y, float(*f)(float, float));
1278  void binary_op(const DataContainer& a_x, const DataContainer& a_y, float(*f)(float, float));
1279 
1280  private:
1282  virtual STIRImageData* clone_impl() const
1283  {
1284  return new STIRImageData(*this);
1285  }
1286 
1287  protected:
1288  stir::shared_ptr<Image3DF> _data;
1289  mutable std::shared_ptr<Iterator> _begin;
1290  mutable std::shared_ptr<Iterator> _end;
1291  mutable std::shared_ptr<Iterator_const> _begin_const;
1292  mutable std::shared_ptr<Iterator_const> _end_const;
1293  };
1294 
1295 } // namespace sirf
1296 
1297 #endif
Execution status type and wrappers for C++ objects.
Definition: LocalisedException.h:32
Definition: DataHandle.h:159
Definition: DataContainer.h:42
virtual void sign(const DataContainer &x)=0
*this = the elementwise sign(x)
Definition: ANumRef.h:68
Definition: ImageData.h:52
Definition: ImageData.h:44
Definition: ImageData.h:38
STIR ProjDataInterfile wrapper with additional file managing features.
Definition: stir_data_containers.h:87
Definition: stir_data_containers.h:60
STIR ProjData wrapper with added functionality.
Definition: stir_data_containers.h:148
virtual void sum(void *ptr) const
below all void* are actually float*
Definition: stir_data_containers.cpp:59
virtual void sqrt(const DataContainer &x)
*this = the elementwise sqrt(x)
Definition: stir_data_containers.h:300
virtual void multiply(const DataContainer &x, const DataContainer &y)
*this = the elementwise product x*y
Definition: stir_data_containers.h:338
virtual void sign(const DataContainer &x)
*this = the elementwise sign(x)
Definition: stir_data_containers.h:304
virtual void xapyb(const DataContainer &a_x, const void *ptr_a, const DataContainer &a_y, const void *ptr_b)
alternative interface to the above
Definition: stir_data_containers.cpp:145
virtual float norm() const
returns the norm of this container viewed as a vector
Definition: stir_data_containers.cpp:46
virtual void axpby(const void *ptr_a, const DataContainer &a_x, const void *ptr_b, const DataContainer &a_y)
*this = the linear combination of x and y
Definition: stir_data_containers.cpp:135
int get_num_sinograms() const
total number of (2D) sinograms
Definition: stir_data_containers.h:378
virtual void dot(const DataContainer &a_x, void *ptr) const
calculates the dot product of this container with another one
Definition: stir_data_containers.cpp:103
virtual void add(const DataContainer &x, const void *ptr_y)
*this = the sum x + y with scalar y
Definition: stir_data_containers.h:313
virtual void divide(const DataContainer &x, const DataContainer &y)
*this = the elementwise ratio x / y
Definition: stir_data_containers.h:342
virtual void minimum(const DataContainer &x, const DataContainer &y)
*this = the elementwise min(x, y)
Definition: stir_data_containers.h:350
int get_num_non_TOF_sinograms() const
total number of (2D) sinograms ignoring time-of-flight
Definition: stir_data_containers.h:384
virtual void abs(const DataContainer &x)
*this = the elementwise abs(x)
Definition: stir_data_containers.h:288
virtual void max(void *ptr) const
calculates the value of this container's element with the largest real part
Definition: stir_data_containers.cpp:81
virtual void log(const DataContainer &x)
*this = the elementwise log(x)
Definition: stir_data_containers.h:296
virtual void maximum(const DataContainer &x, const DataContainer &y)
*this = the elementwise max(x, y)
Definition: stir_data_containers.h:346
virtual void exp(const DataContainer &x)
*this = the elementwise exp(x)
Definition: stir_data_containers.h:292
std::shared_ptr< STIRAcquisitionData > single_slice_rebinned_data(const int num_segments_to_combine, const int num_views_to_combine=1, const int num_tang_poss_to_trim=0, const bool do_normalisation=true, const int max_in_segment_num_to_process=-1, const int num_tof_bins_to_combine=1)
rebin the data to lower resolution by adding
Definition: stir_data_containers.h:180
virtual void multiply(const DataContainer &x, const void *ptr_y)
*this = the product x * y with scalar y
Definition: stir_data_containers.h:308
virtual void power(const DataContainer &x, const DataContainer &y)
*this = the elementwise pow(x, y)
Definition: stir_data_containers.h:354
In-file implementation of STIRAcquisitionData.
Definition: stir_data_containers.h:503
In-memory implementation of STIRAcquisitionData.
Definition: stir_data_containers.h:617
virtual void divide(const DataContainer &x, const DataContainer &y)
*this = the elementwise ratio x / y
Definition: stir_data_containers.h:825
virtual void dot(const DataContainer &a_x, void *ptr) const
calculates the dot product of this container with another one
Definition: stir_data_containers.h:784
STIRAcquisitionDataInMemory(const char *filename)
Constructor for STIRAcquisitionDataInMemory from filename.
Definition: stir_data_containers.h:660
virtual void fill_from(const float *d)
Fill from float array.
Definition: stir_data_containers.h:745
virtual void fill(const STIRAcquisitionData &ad)
fill from another STIRAcquisitionData
Definition: stir_data_containers.h:729
virtual float norm() const
returns the norm of this container viewed as a vector
Definition: stir_data_containers.h:770
virtual void multiply(const DataContainer &x, const DataContainer &y)
*this = the elementwise product x*y
Definition: stir_data_containers.h:804
virtual void fill(const float v)
fill with single value
Definition: stir_data_containers.h:716
virtual void copy_to(float *d) const
Copy to float array.
Definition: stir_data_containers.h:758
Definition: stir_data_containers.h:930
Definition: stir_data_containers.h:879
STIR DiscretisedDensity<3, float> wrapper with added functionality.
Definition: stir_data_containers.h:875
virtual void abs(const DataContainer &x)
*this = the elementwise abs(x)
Definition: stir_data_containers.h:1088
virtual void sqrt(const DataContainer &x)
*this = the elementwise sqrt(x)
Definition: stir_data_containers.h:1100
virtual void divide(const DataContainer &x, const DataContainer &y)
*this = the elementwise ratio x / y
Definition: stir_data_containers.h:1142
virtual void max(void *ptr) const
calculates the value of this container's element with the largest real part
Definition: stir_data_containers.cpp:478
virtual void multiply(const DataContainer &x, const DataContainer &y)
*this = the elementwise product x*y
Definition: stir_data_containers.h:1138
virtual void dot(const DataContainer &a_x, void *ptr) const
calculates the dot product of this container with another one
Definition: stir_data_containers.cpp:494
virtual void set_up_geom_info()
Populate the geometrical info metadata (from the image's own metadata)
Definition: stir_data_containers.cpp:841
void zoom_image(const Coord3DF &zooms={ 1.f, 1.f, 1.f }, const Coord3DF &offsets_in_mm={ 0.f, 0.f, 0.f }, const Coord3DI &new_sizes={ -1,-1,-1 }, const char *const zoom_options_str="preserve_sum")
Definition: stir_data_containers.cpp:788
virtual float norm() const
returns the norm of this container viewed as a vector
Definition: stir_data_containers.cpp:623
std::unique_ptr< STIRImageData > clone() const
Clone and return as unique pointer.
Definition: stir_data_containers.h:1251
virtual void maximum(const DataContainer &x, const DataContainer &y)
*this = the elementwise max(x, y)
Definition: stir_data_containers.h:1146
virtual void axpby(const void *ptr_a, const DataContainer &a_x, const void *ptr_b, const DataContainer &a_y)
*this = the linear combination of x and y
Definition: stir_data_containers.cpp:517
virtual bool is_complex() const
Is complex? Unless overwridden (Gadgetron), assume not complex.
Definition: stir_data_containers.h:1026
virtual void sum(void *ptr) const
below all void* are actually float*
Definition: stir_data_containers.cpp:462
virtual void log(const DataContainer &x)
*this = the elementwise log(x)
Definition: stir_data_containers.h:1096
void move_to_scanner_centre(const STIRAcquisitionData &)
Definition: stir_data_containers.cpp:832
virtual void sign(const DataContainer &x)
*this = the elementwise sign(x)
Definition: stir_data_containers.h:1104
virtual void write(const std::string &filename) const
Write to file.
Definition: stir_data_containers.cpp:430
virtual void xapyb(const DataContainer &a_x, const void *ptr_a, const DataContainer &a_y, const void *ptr_b)
alternative interface to the above
Definition: stir_data_containers.cpp:526
virtual void minimum(const DataContainer &x, const DataContainer &y)
*this = the elementwise min(x, y)
Definition: stir_data_containers.h:1150
virtual void add(const DataContainer &x, const void *ptr_y)
*this = the sum x + y with scalar y
Definition: stir_data_containers.h:1113
virtual void power(const DataContainer &x, const DataContainer &y)
*this = the elementwise pow(x, y)
Definition: stir_data_containers.h:1154
virtual void exp(const DataContainer &x)
*this = the elementwise exp(x)
Definition: stir_data_containers.h:1092
virtual void multiply(const DataContainer &x, const void *ptr_y)
*this = the product x * y with scalar y
Definition: stir_data_containers.h:1108
Defines sirf::iequals.
Abstract data container.
Definition: GeometricalInfo.cpp:141
STIRAcquisitionData PETAcquisitionData
Definition: stir_data_containers.h:859
bool iequals(const std::string &a, const std::string &b)
Case insensitive string comparison, replaces boost::iequals.
Definition: iequals.cpp:7
void err(const std::string &message)
throw error
Definition: sirf_convert_image_type.cpp:115