SIRF  3.8.0
stir_data_containers.h
Go to the documentation of this file.
1 /*
2 SyneRBI Synergistic Image Reconstruction Framework (SIRF)
3 Copyright 2015 - 2023 Rutherford Appleton Laboratory STFC
4 Copyright 2018 - 2024 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 
138 #if 0
139  // not used yet. See also https://github.com/SyneRBI/SIRF/pull/1103
144  class STIRScanData: public virtual ContainerBase {
145  public:
146  virtual ~STIRScanData() {}
147  virtual stir::shared_ptr<stir::ExamData> data_sptr() const = 0;
148  //virtual void set_data_sptr(stir::shared_ptr<stir::ExamData> data) = 0;
149  };
150 #endif
161  class STIRAcquisitionData : /*public STIRScanData, */public DataContainer {
162  public:
163 
164  // virtual constructors
165  virtual STIRAcquisitionData* same_acquisition_data
166  (stir::shared_ptr<const stir::ExamInfo> sptr_exam_info,
167  stir::shared_ptr<stir::ProjDataInfo> sptr_proj_data_info) const = 0;
168  virtual std::shared_ptr<STIRAcquisitionData> new_acquisition_data() const = 0;
169 
170  std::string get_info() const
171  {
172  return this->data()->get_exam_info_sptr()->parameter_info() +
173  this->data()->get_proj_data_info_sptr()->parameter_info();
174  }
175 
176  virtual bool is_complex() const
177  {
178  return false;
179  }
180 
181  virtual std::unique_ptr<STIRAcquisitionData> get_subset(const std::vector<int>& views) const = 0;
182 
184 
198  std::shared_ptr<STIRAcquisitionData> single_slice_rebinned_data(
199  const int num_segments_to_combine,
200  const int num_views_to_combine = 1,
201  const int num_tang_poss_to_trim = 0,
202  const bool do_normalisation = true,
203  const int max_in_segment_num_to_process = -1,
204  const int num_tof_bins_to_combine = 1
205  )
206  {
207  stir::shared_ptr<stir::ProjDataInfo> out_proj_data_info_sptr(
208  stir::SSRB(*data()->get_proj_data_info_sptr(),
209  num_segments_to_combine,
210  num_views_to_combine,
211  num_tang_poss_to_trim,
212  max_in_segment_num_to_process,
213  num_tof_bins_to_combine
214  ));
215  std::shared_ptr<STIRAcquisitionData>
216  sptr(same_acquisition_data
217  (this->get_exam_info_sptr(), out_proj_data_info_sptr));
218  stir::SSRB(*sptr, *data(), do_normalisation);
219  return sptr;
220  }
221 
222  static std::string storage_scheme()
223  {
224  static bool initialized = false;
225  if (!initialized) {
226  _storage_scheme = "file";
227  initialized = true;
228  }
229  return _storage_scheme;
230  }
231  static std::shared_ptr<STIRAcquisitionData> storage_template()
232  {
233  if (!_template)
234  error("storage_template error. You probably need to call set_storage_scheme() first");
235  return _template;
236  }
237 
238  stir::shared_ptr<stir::ProjData> data()
239  {
240  return _data;
241  }
242 /* virtual stir::shared_ptr<stir::ExamData> data_sptr()
243  {
244  return _data;
245  //return stir::shared_ptr<stir::ExamData>(_data);
246  }*/
247  const stir::shared_ptr<stir::ProjData> data() const
248  //stir::shared_ptr<const stir::ProjData> data() const // causes lots of problems
249  {
250  return _data;
251  }
252  #if 1
253  virtual stir::shared_ptr<stir::ExamData> data_sptr() const
254  {
255  return _data;
256  }
257  #endif
258  void set_data(stir::shared_ptr<stir::ProjData> data)
259  {
260  _data = data;
261  }
262 
263  // data import/export
264  virtual void fill(const float v) { data()->fill(v); }
265  virtual void fill(const STIRAcquisitionData& ad)
266  {
267  if (ad.is_empty())
268  THROW("The source of STIRAcquisitionData::fill is empty");
269  stir::shared_ptr<const stir::ProjData> sptr = ad.data();
270  data()->fill(*sptr);
271  }
272  virtual void fill_from(const float* d) { data()->fill_from(d); }
273  virtual void copy_to(float* d) const { data()->copy_to(d); }
274  std::unique_ptr<STIRAcquisitionData> clone() const
275  {
276  return std::unique_ptr<STIRAcquisitionData>(clone_impl());
277  }
278 
279  // data container methods
280  unsigned int items() const {
281  if (_is_empty != -1)
282  return _is_empty ? 0 : 1;
283  try {
284 #ifdef STIR_TOF
285  get_segment_by_sinogram(0,0);
286 #else
287  get_segment_by_sinogram(0);
288 #endif
289  }
290  catch (...) {
291  _is_empty = 1;
292  return 0; // no data found - this must be a template
293  }
294  _is_empty = 0;
295  return 1; // data ok
296  }
297  virtual float norm() const;
299  virtual void sum(void* ptr) const;
300  virtual void max(void* ptr) const;
301  virtual void min(void* ptr) const;
302  virtual void dot(const DataContainer& a_x, void* ptr) const;
303  float dot(const DataContainer& a_x) const
304  {
305  float s;
306  dot(a_x, &s);
307  return s;
308  }
309  virtual void axpby(
310  const void* ptr_a, const DataContainer& a_x,
311  const void* ptr_b, const DataContainer& a_y);
312  virtual void xapyb(
313  const DataContainer& a_x, const void* ptr_a,
314  const DataContainer& a_y, const void* ptr_b);
315  virtual void xapyb(
316  const DataContainer& a_x, const DataContainer& a_a,
317  const DataContainer& a_y, const DataContainer& a_b);
318  virtual void xapyb(
319  const DataContainer& a_x, const void* ptr_a,
320  const DataContainer& a_y, const DataContainer& a_b);
321  virtual void abs(const DataContainer& x)
322  {
323  unary_op(x, std::abs);
324  }
325  virtual void exp(const DataContainer& x)
326  {
327  unary_op(x, std::exp);
328  }
329  virtual void log(const DataContainer& x)
330  {
331  unary_op(x, std::log);
332  }
333  virtual void sqrt(const DataContainer& x)
334  {
335  unary_op(x, std::sqrt);
336  }
337  virtual void sign(const DataContainer& x)
338  {
339  unary_op(x, DataContainer::sign);
340  }
341  virtual void multiply(const DataContainer& x, const void* ptr_y)
342  {
343  float y = *static_cast<const float*>(ptr_y);
344  semibinary_op(x, y, DataContainer::product<float>);
345  }
346  virtual void add(const DataContainer& x, const void* ptr_y)
347  {
348  float y = *static_cast<const float*>(ptr_y);
349  semibinary_op(x, y, DataContainer::sum<float>);
350  }
351  virtual void divide(const DataContainer& x, const void* ptr_y)
352  {
353  float y = *static_cast<const float*>(ptr_y);
354  semibinary_op(x, y, DataContainer::ratio<float>);
355  }
356  virtual void maximum(const DataContainer& x, const void* ptr_y)
357  {
358  float y = *static_cast<const float*>(ptr_y);
359  semibinary_op(x, y, DataContainer::maximum<float>);
360  }
361  virtual void minimum(const DataContainer& x, const void* ptr_y)
362  {
363  float y = *static_cast<const float*>(ptr_y);
364  semibinary_op(x, y, DataContainer::minimum<float>);
365  }
366  virtual void power(const DataContainer& x, const void* ptr_y)
367  {
368  float y = *static_cast<const float*>(ptr_y);
369  semibinary_op(x, y, std::pow);
370  }
371  virtual void multiply(const DataContainer& x, const DataContainer& y)
372  {
373  binary_op(x, y, DataContainer::product<float>);
374  }
375  virtual void divide(const DataContainer& x, const DataContainer& y)
376  {
377  binary_op(x, y, DataContainer::ratio<float>);
378  }
379  virtual void maximum(const DataContainer& x, const DataContainer& y)
380  {
381  binary_op(x, y, DataContainer::maximum<float>);
382  }
383  virtual void minimum(const DataContainer& x, const DataContainer& y)
384  {
385  binary_op(x, y, DataContainer::minimum<float>);
386  }
387  virtual void power(const DataContainer& x, const DataContainer& y)
388  {
389  binary_op(x, y, std::pow);
390  }
391  virtual void inv(float a, const DataContainer& x);
392  virtual void write(const std::string &filename) const
393  {
394  ProjDataFile pd(*data(), filename.c_str(), false);
395  pd.fill(*data());
396  }
397 
398  // ProjData methods
399  int get_num_tangential_poss()
400  {
401  return data()->get_num_tangential_poss();
402  }
403  int get_num_views()
404  {
405  return data()->get_num_views();
406  }
408 
411  int get_num_sinograms() const
412  {
413  return data()->get_num_sinograms();
414  }
416 
418  {
419  return data()->get_num_non_tof_sinograms();
420  }
421 
422  int get_num_TOF_bins()
423  {
424  return data()->get_num_tof_poss();
425  }
426 
427  int get_tof_mash_factor() const
428  {
429  return data()->get_proj_data_info_sptr()->get_tof_mash_factor();
430  }
431 
432  size_t get_dimensions(int* dim)
433  {
434  dim[0] = get_num_tangential_poss();
435  dim[1] = get_num_views();
436  dim[2] = get_num_non_TOF_sinograms();
437  dim[3] = get_num_TOF_bins();
438  return static_cast<size_t>(dim[0] * dim[1] * dim[2] * dim[3]);
439  }
440  int get_max_segment_num() const
441  {
442  return data()->get_max_segment_num();
443  }
444 #ifdef STIR_TOF
445  stir::SegmentBySinogram<float>
446  get_segment_by_sinogram(const int segment_num, const int timing_pos_num) const
447  {
448  return data()->get_segment_by_sinogram(segment_num, timing_pos_num);
449  }
450 #else
451  stir::SegmentBySinogram<float>
452  get_segment_by_sinogram(const int segment_num) const
453  {
454  return data()->get_segment_by_sinogram(segment_num);
455  }
456 #endif
457 #ifdef STIR_TOF
458  stir::SegmentBySinogram<float>
459  get_empty_segment_by_sinogram(const int segment_num, const int timing_pos_num) const
460  {
461  return data()->get_empty_segment_by_sinogram(segment_num, false, timing_pos_num);
462  }
463 #else
464  stir::SegmentBySinogram<float>
465  get_empty_segment_by_sinogram(const int segment_num) const
466  {
467  return data()->get_empty_segment_by_sinogram(segment_num);
468  }
469 #endif
470  void set_segment(const stir::SegmentBySinogram<float>& s)
471  {
472  if (data()->set_segment(s) != stir::Succeeded::yes)
473  THROW("stir::ProjData set segment failed");
474  }
475  stir::shared_ptr<const stir::ExamInfo> get_exam_info_sptr() const
476  {
477  return data()->get_exam_info_sptr();
478  }
479  stir::shared_ptr<const stir::ProjDataInfo> get_proj_data_info_sptr() const
480  {
481  return data()->get_proj_data_info_sptr();
482  }
483  std::string modality() const
484  {
485  const ExamInfo& ex_info = *get_exam_info_sptr();
486  return ex_info.imaging_modality.get_name();
487  }
488 
489  // ProjData casts
490  operator stir::ProjData&() { return *data(); }
491  operator const stir::ProjData&() const { return *data(); }
492  operator stir::shared_ptr<stir::ProjData>() { return data(); }
493 
494  static stir::shared_ptr<stir::ProjDataInfo>
495  proj_data_info_from_scanner(std::string scanner_name,
496  int span = 1, int max_ring_diff = -1, int view_mash_factor = 1)
497  {
498  stir::shared_ptr<stir::Scanner>
499  sptr_s(stir::Scanner::get_scanner_from_name(scanner_name));
500  //std::cout << "scanner: " << sptr_s->get_name().c_str() << '\n';
501  if (sirf::iequals(sptr_s->get_name(), "unknown")) {
502  throw LocalisedException("Unknown scanner", __FILE__, __LINE__);
503  }
504  int num_views = sptr_s->get_num_detectors_per_ring() / 2 / view_mash_factor;
505  int num_tang_pos = sptr_s->get_max_num_non_arccorrected_bins();
506  if (max_ring_diff < 0)
507  max_ring_diff = sptr_s->get_num_rings() - 1;
508  return std::move(stir::ProjDataInfo::construct_proj_data_info
509  (sptr_s, span, max_ring_diff, num_views, num_tang_pos, false));
510  }
511 
512  void unary_op(const DataContainer& a_x, float(*f)(float));
513  void semibinary_op(const DataContainer& a_x, float y, float(*f)(float, float));
514  void binary_op(const DataContainer& a_x, const DataContainer& a_y, float(*f)(float, float));
515 
516  protected:
517  static std::string _storage_scheme;
518  static std::shared_ptr<STIRAcquisitionData> _template;
519  stir::shared_ptr<stir::ProjData> _data;
520  virtual STIRAcquisitionData* clone_impl() const = 0;
521  STIRAcquisitionData* clone_base() const
522  {
523  stir::shared_ptr<stir::ProjDataInfo> sptr_pdi = this->get_proj_data_info_sptr()->create_shared_clone();
524  STIRAcquisitionData* ptr =
525  _template->same_acquisition_data(this->get_exam_info_sptr(), sptr_pdi);
526  if (!this->is_empty())
527  ptr->fill(*this);
528  return ptr;
529  }
530 
531  private:
532  mutable int _is_empty = -1;
533  };
534 
542  public:
543  STIRAcquisitionDataInFile() : _owns_file(false) {}
544  STIRAcquisitionDataInFile(const char* filename) : _owns_file(false)
545  {
546  _data = stir::ProjData::read_from_file(filename);
547  }
548  STIRAcquisitionDataInFile(stir::shared_ptr<const stir::ExamInfo> sptr_exam_info,
549  stir::shared_ptr<stir::ProjDataInfo> sptr_proj_data_info)
550  {
551  _data.reset(new ProjDataFile
552  (MAKE_SHARED<stir::ExamInfo>(*sptr_exam_info), sptr_proj_data_info,
553  _filename = SIRFUtilities::scratch_file_name()));
554  }
555  STIRAcquisitionDataInFile(const stir::ProjData& pd) : _owns_file(true)
556  {
557  _data.reset(new ProjDataFile
558  (pd, _filename = SIRFUtilities::scratch_file_name()));
559  }
561  (stir::shared_ptr<stir::ExamInfo> sptr_ei, std::string scanner_name,
562  int span = 1, int max_ring_diff = -1, int view_mash_factor = 1)
563  {
564  stir::shared_ptr<stir::ProjDataInfo> sptr_pdi =
565  STIRAcquisitionData::proj_data_info_from_scanner
566  (scanner_name, span, max_ring_diff, view_mash_factor);
567  ProjDataFile* ptr = new ProjDataFile(sptr_ei, sptr_pdi,
568  _filename = SIRFUtilities::scratch_file_name());
569  ptr->fill(0.0f);
570  _data.reset(ptr);
571  }
572  STIRAcquisitionDataInFile(std::unique_ptr<stir::ProjData> uptr_pd) : _owns_file(true)
573  {
574 // auto *pd_ptr = dynamic_cast<stir::ProjDataInterfile*>(uptr_pd.get());
575  auto pd_ptr = dynamic_cast<stir::ProjDataInterfile*>(uptr_pd.get());
576  if (pd_ptr)
577  _data = std::move(uptr_pd);
578  else {
579  stir::ProjData& pd = *uptr_pd;
580  stir::shared_ptr<const stir::ExamInfo> sptr_exam_info =
581  pd.get_exam_info_sptr();
582  stir::shared_ptr<stir::ProjDataInfo> sptr_proj_data_info =
583  pd.get_proj_data_info_sptr()->create_shared_clone();
584  _data.reset(new ProjDataFile
585  (MAKE_SHARED<stir::ExamInfo>(*sptr_exam_info), sptr_proj_data_info,
586  _filename = SIRFUtilities::scratch_file_name()));
587  _data->fill(pd);
588  }
589  }
590  std::shared_ptr<STIRAcquisitionData> new_acquisition_data(std::string filename)
591  {
592  std::shared_ptr<STIRAcquisitionDataInFile> sptr_ad(new STIRAcquisitionDataInFile);
593  sptr_ad->_data.reset(new ProjDataFile(*data(), filename, false));
594  return sptr_ad;
595  }
596 
597  static void init() {
598  static bool initialized = false;
599  if (!initialized) {
600  _storage_scheme = "file";
601  _template.reset(new STIRAcquisitionDataInFile());
602  initialized = true;
603  STIRAcquisitionData::storage_scheme();
604  }
605  }
606  static void set_as_template()
607  {
608  init();
609  _storage_scheme = "file";
610  _template.reset(new STIRAcquisitionDataInFile);
611  }
612 
613  virtual STIRAcquisitionData* same_acquisition_data
614  (stir::shared_ptr<const stir::ExamInfo> sptr_exam_info,
615  stir::shared_ptr<stir::ProjDataInfo> sptr_proj_data_info) const
616  {
617  STIRAcquisitionData* ptr_ad =
618  new STIRAcquisitionDataInFile(sptr_exam_info, sptr_proj_data_info);
619  return ptr_ad;
620  }
621  virtual ObjectHandle<DataContainer>* new_data_container_handle() const
622  {
623  init();
624  DataContainer* ptr = _template->same_acquisition_data(
625  this->get_exam_info_sptr(),
626  this->get_proj_data_info_sptr()->create_shared_clone());
627  return new ObjectHandle<DataContainer>
628  (std::shared_ptr<DataContainer>(ptr));
629  }
630  virtual std::shared_ptr<STIRAcquisitionData> new_acquisition_data() const
631  {
632  init();
633  return std::shared_ptr < STIRAcquisitionData >
634  (_template->same_acquisition_data(this->get_exam_info_sptr(),
635  this->get_proj_data_info_sptr()->create_shared_clone()));
636  }
637  virtual std::unique_ptr<STIRAcquisitionData> get_subset(const std::vector<int>& views) const;
638 
639  private:
640  bool _owns_file;
641  std::string _filename;
642  virtual STIRAcquisitionDataInFile* clone_impl() const
643  {
644  init();
645  return (STIRAcquisitionDataInFile*)clone_base();
646  }
647  };
648 
656  public:
658  STIRAcquisitionDataInMemory(stir::shared_ptr<const stir::ExamInfo> sptr_exam_info,
659  stir::shared_ptr<const stir::ProjDataInfo> sptr_proj_data_info)
660  {
661  _data = stir::shared_ptr<stir::ProjData>
662  (new stir::ProjDataInMemory(SPTR_WRAP(sptr_exam_info), SPTR_WRAP(sptr_proj_data_info)));
663  }
664  STIRAcquisitionDataInMemory(const stir::ProjData& templ)
665  {
666  _data = stir::shared_ptr<stir::ProjData>
667  (new stir::ProjDataInMemory(templ.get_exam_info_sptr(),
668  templ.get_proj_data_info_sptr()->create_shared_clone()));
669  }
671  (stir::shared_ptr<stir::ExamInfo> sptr_ei, std::string scanner_name,
672  int span = 1, int max_ring_diff = -1, int view_mash_factor = 1)
673  {
674  stir::shared_ptr<stir::ProjDataInfo> sptr_pdi =
675  STIRAcquisitionData::proj_data_info_from_scanner
676  (scanner_name, span, max_ring_diff, view_mash_factor);
677  stir::ProjDataInMemory* ptr = new stir::ProjDataInMemory(sptr_ei, sptr_pdi);
678  ptr->fill(0.0f);
679  _data.reset(ptr);
680  }
681  STIRAcquisitionDataInMemory(std::unique_ptr<stir::ProjData> uptr_pd)
682  {
683 // auto *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(uptr_pd.get());
684  auto pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(uptr_pd.get());
685  if (pd_ptr)
686  _data = std::move(uptr_pd);
687  else {
688  std::cout << "copying ProjData to ProjDataInMemory...\n";
689  const stir::ProjData& pd = *uptr_pd;
690  auto exam_info_sptr = SPTR_WRAP(pd.get_exam_info_sptr());
691  auto proj_data_info_sptr =
692  SPTR_WRAP(pd.get_proj_data_info_sptr()->create_shared_clone());
693  _data.reset(new stir::ProjDataInMemory(exam_info_sptr, proj_data_info_sptr));
694  _data->fill(pd);
695  }
696  }
698  STIRAcquisitionDataInMemory(const char* filename)
699  {
700  auto pd_sptr = stir::ProjData::read_from_file(filename);
701  bool is_empty = false;
702  try {
703  pd_sptr->get_segment_by_sinogram(0);
704  }
705  catch (...) {
706  is_empty = true;
707  }
708  if (is_empty)
709  _data = stir::shared_ptr<stir::ProjData>
710  (new stir::ProjDataInMemory(pd_sptr->get_exam_info_sptr(),
711  pd_sptr->get_proj_data_info_sptr()->create_shared_clone()));
712  else
713  _data = stir::shared_ptr<stir::ProjData>
714  (new stir::ProjDataInMemory(*pd_sptr));
715  }
716 
717  static void init();
718 
719  static void set_as_template()
720  {
721  init();
722  _storage_scheme = "memory";
723  _template.reset(new STIRAcquisitionDataInMemory);
724  }
725 
726  virtual STIRAcquisitionData* same_acquisition_data
727  (stir::shared_ptr<const stir::ExamInfo> sptr_exam_info,
728  stir::shared_ptr<stir::ProjDataInfo> sptr_proj_data_info) const
729  {
730  STIRAcquisitionData* ptr_ad =
731  new STIRAcquisitionDataInMemory(sptr_exam_info, sptr_proj_data_info);
732  return ptr_ad;
733  }
734  virtual ObjectHandle<DataContainer>* new_data_container_handle() const
735  {
736  init();
737  DataContainer* ptr = _template->same_acquisition_data
738  (this->get_exam_info_sptr(),
739  this->get_proj_data_info_sptr()->create_shared_clone());
740  return new ObjectHandle<DataContainer>
741  (std::shared_ptr<DataContainer>(ptr));
742  }
743  virtual std::shared_ptr<STIRAcquisitionData> new_acquisition_data() const
744  {
745  init();
746  return std::shared_ptr < STIRAcquisitionData >
747  (_template->same_acquisition_data
748  (this->get_exam_info_sptr(),
749  this->get_proj_data_info_sptr()->create_shared_clone()));
750  }
751  virtual std::unique_ptr<STIRAcquisitionData> get_subset(const std::vector<int>& views) const;
752 
754  virtual void fill(const float v)
755  {
756  stir::ProjDataInMemory *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(data().get());
757  // If cast failed, fall back to general method
758  if (is_null_ptr(pd_ptr))
759  return this->STIRAcquisitionData::fill(v);
760 
761  // do it
762  auto iter = pd_ptr->begin();
763  while (iter != pd_ptr->end())
764  *iter++ = v;
765  }
767  virtual void fill(const STIRAcquisitionData& ad)
768  {
769  // Can only do this if both are STIRAcquisitionDataInMemory
770  stir::ProjDataInMemory *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(data().get());
771  const stir::ProjDataInMemory *pd2_ptr = dynamic_cast<const stir::ProjDataInMemory*>(ad.data().get());
772  // If either cast failed, fall back to general method
773  if (is_null_ptr(pd_ptr) || is_null_ptr(pd2_ptr))
774  return this->STIRAcquisitionData::fill(ad);
775 
776  // do it
777  auto iter = pd_ptr->begin();
778  auto iter_other = pd2_ptr->begin();
779  while (iter != pd_ptr->end())
780  *iter++ = *iter_other++;
781  }
783  virtual void fill_from(const float* d)
784  {
785  stir::ProjDataInMemory *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(data().get());
786  // If cast failed, fall back to general method
787  if (is_null_ptr(pd_ptr))
788  return this->STIRAcquisitionData::fill_from(d);
789 
790  // do it
791  auto iter = pd_ptr->begin();
792  while (iter != pd_ptr->end())
793  *iter++ = *d++;
794  }
796  virtual void copy_to(float* d) const
797  {
798  const stir::ProjDataInMemory *pd_ptr = dynamic_cast<const stir::ProjDataInMemory*>(data().get());
799  // If cast failed, fall back to general method
800  if (is_null_ptr(pd_ptr))
801  return this->STIRAcquisitionData::copy_to(d);
802 
803  // do it
804  auto iter = pd_ptr->begin();
805  while (iter != pd_ptr->end())
806  *d++ = *iter++;
807  }
808  virtual float norm() const
809  {
810  const stir::ProjDataInMemory *pd_ptr = dynamic_cast<const stir::ProjDataInMemory*>(data().get());
811  // If cast failed, fall back to general method
812  if (is_null_ptr(pd_ptr))
813  return this->STIRAcquisitionData::norm();
814 
815  // do it
816 #if STIR_VERSION <= 060100
817  double t = 0.0;
818  auto iter = pd_ptr->begin();
819  for (; iter != pd_ptr->end(); ++iter)
820  t += (*iter) * (*iter);
821  return std::sqrt((float)t);
822 #else
823  return static_cast<float>(pd_ptr->norm());
824 #endif
825  }
826  virtual void dot(const DataContainer& a_x, void* ptr) const
827  {
828  auto x = dynamic_cast<const STIRAcquisitionData*>(&a_x);
829  // Can only do this if both are STIRAcquisitionDataInMemory
830  stir::ProjDataInMemory *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(data().get());
831  const stir::ProjDataInMemory *pd2_ptr = dynamic_cast<const stir::ProjDataInMemory*>(x->data().get());
832  // If either cast failed, fall back to general method
833  if (is_null_ptr(pd_ptr) || is_null_ptr(pd2_ptr))
834  return this->STIRAcquisitionData::dot(a_x,ptr);
835 
836  // do it
837  double t = 0.0;
838  auto iter = pd_ptr->begin();
839  auto iter_other = pd2_ptr->begin();
840  while (iter != pd_ptr->end())
841  t += (*iter++) * double(*iter_other++);
842 
843  float* ptr_t = static_cast<float*>(ptr);
844  *ptr_t = (float)t;
845  }
846  virtual void multiply(const DataContainer& x, const DataContainer& y)
847  {
848  auto a_x = dynamic_cast<const STIRAcquisitionData*>(&x);
849  auto a_y = dynamic_cast<const STIRAcquisitionData*>(&y);
850 
851  // Can only do this if all are STIRAcquisitionDataInMemory
852  auto *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(data().get());
853  auto *pd_x_ptr = dynamic_cast<const stir::ProjDataInMemory*>(a_x->data().get());
854  auto *pd_y_ptr = dynamic_cast<const stir::ProjDataInMemory*>(a_y->data().get());
855 
856  // If either cast failed, fall back to general method
857  if (is_null_ptr(pd_ptr) || is_null_ptr(pd_x_ptr) || is_null_ptr(pd_x_ptr))
858  return this->STIRAcquisitionData::multiply(x,y);
859 
860  // do it
861  auto iter = pd_ptr->begin();
862  auto iter_x = pd_x_ptr->begin();
863  auto iter_y = pd_y_ptr->begin();
864  while (iter != pd_ptr->end())
865  *iter++ = (*iter_x++) * (*iter_y++);
866  }
867  virtual void divide(const DataContainer& x, const DataContainer& y)
868  {
869  auto a_x = dynamic_cast<const STIRAcquisitionData*>(&x);
870  auto a_y = dynamic_cast<const STIRAcquisitionData*>(&y);
871 
872  // Can only do this if all are STIRAcquisitionDataInMemory
873  auto *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(data().get());
874  auto *pd_x_ptr = dynamic_cast<const stir::ProjDataInMemory*>(a_x->data().get());
875  auto *pd_y_ptr = dynamic_cast<const stir::ProjDataInMemory*>(a_y->data().get());
876 
877  // If either cast failed, fall back to general method
878  if (is_null_ptr(pd_ptr) || is_null_ptr(pd_x_ptr) || is_null_ptr(pd_x_ptr))
879  return this->STIRAcquisitionData::divide(x,y);
880 
881  // do it
882  auto iter = pd_ptr->begin();
883  auto iter_x = pd_x_ptr->begin();
884  auto iter_y = pd_y_ptr->begin();
885  while (iter != pd_ptr->end())
886  *iter++ = (*iter_x++) / (*iter_y++);
887  }
888 
889  private:
890  virtual STIRAcquisitionDataInMemory* clone_impl() const
891  {
892  init();
893  return (STIRAcquisitionDataInMemory*)clone_base();
894  }
895  };
896 
902  class STIRListmodeData : public ContainerBase /*STIRScanData*/ {
903  public:
904  STIRListmodeData(std::string lmdata_filename)
905  {
906  _data = stir::read_from_file<stir::ListModeData>(lmdata_filename);
907  }
908  virtual ~STIRListmodeData() {}
909 
910  // TODO remove
911  virtual stir::shared_ptr<stir::ExamData> data_sptr() const {
912  return _data;
913  }
914  virtual stir::shared_ptr<stir::ListModeData> data() const {
915  return _data;
916  }
917 #if 0
918  virtual ObjectHandle<DataContainer>* new_data_container_handle() const
919  {
920  THROW("ListmodeData::new_data_container_handle not implemented");
921  return 0;
922  }
923 #endif
925 
926  std::shared_ptr<STIRAcquisitionData> acquisition_data_template() const
927  {
928  return std::shared_ptr < STIRAcquisitionData >
929  (STIRAcquisitionData::storage_template()->same_acquisition_data(this->data()->get_exam_info_sptr(),
930  this->data()->get_proj_data_info_sptr()->create_shared_clone()));
931  }
932  std::string get_info() const
933  {
934  return this->data()->get_exam_info_sptr()->parameter_info() +
935  this->data()->get_proj_data_info_sptr()->parameter_info();
936  }
937  protected:
938  stir::shared_ptr<stir::ListModeData> _data;
939  virtual DataContainer* clone_impl() const
940  {
941  THROW("ListmodeData::clone not implemented");
942  }
943  };
944 
945 #if SIRF_VERSION_MAJOR < 4
952 #endif
953 
954  typedef Image3DF::full_iterator Image3DFIterator;
955  typedef Image3DF::const_full_iterator Image3DFIterator_const;
956 
965  class STIRImageData : public ImageData {
966  public:
969  class Iterator : public BaseIter {
970  public:
972 
973  typedef Image3DFIterator::difference_type difference_type;
974  typedef Image3DFIterator::value_type value_type;
975  typedef Image3DFIterator::reference reference;
976  typedef Image3DFIterator::pointer pointer;
977  typedef std::forward_iterator_tag iterator_category;
979  Iterator(const Image3DFIterator& iter) : _iter(iter)
980  {}
981  Iterator& operator=(const Iterator& iter)
982  {
983  _iter = iter._iter;
984  _ref.copy(iter._ref);
985  _sptr_iter = iter._sptr_iter;
986  return *this;
987  }
988  virtual Iterator& operator++()
989  {
990  ++_iter;
991  return *this;
992  }
993  //virtual Iterator& operator++(int)
994  //{
995  // _sptr_iter.reset(new Iterator(_iter));
996  // ++_iter;
997  // return *_sptr_iter;
998  //}
999  virtual bool operator==(const BaseIter& an_iter) const
1000  {
1001  const Iterator& iter = (const Iterator&)an_iter;
1002  return _iter == iter._iter;
1003  }
1004  virtual bool operator!=(const BaseIter& an_iter) const
1005  {
1006  const Iterator& iter = (const Iterator&)an_iter;
1007  return _iter != iter._iter;
1008  }
1009  virtual FloatRef& operator*()
1010  {
1011  float& v = *_iter;
1012  _ref.set_ptr(&v);
1013  return _ref;
1014  }
1015  private:
1016  Image3DFIterator _iter;
1017  FloatRef _ref;
1018  std::shared_ptr<Iterator> _sptr_iter;
1019  };
1021  public:
1022  Iterator_const(const Image3DFIterator_const& iter) : _iter(iter)
1023  {}
1024  Iterator_const& operator=(const Iterator_const& iter)
1025  {
1026  _iter = iter._iter;
1027  _ref.copy(iter._ref);
1028  _sptr_iter = iter._sptr_iter;
1029  return *this;
1030  }
1031  virtual Iterator_const& operator++()
1032  {
1033  ++_iter;
1034  return *this;
1035  }
1036  //virtual Iterator_const& operator++(int)
1037  //{
1038  // _sptr_iter.reset(new Iterator_const(_iter));
1039  // ++_iter;
1040  // return *_sptr_iter;
1041  //}
1042  virtual bool operator==(const BaseIter_const& an_iter) const
1043  {
1044  const Iterator_const& iter = (const Iterator_const&)an_iter;
1045  return _iter == iter._iter;
1046  }
1047  virtual bool operator!=(const BaseIter_const& an_iter) const
1048  {
1049  const Iterator_const& iter = (const Iterator_const&)an_iter;
1050  return _iter != iter._iter;
1051  }
1052  virtual const FloatRef& operator*() const
1053  {
1054  const float& v = *_iter;
1055  _ref.set_ptr((void*)&v);
1056  return _ref;
1057  }
1058  private:
1059  Image3DFIterator_const _iter;
1060  mutable FloatRef _ref;
1061  std::shared_ptr<Iterator_const> _sptr_iter;
1062  };
1063  STIRImageData() {}
1064  STIRImageData(const ImageData& id);
1065  STIRImageData(const STIRImageData& image)
1066  {
1067  _data.reset(image.data().clone());
1068  this->set_up_geom_info();
1069  }
1070  STIRImageData(const STIRAcquisitionData& ad)
1071  {
1072  _data.reset(new Voxels3DF(MAKE_SHARED<stir::ExamInfo>(*ad.get_exam_info_sptr()), *ad.get_proj_data_info_sptr()));
1073  this->set_up_geom_info();
1074  }
1075  STIRImageData(const Image3DF& image)
1076  {
1077  _data.reset(image.clone());
1078  this->set_up_geom_info();
1079  }
1080  STIRImageData(const Voxels3DF& v)
1081  {
1082  _data.reset(v.clone());
1083  this->set_up_geom_info();
1084  }
1085  STIRImageData(const stir::ProjDataInfo& pdi)
1086  {
1087  _data.reset(new Voxels3DF(pdi));
1088  this->set_up_geom_info();
1089  }
1090  STIRImageData(stir::shared_ptr<Image3DF> ptr)
1091  {
1092  _data = ptr;
1093  this->set_up_geom_info();
1094  }
1095  STIRImageData(std::string filename)
1096  {
1097  _data = stir::read_from_file<Image3DF>(filename);
1098  this->set_up_geom_info();
1099  }
1100  STIRImageData* same_image_data() const
1101  {
1102  STIRImageData* ptr_image = new STIRImageData;
1103  ptr_image->_data.reset(_data->get_empty_copy());
1104  ptr_image->set_up_geom_info();
1105  return ptr_image;
1106  }
1107  std::shared_ptr<STIRImageData> new_image_data()
1108  {
1109  return std::shared_ptr<STIRImageData>(same_image_data());
1110  }
1111  virtual ObjectHandle<DataContainer>* new_data_container_handle() const
1112  {
1113  return new ObjectHandle<DataContainer>
1114  (std::shared_ptr<DataContainer>(same_image_data()));
1115  }
1116  std::string get_info() const
1117  {
1118  return this->data().get_exam_info_sptr()->parameter_info();
1119  // TODO geometric info, although that's handled separately in SIRF
1120  }
1121  virtual bool is_complex() const
1122  {
1123  return false;
1124  }
1125  unsigned int items() const
1126  {
1127  return 1;
1128  }
1129 
1130  std::string modality() const
1131  {
1132  ExamInfo ex_info = data().get_exam_info();
1133  return ex_info.imaging_modality.get_name();
1134  }
1135  void set_modality(const std::string& mod)
1136  {
1137  ExamInfo ex_info = data().get_exam_info();
1138  ex_info.imaging_modality = ImagingModality(mod);
1139  data().set_exam_info(ex_info);
1140  }
1141 
1143  virtual void write(const std::string& filename) const;
1145 
1164  virtual void write(const std::string& filename, const std::string& format_file) const;
1165 
1166  virtual float norm() const;
1168  virtual void sum(void* ptr) const;
1169  virtual void max(void* ptr) const;
1170  virtual void min(void* ptr) const;
1171  virtual void dot(const DataContainer& a_x, void* ptr) const;
1172  virtual void axpby(
1173  const void* ptr_a, const DataContainer& a_x,
1174  const void* ptr_b, const DataContainer& a_y);
1175  virtual void xapyb(
1176  const DataContainer& a_x, const void* ptr_a,
1177  const DataContainer& a_y, const void* ptr_b);
1178  virtual void xapyb(
1179  const DataContainer& a_x, const DataContainer& a_a,
1180  const DataContainer& a_y, const DataContainer& a_b);
1181  virtual void xapyb(
1182  const DataContainer& a_x, const void* ptr_a,
1183  const DataContainer& a_y, const DataContainer& a_b);
1184  virtual void abs(const DataContainer& x)
1185  {
1186  unary_op(x, std::abs);
1187  }
1188  virtual void exp(const DataContainer& x)
1189  {
1190  unary_op(x, std::exp);
1191  }
1192  virtual void log(const DataContainer& x)
1193  {
1194  unary_op(x, std::log);
1195  }
1196  virtual void sqrt(const DataContainer& x)
1197  {
1198  unary_op(x, std::sqrt);
1199  }
1200  virtual void sign(const DataContainer& x)
1201  {
1202  unary_op(x, DataContainer::sign);
1203  }
1204  virtual void multiply(const DataContainer& x, const void* ptr_y)
1205  {
1206  float y = *static_cast<const float*>(ptr_y);
1207  semibinary_op(x, y, DataContainer::product<float>);
1208  }
1209  virtual void add(const DataContainer& x, const void* ptr_y)
1210  {
1211  float y = *static_cast<const float*>(ptr_y);
1212  semibinary_op(x, y, DataContainer::sum<float>);
1213  }
1214  virtual void divide(const DataContainer& x, const void* ptr_y)
1215  {
1216  float y = *static_cast<const float*>(ptr_y);
1217  semibinary_op(x, y, DataContainer::ratio<float>);
1218  }
1219  virtual void maximum(const DataContainer& x, const void* ptr_y)
1220  {
1221  float y = *static_cast<const float*>(ptr_y);
1222  semibinary_op(x, y, DataContainer::maximum<float>);
1223  }
1224  virtual void minimum(const DataContainer& x, const void* ptr_y)
1225  {
1226  float y = *static_cast<const float*>(ptr_y);
1227  semibinary_op(x, y, DataContainer::minimum<float>);
1228  }
1229  virtual void power(const DataContainer& x, const void* ptr_y)
1230  {
1231  float y = *static_cast<const float*>(ptr_y);
1232  semibinary_op(x, y, std::pow);
1233  }
1234  virtual void multiply(const DataContainer& x, const DataContainer& y)
1235  {
1236  binary_op(x, y, DataContainer::product<float>);
1237  }
1238  virtual void divide(const DataContainer& x, const DataContainer& y)
1239  {
1240  binary_op(x, y, DataContainer::ratio<float>);
1241  }
1242  virtual void maximum(const DataContainer& x, const DataContainer& y)
1243  {
1244  binary_op(x, y, DataContainer::maximum<float>);
1245  }
1246  virtual void minimum(const DataContainer& x, const DataContainer& y)
1247  {
1248  binary_op(x, y, DataContainer::minimum<float>);
1249  }
1250  virtual void power(const DataContainer& x, const DataContainer& y)
1251  {
1252  binary_op(x, y, std::pow);
1253  }
1254 
1255  Image3DF& data()
1256  {
1257  return *_data;
1258  }
1259  const Image3DF& data() const
1260  {
1261  return *_data;
1262  }
1263  Image3DF* data_ptr()
1264  {
1265  return _data.get();
1266  }
1267  const Image3DF* data_ptr() const
1268  {
1269  return _data.get();
1270  }
1271  stir::shared_ptr<Image3DF> data_sptr()
1272  {
1273  return _data;
1274  }
1275  stir::shared_ptr<const Image3DF> data_sptr() const
1276  {
1277  return _data;
1278  }
1279  void set_data_sptr(stir::shared_ptr<Image3DF> sptr_data)
1280  {
1281  _data = sptr_data;
1282  }
1283 
1284  void fill(float v)
1285  {
1286  _data->fill(v);
1287  }
1288  void scale(float s);
1289  float dot(const DataContainer& a_x) const
1290  {
1291  float s;
1292  dot(a_x, &s);
1293  return s;
1294  }
1295  void axpby(
1296  float a, const DataContainer& a_x,
1297  float b, const DataContainer& a_y)
1298  {
1299  axpby(&a, a_x, &b, a_y);
1300  }
1301  void xapyb(
1302  const DataContainer& a_x, float a,
1303  const DataContainer& a_y, float b)
1304  {
1305  xapyb(a_x, &a, a_y, &b);
1306  }
1307  size_t size() const
1308  {
1309  return _data->size_all();
1310  }
1311  virtual Dimensions dimensions() const
1312  {
1313  Dimensions dim;
1314  int d[4];
1315  get_dimensions(d);
1316  dim["z"] = d[0];
1317  dim["y"] = d[1];
1318  dim["x"] = d[2];
1319  return dim;
1320  }
1321  int get_dimensions(int* dim) const;
1322  void get_voxel_sizes(float* vsizes) const;
1323  virtual void get_data(float* data) const;
1324  virtual void set_data(const float* data);
1325  virtual Iterator& begin()
1326  {
1327  _begin.reset(new Iterator(data().begin_all()));
1328  return *_begin;
1329  }
1330  virtual Iterator_const& begin() const
1331  {
1332  _begin_const.reset(new Iterator_const(data().begin_all()));
1333  return *_begin_const;
1334  }
1335  virtual Iterator& end()
1336  {
1337  _end.reset(new Iterator(data().end_all()));
1338  return *_end;
1339  }
1340  virtual Iterator_const& end() const
1341  {
1342  _end_const.reset(new Iterator_const(data().end_all()));
1343  return *_end_const;
1344  }
1345 
1347  std::unique_ptr<STIRImageData> clone() const
1348  {
1349  return std::unique_ptr<STIRImageData>(this->clone_impl());
1350  }
1351 
1355  void zoom_image(const Coord3DF& zooms = { 1.f,1.f,1.f }, const Coord3DF& offsets_in_mm = { 0.f,0.f,0.f },
1356  const Coord3DI& new_sizes = { -1,-1,-1 }, const char* const zoom_options_str = "preserve_sum");
1357 
1361  void zoom_image(const Coord3DF& zooms = { 1.f,1.f,1.f }, const Coord3DF& offsets_in_mm = { 0.f,0.f,0.f },
1362  const Coord3DI& new_sizes = { -1,-1,-1 },
1363  const stir::ZoomOptions zoom_options = stir::ZoomOptions::preserve_sum);
1364 
1367  void move_to_scanner_centre(const STIRAcquisitionData&);
1368 
1370  virtual void set_up_geom_info();
1371 
1372  void unary_op(const DataContainer& a_x, float(*f)(float));
1373  void semibinary_op(const DataContainer& a_x, float y, float(*f)(float, float));
1374  void binary_op(const DataContainer& a_x, const DataContainer& a_y, float(*f)(float, float));
1375 
1376  private:
1378  virtual STIRImageData* clone_impl() const
1379  {
1380  return new STIRImageData(*this);
1381  }
1382 
1383  protected:
1384  stir::shared_ptr<Image3DF> _data;
1385  mutable std::shared_ptr<Iterator> _begin;
1386  mutable std::shared_ptr<Iterator> _end;
1387  mutable std::shared_ptr<Iterator_const> _begin_const;
1388  mutable std::shared_ptr<Iterator_const> _end_const;
1389  };
1390 
1391 } // namespace sirf
1392 
1393 #endif
Execution status type and wrappers for C++ objects.
Definition: LocalisedException.h:32
Definition: DataHandle.h:159
Abstract data container.
Definition: DataContainer.h:44
Abstract data container with numerical operations.
Definition: DataContainer.h:58
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:161
virtual void min(void *ptr) const
calculates the value of this container's element with the smallest real part
Definition: stir_data_containers.cpp:121
virtual void sum(void *ptr) const
below all void* are actually float*
Definition: stir_data_containers.cpp:63
virtual void sqrt(const DataContainer &x)
*this = the elementwise sqrt(x)
Definition: stir_data_containers.h:333
virtual void multiply(const DataContainer &x, const DataContainer &y)
*this = the elementwise product x*y
Definition: stir_data_containers.h:371
virtual void sign(const DataContainer &x)
*this = the elementwise sign(x)
Definition: stir_data_containers.h:337
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:188
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:178
int get_num_sinograms() const
total number of (2D) sinograms
Definition: stir_data_containers.h:411
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:146
virtual void add(const DataContainer &x, const void *ptr_y)
*this = the sum x + y with scalar y
Definition: stir_data_containers.h:346
virtual void divide(const DataContainer &x, const DataContainer &y)
*this = the elementwise ratio x / y
Definition: stir_data_containers.h:375
virtual void minimum(const DataContainer &x, const DataContainer &y)
*this = the elementwise min(x, y)
Definition: stir_data_containers.h:383
int get_num_non_TOF_sinograms() const
total number of (2D) sinograms ignoring time-of-flight
Definition: stir_data_containers.h:417
virtual void abs(const DataContainer &x)
*this = the elementwise abs(x)
Definition: stir_data_containers.h:321
virtual void max(void *ptr) const
calculates the value of this container's element with the largest real part
Definition: stir_data_containers.cpp:89
virtual void log(const DataContainer &x)
*this = the elementwise log(x)
Definition: stir_data_containers.h:329
virtual void maximum(const DataContainer &x, const DataContainer &y)
*this = the elementwise max(x, y)
Definition: stir_data_containers.h:379
virtual void exp(const DataContainer &x)
*this = the elementwise exp(x)
Definition: stir_data_containers.h:325
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:198
virtual void multiply(const DataContainer &x, const void *ptr_y)
*this = the product x * y with scalar y
Definition: stir_data_containers.h:341
virtual void power(const DataContainer &x, const DataContainer &y)
*this = the elementwise pow(x, y)
Definition: stir_data_containers.h:387
In-file implementation of STIRAcquisitionData.
Definition: stir_data_containers.h:541
In-memory implementation of STIRAcquisitionData.
Definition: stir_data_containers.h:655
virtual void divide(const DataContainer &x, const DataContainer &y)
*this = the elementwise ratio x / y
Definition: stir_data_containers.h:867
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:826
STIRAcquisitionDataInMemory(const char *filename)
Constructor for STIRAcquisitionDataInMemory from filename.
Definition: stir_data_containers.h:698
virtual void fill_from(const float *d)
Fill from float array.
Definition: stir_data_containers.h:783
virtual void fill(const STIRAcquisitionData &ad)
fill from another STIRAcquisitionData
Definition: stir_data_containers.h:767
virtual float norm() const
returns the norm of this container viewed as a vector
Definition: stir_data_containers.h:808
virtual void multiply(const DataContainer &x, const DataContainer &y)
*this = the elementwise product x*y
Definition: stir_data_containers.h:846
virtual void fill(const float v)
fill with single value
Definition: stir_data_containers.h:754
virtual void copy_to(float *d) const
Copy to float array.
Definition: stir_data_containers.h:796
Definition: stir_data_containers.h:1020
Definition: stir_data_containers.h:969
STIR DiscretisedDensity<3, float> wrapper with added functionality.
Definition: stir_data_containers.h:965
virtual void abs(const DataContainer &x)
*this = the elementwise abs(x)
Definition: stir_data_containers.h:1184
virtual void sqrt(const DataContainer &x)
*this = the elementwise sqrt(x)
Definition: stir_data_containers.h:1196
virtual void divide(const DataContainer &x, const DataContainer &y)
*this = the elementwise ratio x / y
Definition: stir_data_containers.h:1238
virtual void max(void *ptr) const
calculates the value of this container's element with the largest real part
Definition: stir_data_containers.cpp:512
virtual void multiply(const DataContainer &x, const DataContainer &y)
*this = the elementwise product x*y
Definition: stir_data_containers.h:1234
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:526
virtual void set_up_geom_info()
Populate the geometrical info metadata (from the image's own metadata)
Definition: stir_data_containers.cpp:826
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:773
virtual float norm() const
returns the norm of this container viewed as a vector
Definition: stir_data_containers.cpp:614
std::unique_ptr< STIRImageData > clone() const
Clone and return as unique pointer.
Definition: stir_data_containers.h:1347
virtual void maximum(const DataContainer &x, const DataContainer &y)
*this = the elementwise max(x, y)
Definition: stir_data_containers.h:1242
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:549
virtual bool is_complex() const
Is complex? Unless overwridden (Gadgetron), assume not complex.
Definition: stir_data_containers.h:1121
virtual void sum(void *ptr) const
below all void* are actually float*
Definition: stir_data_containers.cpp:505
virtual void log(const DataContainer &x)
*this = the elementwise log(x)
Definition: stir_data_containers.h:1192
void move_to_scanner_centre(const STIRAcquisitionData &)
Definition: stir_data_containers.cpp:817
virtual void sign(const DataContainer &x)
*this = the elementwise sign(x)
Definition: stir_data_containers.h:1200
virtual void write(const std::string &filename) const
Write to file.
Definition: stir_data_containers.cpp:473
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:558
virtual void minimum(const DataContainer &x, const DataContainer &y)
*this = the elementwise min(x, y)
Definition: stir_data_containers.h:1246
virtual void min(void *ptr) const
calculates the value of this container's element with the smallest real part
Definition: stir_data_containers.cpp:519
virtual void add(const DataContainer &x, const void *ptr_y)
*this = the sum x + y with scalar y
Definition: stir_data_containers.h:1209
virtual void power(const DataContainer &x, const DataContainer &y)
*this = the elementwise pow(x, y)
Definition: stir_data_containers.h:1250
virtual void exp(const DataContainer &x)
*this = the elementwise exp(x)
Definition: stir_data_containers.h:1188
virtual void multiply(const DataContainer &x, const void *ptr_y)
*this = the product x * y with scalar y
Definition: stir_data_containers.h:1204
Definition: stir_data_containers.h:902
std::shared_ptr< STIRAcquisitionData > acquisition_data_template() const
Construct an AcquisitionData object corresponding to the listmode data.
Definition: stir_data_containers.h:926
Defines sirf::iequals.
Abstract base class for SIRF image data.
Definition: GeometricalInfo.cpp:141
STIRAcquisitionData PETAcquisitionData
Definition: stir_data_containers.h:949
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