SIRF  3.7.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 
484  // ProjData casts
485  operator stir::ProjData&() { return *data(); }
486  operator const stir::ProjData&() const { return *data(); }
487  operator stir::shared_ptr<stir::ProjData>() { return data(); }
488 
489  static stir::shared_ptr<stir::ProjDataInfo>
490  proj_data_info_from_scanner(std::string scanner_name,
491  int span = 1, int max_ring_diff = -1, int view_mash_factor = 1)
492  {
493  stir::shared_ptr<stir::Scanner>
494  sptr_s(stir::Scanner::get_scanner_from_name(scanner_name));
495  //std::cout << "scanner: " << sptr_s->get_name().c_str() << '\n';
496  if (sirf::iequals(sptr_s->get_name(), "unknown")) {
497  throw LocalisedException("Unknown scanner", __FILE__, __LINE__);
498  }
499  int num_views = sptr_s->get_num_detectors_per_ring() / 2 / view_mash_factor;
500  int num_tang_pos = sptr_s->get_max_num_non_arccorrected_bins();
501  if (max_ring_diff < 0)
502  max_ring_diff = sptr_s->get_num_rings() - 1;
503  return std::move(stir::ProjDataInfo::construct_proj_data_info
504  (sptr_s, span, max_ring_diff, num_views, num_tang_pos, false));
505  }
506 
507  void unary_op(const DataContainer& a_x, float(*f)(float));
508  void semibinary_op(const DataContainer& a_x, float y, float(*f)(float, float));
509  void binary_op(const DataContainer& a_x, const DataContainer& a_y, float(*f)(float, float));
510 
511  protected:
512  static std::string _storage_scheme;
513  static std::shared_ptr<STIRAcquisitionData> _template;
514  stir::shared_ptr<stir::ProjData> _data;
515  virtual STIRAcquisitionData* clone_impl() const = 0;
516  STIRAcquisitionData* clone_base() const
517  {
518  stir::shared_ptr<stir::ProjDataInfo> sptr_pdi = this->get_proj_data_info_sptr()->create_shared_clone();
519  STIRAcquisitionData* ptr =
520  _template->same_acquisition_data(this->get_exam_info_sptr(), sptr_pdi);
521  if (!this->is_empty())
522  ptr->fill(*this);
523  return ptr;
524  }
525 
526  private:
527  mutable int _is_empty = -1;
528  };
529 
537  public:
538  STIRAcquisitionDataInFile() : _owns_file(false) {}
539  STIRAcquisitionDataInFile(const char* filename) : _owns_file(false)
540  {
541  _data = stir::ProjData::read_from_file(filename);
542  }
543  STIRAcquisitionDataInFile(stir::shared_ptr<const stir::ExamInfo> sptr_exam_info,
544  stir::shared_ptr<stir::ProjDataInfo> sptr_proj_data_info)
545  {
546  _data.reset(new ProjDataFile
547  (MAKE_SHARED<stir::ExamInfo>(*sptr_exam_info), sptr_proj_data_info,
548  _filename = SIRFUtilities::scratch_file_name()));
549  }
550  STIRAcquisitionDataInFile(const stir::ProjData& pd) : _owns_file(true)
551  {
552  _data.reset(new ProjDataFile
553  (pd, _filename = SIRFUtilities::scratch_file_name()));
554  }
556  (stir::shared_ptr<stir::ExamInfo> sptr_ei, std::string scanner_name,
557  int span = 1, int max_ring_diff = -1, int view_mash_factor = 1)
558  {
559  stir::shared_ptr<stir::ProjDataInfo> sptr_pdi =
560  STIRAcquisitionData::proj_data_info_from_scanner
561  (scanner_name, span, max_ring_diff, view_mash_factor);
562  ProjDataFile* ptr = new ProjDataFile(sptr_ei, sptr_pdi,
563  _filename = SIRFUtilities::scratch_file_name());
564  ptr->fill(0.0f);
565  _data.reset(ptr);
566  }
567  STIRAcquisitionDataInFile(std::unique_ptr<stir::ProjData> uptr_pd) : _owns_file(true)
568  {
569 // auto *pd_ptr = dynamic_cast<stir::ProjDataInterfile*>(uptr_pd.get());
570  auto pd_ptr = dynamic_cast<stir::ProjDataInterfile*>(uptr_pd.get());
571  if (pd_ptr)
572  _data = std::move(uptr_pd);
573  else {
574  stir::ProjData& pd = *uptr_pd;
575  stir::shared_ptr<const stir::ExamInfo> sptr_exam_info =
576  pd.get_exam_info_sptr();
577  stir::shared_ptr<stir::ProjDataInfo> sptr_proj_data_info =
578  pd.get_proj_data_info_sptr()->create_shared_clone();
579  _data.reset(new ProjDataFile
580  (MAKE_SHARED<stir::ExamInfo>(*sptr_exam_info), sptr_proj_data_info,
581  _filename = SIRFUtilities::scratch_file_name()));
582  _data->fill(pd);
583  }
584  }
585  std::shared_ptr<STIRAcquisitionData> new_acquisition_data(std::string filename)
586  {
587  std::shared_ptr<STIRAcquisitionDataInFile> sptr_ad(new STIRAcquisitionDataInFile);
588  sptr_ad->_data.reset(new ProjDataFile(*data(), filename, false));
589  return sptr_ad;
590  }
591 
592  static void init() {
593  static bool initialized = false;
594  if (!initialized) {
595  _storage_scheme = "file";
596  _template.reset(new STIRAcquisitionDataInFile());
597  initialized = true;
598  STIRAcquisitionData::storage_scheme();
599  }
600  }
601  static void set_as_template()
602  {
603  init();
604  _storage_scheme = "file";
605  _template.reset(new STIRAcquisitionDataInFile);
606  }
607 
608  virtual STIRAcquisitionData* same_acquisition_data
609  (stir::shared_ptr<const stir::ExamInfo> sptr_exam_info,
610  stir::shared_ptr<stir::ProjDataInfo> sptr_proj_data_info) const
611  {
612  STIRAcquisitionData* ptr_ad =
613  new STIRAcquisitionDataInFile(sptr_exam_info, sptr_proj_data_info);
614  return ptr_ad;
615  }
616  virtual ObjectHandle<DataContainer>* new_data_container_handle() const
617  {
618  init();
619  DataContainer* ptr = _template->same_acquisition_data(
620  this->get_exam_info_sptr(),
621  this->get_proj_data_info_sptr()->create_shared_clone());
622  return new ObjectHandle<DataContainer>
623  (std::shared_ptr<DataContainer>(ptr));
624  }
625  virtual std::shared_ptr<STIRAcquisitionData> new_acquisition_data() const
626  {
627  init();
628  return std::shared_ptr < STIRAcquisitionData >
629  (_template->same_acquisition_data(this->get_exam_info_sptr(),
630  this->get_proj_data_info_sptr()->create_shared_clone()));
631  }
632  virtual std::unique_ptr<STIRAcquisitionData> get_subset(const std::vector<int>& views) const;
633 
634  private:
635  bool _owns_file;
636  std::string _filename;
637  virtual STIRAcquisitionDataInFile* clone_impl() const
638  {
639  init();
640  return (STIRAcquisitionDataInFile*)clone_base();
641  }
642  };
643 
651  public:
653  STIRAcquisitionDataInMemory(stir::shared_ptr<const stir::ExamInfo> sptr_exam_info,
654  stir::shared_ptr<const stir::ProjDataInfo> sptr_proj_data_info)
655  {
656  _data = stir::shared_ptr<stir::ProjData>
657  (new stir::ProjDataInMemory(SPTR_WRAP(sptr_exam_info), SPTR_WRAP(sptr_proj_data_info)));
658  }
659  STIRAcquisitionDataInMemory(const stir::ProjData& templ)
660  {
661  _data = stir::shared_ptr<stir::ProjData>
662  (new stir::ProjDataInMemory(templ.get_exam_info_sptr(),
663  templ.get_proj_data_info_sptr()->create_shared_clone()));
664  }
666  (stir::shared_ptr<stir::ExamInfo> sptr_ei, std::string scanner_name,
667  int span = 1, int max_ring_diff = -1, int view_mash_factor = 1)
668  {
669  stir::shared_ptr<stir::ProjDataInfo> sptr_pdi =
670  STIRAcquisitionData::proj_data_info_from_scanner
671  (scanner_name, span, max_ring_diff, view_mash_factor);
672  stir::ProjDataInMemory* ptr = new stir::ProjDataInMemory(sptr_ei, sptr_pdi);
673  ptr->fill(0.0f);
674  _data.reset(ptr);
675  }
676  STIRAcquisitionDataInMemory(std::unique_ptr<stir::ProjData> uptr_pd)
677  {
678 // auto *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(uptr_pd.get());
679  auto pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(uptr_pd.get());
680  if (pd_ptr)
681  _data = std::move(uptr_pd);
682  else {
683  std::cout << "copying ProjData to ProjDataInMemory...\n";
684  const stir::ProjData& pd = *uptr_pd;
685  auto exam_info_sptr = SPTR_WRAP(pd.get_exam_info_sptr());
686  auto proj_data_info_sptr =
687  SPTR_WRAP(pd.get_proj_data_info_sptr()->create_shared_clone());
688  _data.reset(new stir::ProjDataInMemory(exam_info_sptr, proj_data_info_sptr));
689  _data->fill(pd);
690  }
691  }
693  STIRAcquisitionDataInMemory(const char* filename)
694  {
695  auto pd_sptr = stir::ProjData::read_from_file(filename);
696  bool is_empty = false;
697  try {
698  pd_sptr->get_segment_by_sinogram(0);
699  }
700  catch (...) {
701  is_empty = true;
702  }
703  if (is_empty)
704  _data = stir::shared_ptr<stir::ProjData>
705  (new stir::ProjDataInMemory(pd_sptr->get_exam_info_sptr(),
706  pd_sptr->get_proj_data_info_sptr()->create_shared_clone()));
707  else
708  _data = stir::shared_ptr<stir::ProjData>
709  (new stir::ProjDataInMemory(*pd_sptr));
710  }
711 
712  static void init();
713 
714  static void set_as_template()
715  {
716  init();
717  _storage_scheme = "memory";
718  _template.reset(new STIRAcquisitionDataInMemory);
719  }
720 
721  virtual STIRAcquisitionData* same_acquisition_data
722  (stir::shared_ptr<const stir::ExamInfo> sptr_exam_info,
723  stir::shared_ptr<stir::ProjDataInfo> sptr_proj_data_info) const
724  {
725  STIRAcquisitionData* ptr_ad =
726  new STIRAcquisitionDataInMemory(sptr_exam_info, sptr_proj_data_info);
727  return ptr_ad;
728  }
729  virtual ObjectHandle<DataContainer>* new_data_container_handle() const
730  {
731  init();
732  DataContainer* ptr = _template->same_acquisition_data
733  (this->get_exam_info_sptr(),
734  this->get_proj_data_info_sptr()->create_shared_clone());
735  return new ObjectHandle<DataContainer>
736  (std::shared_ptr<DataContainer>(ptr));
737  }
738  virtual std::shared_ptr<STIRAcquisitionData> new_acquisition_data() const
739  {
740  init();
741  return std::shared_ptr < STIRAcquisitionData >
742  (_template->same_acquisition_data
743  (this->get_exam_info_sptr(),
744  this->get_proj_data_info_sptr()->create_shared_clone()));
745  }
746  virtual std::unique_ptr<STIRAcquisitionData> get_subset(const std::vector<int>& views) const;
747 
749  virtual void fill(const float v)
750  {
751  stir::ProjDataInMemory *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(data().get());
752  // If cast failed, fall back to general method
753  if (is_null_ptr(pd_ptr))
754  return this->STIRAcquisitionData::fill(v);
755 
756  // do it
757  auto iter = pd_ptr->begin();
758  while (iter != pd_ptr->end())
759  *iter++ = v;
760  }
762  virtual void fill(const STIRAcquisitionData& ad)
763  {
764  // Can only do this if both are STIRAcquisitionDataInMemory
765  stir::ProjDataInMemory *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(data().get());
766  const stir::ProjDataInMemory *pd2_ptr = dynamic_cast<const stir::ProjDataInMemory*>(ad.data().get());
767  // If either cast failed, fall back to general method
768  if (is_null_ptr(pd_ptr) || is_null_ptr(pd2_ptr))
769  return this->STIRAcquisitionData::fill(ad);
770 
771  // do it
772  auto iter = pd_ptr->begin();
773  auto iter_other = pd2_ptr->begin();
774  while (iter != pd_ptr->end())
775  *iter++ = *iter_other++;
776  }
778  virtual void fill_from(const float* d)
779  {
780  stir::ProjDataInMemory *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(data().get());
781  // If cast failed, fall back to general method
782  if (is_null_ptr(pd_ptr))
783  return this->STIRAcquisitionData::fill_from(d);
784 
785  // do it
786  auto iter = pd_ptr->begin();
787  while (iter != pd_ptr->end())
788  *iter++ = *d++;
789  }
791  virtual void copy_to(float* d) const
792  {
793  const stir::ProjDataInMemory *pd_ptr = dynamic_cast<const stir::ProjDataInMemory*>(data().get());
794  // If cast failed, fall back to general method
795  if (is_null_ptr(pd_ptr))
796  return this->STIRAcquisitionData::copy_to(d);
797 
798  // do it
799  auto iter = pd_ptr->begin();
800  while (iter != pd_ptr->end())
801  *d++ = *iter++;
802  }
803  virtual float norm() const
804  {
805  const stir::ProjDataInMemory *pd_ptr = dynamic_cast<const stir::ProjDataInMemory*>(data().get());
806  // If cast failed, fall back to general method
807  if (is_null_ptr(pd_ptr))
808  return this->STIRAcquisitionData::norm();
809 
810  // do it
811  double t = 0.0;
812  auto iter = pd_ptr->begin();
813  for (; iter != pd_ptr->end(); ++iter)
814  t += (*iter) * (*iter);
815  return std::sqrt((float)t);
816  }
817  virtual void dot(const DataContainer& a_x, void* ptr) const
818  {
819  auto x = dynamic_cast<const STIRAcquisitionData*>(&a_x);
820  // Can only do this if both are STIRAcquisitionDataInMemory
821  stir::ProjDataInMemory *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(data().get());
822  const stir::ProjDataInMemory *pd2_ptr = dynamic_cast<const stir::ProjDataInMemory*>(x->data().get());
823  // If either cast failed, fall back to general method
824  if (is_null_ptr(pd_ptr) || is_null_ptr(pd2_ptr))
825  return this->STIRAcquisitionData::dot(a_x,ptr);
826 
827  // do it
828  double t = 0.0;
829  auto iter = pd_ptr->begin();
830  auto iter_other = pd2_ptr->begin();
831  while (iter != pd_ptr->end())
832  t += (*iter++) * double(*iter_other++);
833 
834  float* ptr_t = static_cast<float*>(ptr);
835  *ptr_t = (float)t;
836  }
837  virtual void multiply(const DataContainer& x, const DataContainer& y)
838  {
839  auto a_x = dynamic_cast<const STIRAcquisitionData*>(&x);
840  auto a_y = dynamic_cast<const STIRAcquisitionData*>(&y);
841 
842  // Can only do this if all are STIRAcquisitionDataInMemory
843  auto *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(data().get());
844  auto *pd_x_ptr = dynamic_cast<const stir::ProjDataInMemory*>(a_x->data().get());
845  auto *pd_y_ptr = dynamic_cast<const stir::ProjDataInMemory*>(a_y->data().get());
846 
847  // If either cast failed, fall back to general method
848  if (is_null_ptr(pd_ptr) || is_null_ptr(pd_x_ptr) || is_null_ptr(pd_x_ptr))
849  return this->STIRAcquisitionData::multiply(x,y);
850 
851  // do it
852  auto iter = pd_ptr->begin();
853  auto iter_x = pd_x_ptr->begin();
854  auto iter_y = pd_y_ptr->begin();
855  while (iter != pd_ptr->end())
856  *iter++ = (*iter_x++) * (*iter_y++);
857  }
858  virtual void divide(const DataContainer& x, const DataContainer& y)
859  {
860  auto a_x = dynamic_cast<const STIRAcquisitionData*>(&x);
861  auto a_y = dynamic_cast<const STIRAcquisitionData*>(&y);
862 
863  // Can only do this if all are STIRAcquisitionDataInMemory
864  auto *pd_ptr = dynamic_cast<stir::ProjDataInMemory*>(data().get());
865  auto *pd_x_ptr = dynamic_cast<const stir::ProjDataInMemory*>(a_x->data().get());
866  auto *pd_y_ptr = dynamic_cast<const stir::ProjDataInMemory*>(a_y->data().get());
867 
868  // If either cast failed, fall back to general method
869  if (is_null_ptr(pd_ptr) || is_null_ptr(pd_x_ptr) || is_null_ptr(pd_x_ptr))
870  return this->STIRAcquisitionData::divide(x,y);
871 
872  // do it
873  auto iter = pd_ptr->begin();
874  auto iter_x = pd_x_ptr->begin();
875  auto iter_y = pd_y_ptr->begin();
876  while (iter != pd_ptr->end())
877  *iter++ = (*iter_x++) / (*iter_y++);
878  }
879 
880  private:
881  virtual STIRAcquisitionDataInMemory* clone_impl() const
882  {
883  init();
884  return (STIRAcquisitionDataInMemory*)clone_base();
885  }
886  };
887 
893  class STIRListmodeData : public ContainerBase /*STIRScanData*/ {
894  public:
895  STIRListmodeData(std::string lmdata_filename)
896  {
897  _data = stir::read_from_file<stir::ListModeData>(lmdata_filename);
898  }
899  virtual ~STIRListmodeData() {}
900 
901  // TODO remove
902  virtual stir::shared_ptr<stir::ExamData> data_sptr() const {
903  return _data;
904  }
905  virtual stir::shared_ptr<stir::ListModeData> data() const {
906  return _data;
907  }
908 #if 0
909  virtual ObjectHandle<DataContainer>* new_data_container_handle() const
910  {
911  THROW("ListmodeData::new_data_container_handle not implemented");
912  return 0;
913  }
914 #endif
916 
917  std::shared_ptr<STIRAcquisitionData> acquisition_data_template() const
918  {
919  return std::shared_ptr < STIRAcquisitionData >
920  (STIRAcquisitionData::storage_template()->same_acquisition_data(this->data()->get_exam_info_sptr(),
921  this->data()->get_proj_data_info_sptr()->create_shared_clone()));
922  }
923  std::string get_info() const
924  {
925  return this->data()->get_exam_info_sptr()->parameter_info() +
926  this->data()->get_proj_data_info_sptr()->parameter_info();
927  }
928  protected:
929  stir::shared_ptr<stir::ListModeData> _data;
930  virtual DataContainer* clone_impl() const
931  {
932  THROW("ListmodeData::clone not implemented");
933  }
934  };
935 
936 #if SIRF_VERSION_MAJOR < 4
943 #endif
944 
945  typedef Image3DF::full_iterator Image3DFIterator;
946  typedef Image3DF::const_full_iterator Image3DFIterator_const;
947 
956  class STIRImageData : public ImageData {
957  public:
960  class Iterator : public BaseIter {
961  public:
963 
964  typedef Image3DFIterator::difference_type difference_type;
965  typedef Image3DFIterator::value_type value_type;
966  typedef Image3DFIterator::reference reference;
967  typedef Image3DFIterator::pointer pointer;
968  typedef std::forward_iterator_tag iterator_category;
970  Iterator(const Image3DFIterator& iter) : _iter(iter)
971  {}
972  Iterator& operator=(const Iterator& iter)
973  {
974  _iter = iter._iter;
975  _ref.copy(iter._ref);
976  _sptr_iter = iter._sptr_iter;
977  return *this;
978  }
979  virtual Iterator& operator++()
980  {
981  ++_iter;
982  return *this;
983  }
984  //virtual Iterator& operator++(int)
985  //{
986  // _sptr_iter.reset(new Iterator(_iter));
987  // ++_iter;
988  // return *_sptr_iter;
989  //}
990  virtual bool operator==(const BaseIter& an_iter) const
991  {
992  const Iterator& iter = (const Iterator&)an_iter;
993  return _iter == iter._iter;
994  }
995  virtual bool operator!=(const BaseIter& an_iter) const
996  {
997  const Iterator& iter = (const Iterator&)an_iter;
998  return _iter != iter._iter;
999  }
1000  virtual FloatRef& operator*()
1001  {
1002  float& v = *_iter;
1003  _ref.set_ptr(&v);
1004  return _ref;
1005  }
1006  private:
1007  Image3DFIterator _iter;
1008  FloatRef _ref;
1009  std::shared_ptr<Iterator> _sptr_iter;
1010  };
1012  public:
1013  Iterator_const(const Image3DFIterator_const& iter) : _iter(iter)
1014  {}
1015  Iterator_const& operator=(const Iterator_const& iter)
1016  {
1017  _iter = iter._iter;
1018  _ref.copy(iter._ref);
1019  _sptr_iter = iter._sptr_iter;
1020  return *this;
1021  }
1022  virtual Iterator_const& operator++()
1023  {
1024  ++_iter;
1025  return *this;
1026  }
1027  //virtual Iterator_const& operator++(int)
1028  //{
1029  // _sptr_iter.reset(new Iterator_const(_iter));
1030  // ++_iter;
1031  // return *_sptr_iter;
1032  //}
1033  virtual bool operator==(const BaseIter_const& an_iter) const
1034  {
1035  const Iterator_const& iter = (const Iterator_const&)an_iter;
1036  return _iter == iter._iter;
1037  }
1038  virtual bool operator!=(const BaseIter_const& an_iter) const
1039  {
1040  const Iterator_const& iter = (const Iterator_const&)an_iter;
1041  return _iter != iter._iter;
1042  }
1043  virtual const FloatRef& operator*() const
1044  {
1045  const float& v = *_iter;
1046  _ref.set_ptr((void*)&v);
1047  return _ref;
1048  }
1049  private:
1050  Image3DFIterator_const _iter;
1051  mutable FloatRef _ref;
1052  std::shared_ptr<Iterator_const> _sptr_iter;
1053  };
1054  STIRImageData() {}
1055  STIRImageData(const ImageData& id);
1056  STIRImageData(const STIRImageData& image)
1057  {
1058  _data.reset(image.data().clone());
1059  this->set_up_geom_info();
1060  }
1061  STIRImageData(const STIRAcquisitionData& ad)
1062  {
1063  _data.reset(new Voxels3DF(MAKE_SHARED<stir::ExamInfo>(*ad.get_exam_info_sptr()), *ad.get_proj_data_info_sptr()));
1064  this->set_up_geom_info();
1065  }
1066  STIRImageData(const Image3DF& image)
1067  {
1068  _data.reset(image.clone());
1069  this->set_up_geom_info();
1070  }
1071  STIRImageData(const Voxels3DF& v)
1072  {
1073  _data.reset(v.clone());
1074  this->set_up_geom_info();
1075  }
1076  STIRImageData(const stir::ProjDataInfo& pdi)
1077  {
1078  _data.reset(new Voxels3DF(pdi));
1079  this->set_up_geom_info();
1080  }
1081  STIRImageData(stir::shared_ptr<Image3DF> ptr)
1082  {
1083  _data = ptr;
1084  this->set_up_geom_info();
1085  }
1086  STIRImageData(std::string filename)
1087  {
1088  _data = stir::read_from_file<Image3DF>(filename);
1089  this->set_up_geom_info();
1090  }
1091  STIRImageData* same_image_data() const
1092  {
1093  STIRImageData* ptr_image = new STIRImageData;
1094  ptr_image->_data.reset(_data->get_empty_copy());
1095  ptr_image->set_up_geom_info();
1096  return ptr_image;
1097  }
1098  std::shared_ptr<STIRImageData> new_image_data()
1099  {
1100  return std::shared_ptr<STIRImageData>(same_image_data());
1101  }
1102  virtual ObjectHandle<DataContainer>* new_data_container_handle() const
1103  {
1104  return new ObjectHandle<DataContainer>
1105  (std::shared_ptr<DataContainer>(same_image_data()));
1106  }
1107  std::string get_info() const
1108  {
1109  return this->data().get_exam_info_sptr()->parameter_info();
1110  // TODO geometric info, although that's handled separately in SIRF
1111  }
1112  virtual bool is_complex() const
1113  {
1114  return false;
1115  }
1116  unsigned int items() const
1117  {
1118  return 1;
1119  }
1120 
1121  std::string modality() const
1122  {
1123  ExamInfo ex_info = data().get_exam_info();
1124  return ex_info.imaging_modality.get_name();
1125  }
1126  void set_modality(const std::string& mod)
1127  {
1128  ExamInfo ex_info = data().get_exam_info();
1129  ex_info.imaging_modality = ImagingModality(mod);
1130  data().set_exam_info(ex_info);
1131  }
1132 
1134  virtual void write(const std::string& filename) const;
1136 
1155  virtual void write(const std::string& filename, const std::string& format_file) const;
1156 
1157  virtual float norm() const;
1159  virtual void sum(void* ptr) const;
1160  virtual void max(void* ptr) const;
1161  virtual void min(void* ptr) const;
1162  virtual void dot(const DataContainer& a_x, void* ptr) const;
1163  virtual void axpby(
1164  const void* ptr_a, const DataContainer& a_x,
1165  const void* ptr_b, const DataContainer& a_y);
1166  virtual void xapyb(
1167  const DataContainer& a_x, const void* ptr_a,
1168  const DataContainer& a_y, const void* ptr_b);
1169  virtual void xapyb(
1170  const DataContainer& a_x, const DataContainer& a_a,
1171  const DataContainer& a_y, const DataContainer& a_b);
1172  virtual void xapyb(
1173  const DataContainer& a_x, const void* ptr_a,
1174  const DataContainer& a_y, const DataContainer& a_b);
1175  virtual void abs(const DataContainer& x)
1176  {
1177  unary_op(x, std::abs);
1178  }
1179  virtual void exp(const DataContainer& x)
1180  {
1181  unary_op(x, std::exp);
1182  }
1183  virtual void log(const DataContainer& x)
1184  {
1185  unary_op(x, std::log);
1186  }
1187  virtual void sqrt(const DataContainer& x)
1188  {
1189  unary_op(x, std::sqrt);
1190  }
1191  virtual void sign(const DataContainer& x)
1192  {
1193  unary_op(x, DataContainer::sign);
1194  }
1195  virtual void multiply(const DataContainer& x, const void* ptr_y)
1196  {
1197  float y = *static_cast<const float*>(ptr_y);
1198  semibinary_op(x, y, DataContainer::product<float>);
1199  }
1200  virtual void add(const DataContainer& x, const void* ptr_y)
1201  {
1202  float y = *static_cast<const float*>(ptr_y);
1203  semibinary_op(x, y, DataContainer::sum<float>);
1204  }
1205  virtual void divide(const DataContainer& x, const void* ptr_y)
1206  {
1207  float y = *static_cast<const float*>(ptr_y);
1208  semibinary_op(x, y, DataContainer::ratio<float>);
1209  }
1210  virtual void maximum(const DataContainer& x, const void* ptr_y)
1211  {
1212  float y = *static_cast<const float*>(ptr_y);
1213  semibinary_op(x, y, DataContainer::maximum<float>);
1214  }
1215  virtual void minimum(const DataContainer& x, const void* ptr_y)
1216  {
1217  float y = *static_cast<const float*>(ptr_y);
1218  semibinary_op(x, y, DataContainer::minimum<float>);
1219  }
1220  virtual void power(const DataContainer& x, const void* ptr_y)
1221  {
1222  float y = *static_cast<const float*>(ptr_y);
1223  semibinary_op(x, y, std::pow);
1224  }
1225  virtual void multiply(const DataContainer& x, const DataContainer& y)
1226  {
1227  binary_op(x, y, DataContainer::product<float>);
1228  }
1229  virtual void divide(const DataContainer& x, const DataContainer& y)
1230  {
1231  binary_op(x, y, DataContainer::ratio<float>);
1232  }
1233  virtual void maximum(const DataContainer& x, const DataContainer& y)
1234  {
1235  binary_op(x, y, DataContainer::maximum<float>);
1236  }
1237  virtual void minimum(const DataContainer& x, const DataContainer& y)
1238  {
1239  binary_op(x, y, DataContainer::minimum<float>);
1240  }
1241  virtual void power(const DataContainer& x, const DataContainer& y)
1242  {
1243  binary_op(x, y, std::pow);
1244  }
1245 
1246  Image3DF& data()
1247  {
1248  return *_data;
1249  }
1250  const Image3DF& data() const
1251  {
1252  return *_data;
1253  }
1254  Image3DF* data_ptr()
1255  {
1256  return _data.get();
1257  }
1258  const Image3DF* data_ptr() const
1259  {
1260  return _data.get();
1261  }
1262  stir::shared_ptr<Image3DF> data_sptr()
1263  {
1264  return _data;
1265  }
1266  stir::shared_ptr<const Image3DF> data_sptr() const
1267  {
1268  return _data;
1269  }
1270  void set_data_sptr(stir::shared_ptr<Image3DF> sptr_data)
1271  {
1272  _data = sptr_data;
1273  }
1274 
1275  void fill(float v)
1276  {
1277  _data->fill(v);
1278  }
1279  void scale(float s);
1280  float dot(const DataContainer& a_x) const
1281  {
1282  float s;
1283  dot(a_x, &s);
1284  return s;
1285  }
1286  void axpby(
1287  float a, const DataContainer& a_x,
1288  float b, const DataContainer& a_y)
1289  {
1290  axpby(&a, a_x, &b, a_y);
1291  }
1292  void xapyb(
1293  const DataContainer& a_x, float a,
1294  const DataContainer& a_y, float b)
1295  {
1296  xapyb(a_x, &a, a_y, &b);
1297  }
1298  size_t size() const
1299  {
1300  return _data->size_all();
1301  }
1302  virtual Dimensions dimensions() const
1303  {
1304  Dimensions dim;
1305  int d[4];
1306  get_dimensions(d);
1307  dim["z"] = d[0];
1308  dim["y"] = d[1];
1309  dim["x"] = d[2];
1310  return dim;
1311  }
1312  int get_dimensions(int* dim) const;
1313  void get_voxel_sizes(float* vsizes) const;
1314  virtual void get_data(float* data) const;
1315  virtual void set_data(const float* data);
1316  virtual Iterator& begin()
1317  {
1318  _begin.reset(new Iterator(data().begin_all()));
1319  return *_begin;
1320  }
1321  virtual Iterator_const& begin() const
1322  {
1323  _begin_const.reset(new Iterator_const(data().begin_all()));
1324  return *_begin_const;
1325  }
1326  virtual Iterator& end()
1327  {
1328  _end.reset(new Iterator(data().end_all()));
1329  return *_end;
1330  }
1331  virtual Iterator_const& end() const
1332  {
1333  _end_const.reset(new Iterator_const(data().end_all()));
1334  return *_end_const;
1335  }
1336 
1338  std::unique_ptr<STIRImageData> clone() const
1339  {
1340  return std::unique_ptr<STIRImageData>(this->clone_impl());
1341  }
1342 
1346  void zoom_image(const Coord3DF& zooms = { 1.f,1.f,1.f }, const Coord3DF& offsets_in_mm = { 0.f,0.f,0.f },
1347  const Coord3DI& new_sizes = { -1,-1,-1 }, const char* const zoom_options_str = "preserve_sum");
1348 
1352  void zoom_image(const Coord3DF& zooms = { 1.f,1.f,1.f }, const Coord3DF& offsets_in_mm = { 0.f,0.f,0.f },
1353  const Coord3DI& new_sizes = { -1,-1,-1 },
1354  const stir::ZoomOptions zoom_options = stir::ZoomOptions::preserve_sum);
1355 
1358  void move_to_scanner_centre(const STIRAcquisitionData&);
1359 
1361  virtual void set_up_geom_info();
1362 
1363  void unary_op(const DataContainer& a_x, float(*f)(float));
1364  void semibinary_op(const DataContainer& a_x, float y, float(*f)(float, float));
1365  void binary_op(const DataContainer& a_x, const DataContainer& a_y, float(*f)(float, float));
1366 
1367  private:
1369  virtual STIRImageData* clone_impl() const
1370  {
1371  return new STIRImageData(*this);
1372  }
1373 
1374  protected:
1375  stir::shared_ptr<Image3DF> _data;
1376  mutable std::shared_ptr<Iterator> _begin;
1377  mutable std::shared_ptr<Iterator> _end;
1378  mutable std::shared_ptr<Iterator_const> _begin_const;
1379  mutable std::shared_ptr<Iterator_const> _end_const;
1380  };
1381 
1382 } // namespace sirf
1383 
1384 #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:109
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: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:179
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:169
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:137
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:81
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:536
In-memory implementation of STIRAcquisitionData.
Definition: stir_data_containers.h:650
virtual void divide(const DataContainer &x, const DataContainer &y)
*this = the elementwise ratio x / y
Definition: stir_data_containers.h:858
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:817
STIRAcquisitionDataInMemory(const char *filename)
Constructor for STIRAcquisitionDataInMemory from filename.
Definition: stir_data_containers.h:693
virtual void fill_from(const float *d)
Fill from float array.
Definition: stir_data_containers.h:778
virtual void fill(const STIRAcquisitionData &ad)
fill from another STIRAcquisitionData
Definition: stir_data_containers.h:762
virtual float norm() const
returns the norm of this container viewed as a vector
Definition: stir_data_containers.h:803
virtual void multiply(const DataContainer &x, const DataContainer &y)
*this = the elementwise product x*y
Definition: stir_data_containers.h:837
virtual void fill(const float v)
fill with single value
Definition: stir_data_containers.h:749
virtual void copy_to(float *d) const
Copy to float array.
Definition: stir_data_containers.h:791
Definition: stir_data_containers.h:1011
Definition: stir_data_containers.h:960
STIR DiscretisedDensity<3, float> wrapper with added functionality.
Definition: stir_data_containers.h:956
virtual void abs(const DataContainer &x)
*this = the elementwise abs(x)
Definition: stir_data_containers.h:1175
virtual void sqrt(const DataContainer &x)
*this = the elementwise sqrt(x)
Definition: stir_data_containers.h:1187
virtual void divide(const DataContainer &x, const DataContainer &y)
*this = the elementwise ratio x / y
Definition: stir_data_containers.h:1229
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:1225
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:544
virtual void set_up_geom_info()
Populate the geometrical info metadata (from the image's own metadata)
Definition: stir_data_containers.cpp:891
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:838
virtual float norm() const
returns the norm of this container viewed as a vector
Definition: stir_data_containers.cpp:673
std::unique_ptr< STIRImageData > clone() const
Clone and return as unique pointer.
Definition: stir_data_containers.h:1338
virtual void maximum(const DataContainer &x, const DataContainer &y)
*this = the elementwise max(x, y)
Definition: stir_data_containers.h:1233
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:567
virtual bool is_complex() const
Is complex? Unless overwridden (Gadgetron), assume not complex.
Definition: stir_data_containers.h:1112
virtual void sum(void *ptr) const
below all void* are actually float*
Definition: stir_data_containers.cpp:496
virtual void log(const DataContainer &x)
*this = the elementwise log(x)
Definition: stir_data_containers.h:1183
void move_to_scanner_centre(const STIRAcquisitionData &)
Definition: stir_data_containers.cpp:882
virtual void sign(const DataContainer &x)
*this = the elementwise sign(x)
Definition: stir_data_containers.h:1191
virtual void write(const std::string &filename) const
Write to file.
Definition: stir_data_containers.cpp:464
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:576
virtual void minimum(const DataContainer &x, const DataContainer &y)
*this = the elementwise min(x, y)
Definition: stir_data_containers.h:1237
virtual void min(void *ptr) const
calculates the value of this container's element with the smallest real part
Definition: stir_data_containers.cpp:528
virtual void add(const DataContainer &x, const void *ptr_y)
*this = the sum x + y with scalar y
Definition: stir_data_containers.h:1200
virtual void power(const DataContainer &x, const DataContainer &y)
*this = the elementwise pow(x, y)
Definition: stir_data_containers.h:1241
virtual void exp(const DataContainer &x)
*this = the elementwise exp(x)
Definition: stir_data_containers.h:1179
virtual void multiply(const DataContainer &x, const void *ptr_y)
*this = the product x * y with scalar y
Definition: stir_data_containers.h:1195
Definition: stir_data_containers.h:893
std::shared_ptr< STIRAcquisitionData > acquisition_data_template() const
Construct an AcquisitionData object corresponding to the listmode data.
Definition: stir_data_containers.h:917
Defines sirf::iequals.
Abstract base class for SIRF image data.
Definition: GeometricalInfo.cpp:141
STIRAcquisitionData PETAcquisitionData
Definition: stir_data_containers.h:940
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