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