|
48 | 48 | #include "stir/IO/stir_ecat7.h"
|
49 | 49 | #include "stir/ViewgramIndices.h"
|
50 | 50 | #include "stir/is_null_ptr.h"
|
| 51 | +#include "stir/numerics/norm.h" |
51 | 52 | #include <cstring>
|
52 | 53 | #include <fstream>
|
53 | 54 | #include <algorithm>
|
@@ -478,6 +479,167 @@ ProjData::sapyb(const ProjData& a, const ProjData& y, const ProjData& b)
|
478 | 479 | this->xapyb(*this, a, y, b);
|
479 | 480 | }
|
480 | 481 |
|
| 482 | +float |
| 483 | +ProjData::sum() const |
| 484 | +{ |
| 485 | + double t = 0.; |
| 486 | + for (int timing_pos_num = this->get_min_tof_pos_num(); timing_pos_num <= this->get_max_tof_pos_num(); ++timing_pos_num) |
| 487 | + for (int s = this->get_min_segment_num(); s <= this->get_max_segment_num(); ++s) |
| 488 | + { |
| 489 | + const SegmentIndices ind(s, timing_pos_num); |
| 490 | + t += this->get_segment_by_sinogram(ind).sum(); |
| 491 | + } |
| 492 | + return static_cast<float>(t); |
| 493 | +} |
| 494 | + |
| 495 | +float |
| 496 | +ProjData::find_max() const |
| 497 | +{ |
| 498 | + float t = 0; |
| 499 | + bool init = true; |
| 500 | + for (int timing_pos_num = this->get_min_tof_pos_num(); timing_pos_num <= this->get_max_tof_pos_num(); ++timing_pos_num) |
| 501 | + for (int s = this->get_min_segment_num(); s <= this->get_max_segment_num(); ++s) |
| 502 | + { |
| 503 | + const SegmentIndices ind(s, timing_pos_num); |
| 504 | + const auto t_seg = this->get_segment_by_sinogram(ind).find_max(); |
| 505 | + if (init) |
| 506 | + { |
| 507 | + init = false; |
| 508 | + t = t_seg; |
| 509 | + } |
| 510 | + else |
| 511 | + { |
| 512 | + t = std::max(t, t_seg); |
| 513 | + } |
| 514 | + } |
| 515 | + return t; |
| 516 | +} |
| 517 | + |
| 518 | +float |
| 519 | +ProjData::find_min() const |
| 520 | +{ |
| 521 | + float t = 0; |
| 522 | + bool init = true; |
| 523 | + for (int timing_pos_num = this->get_min_tof_pos_num(); timing_pos_num <= this->get_max_tof_pos_num(); ++timing_pos_num) |
| 524 | + for (int s = this->get_min_segment_num(); s <= this->get_max_segment_num(); ++s) |
| 525 | + { |
| 526 | + const SegmentIndices ind(s, timing_pos_num); |
| 527 | + const auto t_seg = this->get_segment_by_sinogram(ind).find_min(); |
| 528 | + if (init) |
| 529 | + { |
| 530 | + init = false; |
| 531 | + t = t_seg; |
| 532 | + } |
| 533 | + else |
| 534 | + { |
| 535 | + t = std::min(t, t_seg); |
| 536 | + } |
| 537 | + } |
| 538 | + return t; |
| 539 | +} |
| 540 | + |
| 541 | +double |
| 542 | +ProjData::norm_squared() const |
| 543 | +{ |
| 544 | + double t = 0.; |
| 545 | + for (int timing_pos_num = this->get_min_tof_pos_num(); timing_pos_num <= this->get_max_tof_pos_num(); ++timing_pos_num) |
| 546 | + for (int s = this->get_min_segment_num(); s <= this->get_max_segment_num(); ++s) |
| 547 | + { |
| 548 | + const SegmentIndices ind(s, timing_pos_num); |
| 549 | + const auto seg = this->get_segment_by_sinogram(ind); |
| 550 | + t += stir::norm_squared(seg.begin_all(), seg.end_all()); |
| 551 | + } |
| 552 | + return t; |
| 553 | +} |
| 554 | + |
| 555 | +double |
| 556 | +ProjData::norm() const |
| 557 | +{ |
| 558 | + return std::sqrt(this->norm_squared()); |
| 559 | +} |
| 560 | + |
| 561 | +// static helper functions to iterate over segment and apply a function |
| 562 | + |
| 563 | +// func(s1, s2) is supposed to modify s1 |
| 564 | +template <typename Func> |
| 565 | +static ProjData& |
| 566 | +apply_func(ProjData& self, const ProjData& arg, Func func) |
| 567 | +{ |
| 568 | + for (int timing_pos_num = self.get_min_tof_pos_num(); timing_pos_num <= self.get_max_tof_pos_num(); ++timing_pos_num) |
| 569 | + for (int s = self.get_min_segment_num(); s <= self.get_max_segment_num(); ++s) |
| 570 | + { |
| 571 | + const SegmentIndices ind(s, timing_pos_num); |
| 572 | + auto seg = self.get_segment_by_sinogram(ind); |
| 573 | + func(seg, arg.get_segment_by_sinogram(ind)); |
| 574 | + self.set_segment(seg); |
| 575 | + } |
| 576 | + return self; |
| 577 | +} |
| 578 | + |
| 579 | +// func(s1) is supposed to modify s1 |
| 580 | +template <typename Func> |
| 581 | +static ProjData& |
| 582 | +apply_func(ProjData& self, Func func) |
| 583 | +{ |
| 584 | + for (int timing_pos_num = self.get_min_tof_pos_num(); timing_pos_num <= self.get_max_tof_pos_num(); ++timing_pos_num) |
| 585 | + for (int s = self.get_min_segment_num(); s <= self.get_max_segment_num(); ++s) |
| 586 | + { |
| 587 | + const SegmentIndices ind(s, timing_pos_num); |
| 588 | + auto seg = self.get_segment_by_sinogram(ind); |
| 589 | + func(seg); |
| 590 | + self.set_segment(seg); |
| 591 | + } |
| 592 | + return self; |
| 593 | +} |
| 594 | + |
| 595 | +ProjData& |
| 596 | +ProjData::operator+=(const ProjData& arg) |
| 597 | +{ |
| 598 | + return apply_func(*this, arg, [](SegmentBySinogram<float>& s, const SegmentBySinogram<float>& s_arg) { s += s_arg; }); |
| 599 | +} |
| 600 | + |
| 601 | +ProjData& |
| 602 | +ProjData::operator-=(const ProjData& arg) |
| 603 | +{ |
| 604 | + return apply_func(*this, arg, [](SegmentBySinogram<float>& s, const SegmentBySinogram<float>& s_arg) { s -= s_arg; }); |
| 605 | +} |
| 606 | + |
| 607 | +ProjData& |
| 608 | +ProjData::operator*=(const ProjData& arg) |
| 609 | +{ |
| 610 | + return apply_func(*this, arg, [](SegmentBySinogram<float>& s, const SegmentBySinogram<float>& s_arg) { s *= s_arg; }); |
| 611 | +} |
| 612 | + |
| 613 | +ProjData& |
| 614 | +ProjData::operator/=(const ProjData& arg) |
| 615 | +{ |
| 616 | + return apply_func(*this, arg, [](SegmentBySinogram<float>& s, const SegmentBySinogram<float>& s_arg) { s /= s_arg; }); |
| 617 | +} |
| 618 | + |
| 619 | +ProjData& |
| 620 | +ProjData::operator+=(float arg) |
| 621 | +{ |
| 622 | + return apply_func(*this, [arg](SegmentBySinogram<float>& s) { s += arg; }); |
| 623 | +} |
| 624 | + |
| 625 | +ProjData& |
| 626 | +ProjData::operator-=(float arg) |
| 627 | +{ |
| 628 | + return apply_func(*this, [arg](SegmentBySinogram<float>& s) { s -= arg; }); |
| 629 | +} |
| 630 | + |
| 631 | +ProjData& |
| 632 | +ProjData::operator*=(float arg) |
| 633 | +{ |
| 634 | + return apply_func(*this, [arg](SegmentBySinogram<float>& s) { s *= arg; }); |
| 635 | +} |
| 636 | + |
| 637 | +ProjData& |
| 638 | +ProjData::operator/=(float arg) |
| 639 | +{ |
| 640 | + return apply_func(*this, [arg](SegmentBySinogram<float>& s) { s /= arg; }); |
| 641 | +} |
| 642 | + |
481 | 643 | std::vector<int>
|
482 | 644 | ProjData::standard_segment_sequence(const ProjDataInfo& pdi)
|
483 | 645 | {
|
|
0 commit comments