diff --git a/documentation/STIR-glossary.tex b/documentation/STIR-glossary.tex index b4786d0d79..0aa5e7ad37 100644 --- a/documentation/STIR-glossary.tex +++ b/documentation/STIR-glossary.tex @@ -135,6 +135,9 @@ \section*{Basics} Set of \textbf{merged} \textbf{sinograms} with a common average \textbf{ring difference} as shown in Annex 1. +\item[TOF number] +The line of response is divided $N_t$ TOF positions the numbering goes from 0 to $N_t -1$ + \item[Viewgram] Set of equal azimuth \textbf{merged} \textbf{LORs} of a \textbf{segment}. diff --git a/src/IO/stir_ecat_common.cxx b/src/IO/stir_ecat_common.cxx index 0fa9df608c..ebd49831e9 100644 --- a/src/IO/stir_ecat_common.cxx +++ b/src/IO/stir_ecat_common.cxx @@ -207,8 +207,8 @@ find_timing_poss_sequence(const ProjDataInfo& pdi) timing_pos_sequence[0] = 0; for (int timing_pos_num = 1; timing_pos_num <= max_timing_pos_num; ++timing_pos_num) { - timing_pos_sequence[2 * timing_pos_num - 1] = timing_pos_num; - timing_pos_sequence[2 * timing_pos_num] = -timing_pos_num; + timing_pos_sequence[2 * timing_pos_num - 1] = max_timing_pos_num + timing_pos_num; + timing_pos_sequence[2 * timing_pos_num] = max_timing_pos_num - timing_pos_num; } return timing_pos_sequence; } diff --git a/src/buildblock/ProjDataFromStream.cxx b/src/buildblock/ProjDataFromStream.cxx index bcb47f9c65..8411f09dbd 100644 --- a/src/buildblock/ProjDataFromStream.cxx +++ b/src/buildblock/ProjDataFromStream.cxx @@ -151,6 +151,10 @@ ProjDataFromStream::activate_TOF() void ProjDataFromStream::set_timing_poss_sequence_in_stream(const std::vector& seq) { + if(!(seq[0]==this->proj_data_info_sptr->get_min_tof_pos_num() && + seq[seq.size()-1]==this->proj_data_info_sptr->get_max_tof_pos_num())) + error("the timing position sequence is different from STIR convention 0-max!"); + this->timing_poss_sequence = seq; } diff --git a/src/buildblock/ProjDataInfo.cxx b/src/buildblock/ProjDataInfo.cxx index 05adde73ca..d0979fa14f 100644 --- a/src/buildblock/ProjDataInfo.cxx +++ b/src/buildblock/ProjDataInfo.cxx @@ -68,10 +68,7 @@ START_NAMESPACE_STIR float ProjDataInfo::get_k(const Bin& bin) const { - if (!(num_tof_bins % 2)) - return bin.timing_pos_num() * tof_increament_in_mm + tof_increament_in_mm / 2.f; - else - return (bin.timing_pos_num() * tof_increament_in_mm); + return (bin.timing_pos_num() - (num_tof_bins - 1) / 2.f) * tof_increament_in_mm; } double @@ -212,14 +209,15 @@ ProjDataInfo::set_tof_mash_factor(const int new_num) tof_increament_in_mm = tof_delta_time_to_mm(tof_mash_factor * scanner_ptr->get_size_of_timing_pos()); // TODO cope with even numbers! - min_tof_pos_num = -(scanner_ptr->get_max_num_timing_poss() / tof_mash_factor) / 2; - max_tof_pos_num = min_tof_pos_num + (scanner_ptr->get_max_num_timing_poss() / tof_mash_factor) - 1; + min_tof_pos_num = 0; //- (scanner_ptr->get_max_num_timing_poss() / tof_mash_factor)/2; + max_tof_pos_num = (scanner_ptr->get_max_num_timing_poss() / tof_mash_factor) + - 1; // min_tof_pos_num + (scanner_ptr->get_max_num_timing_poss() / tof_mash_factor) -1; num_tof_bins = max_tof_pos_num - min_tof_pos_num + 1; // Ensure that we have a central tof bin. - if (num_tof_bins % 2 == 0) - error("ProjDataInfo: Number of TOF bins should be an odd number. Abort."); + // if (num_tof_bins%2 == 0) + // error("ProjDataInfo: Number of TOF bins should be an odd number. Abort."); // Upper and lower boundaries of the timing poss; tof_bin_boundaries_mm.grow(min_tof_pos_num, max_tof_pos_num); diff --git a/src/buildblock/ProjDataInfoCylindrical.cxx b/src/buildblock/ProjDataInfoCylindrical.cxx index 8878214a0a..16f30304f0 100644 --- a/src/buildblock/ProjDataInfoCylindrical.cxx +++ b/src/buildblock/ProjDataInfoCylindrical.cxx @@ -534,12 +534,14 @@ ProjDataInfoCylindrical::get_LOR(LORInAxialAndNoArcCorrSinogramCoordinates(z1, z2, + phi, asin(s_in_mm / get_ring_radius()), get_ring_radius(), - false); // needs to set "swapped" to false given above code + swap); // needs to set "swapped" to false given above code } #if 0 diff --git a/src/buildblock/ProjDataInfoCylindricalNoArcCorr.cxx b/src/buildblock/ProjDataInfoCylindricalNoArcCorr.cxx index 93b2e49169..1355df9c15 100644 --- a/src/buildblock/ProjDataInfoCylindricalNoArcCorr.cxx +++ b/src/buildblock/ProjDataInfoCylindricalNoArcCorr.cxx @@ -346,8 +346,12 @@ ProjDataInfoCylindricalNoArcCorr::get_all_det_pos_pairs_for_bin(vectorsecond; dps[current_dp_num].timing_pos() = uncompressed_timing_pos_num; + ++current_dp_num; } } @@ -470,8 +475,7 @@ ProjDataInfoCylindricalNoArcCorr::find_cartesian_coordinates_given_scanner_coord { const int num_detectors_per_ring = get_scanner_ptr()->get_num_detectors_per_ring(); - int d1, d2, r1, r2; - int tpos = timing_pos_num; + int d1, d2, r1, r2, tpos; this->initialise_det1det2_to_uncompressed_view_tangpos_if_not_done_yet(); @@ -481,7 +485,7 @@ ProjDataInfoCylindricalNoArcCorr::find_cartesian_coordinates_given_scanner_coord d2 = det1; r1 = Ring_B; r2 = Ring_A; - tpos *= -1; + tpos = get_max_tof_pos_num() - timing_pos_num; } else { @@ -489,6 +493,7 @@ ProjDataInfoCylindricalNoArcCorr::find_cartesian_coordinates_given_scanner_coord d2 = det2; r1 = Ring_A; r2 = Ring_B; + tpos = timing_pos_num; } #if 0 @@ -519,7 +524,8 @@ ProjDataInfoCylindricalNoArcCorr::find_cartesian_coordinates_given_scanner_coord coord_2 = lor.p2(); #endif - if (tpos < 0) + + if (tpos - get_max_tof_pos_num() / 2.F < 0) std::swap(coord_1, coord_2); } diff --git a/src/include/stir/ProjDataInfoCylindricalNoArcCorr.inl b/src/include/stir/ProjDataInfoCylindricalNoArcCorr.inl index 9f3678de3f..6c73c43b84 100644 --- a/src/include/stir/ProjDataInfoCylindricalNoArcCorr.inl +++ b/src/include/stir/ProjDataInfoCylindricalNoArcCorr.inl @@ -124,7 +124,7 @@ ProjDataInfoCylindricalNoArcCorr::get_bin_for_det_pair( } else { - bin.timing_pos_num() = -timing_pos_num; + bin.timing_pos_num() = get_max_tof_pos_num() - timing_pos_num; return get_segment_axial_pos_num_for_ring_pair(bin.segment_num(), bin.axial_pos_num(), ring_num2, ring_num1); } } @@ -137,9 +137,8 @@ ProjDataInfoCylindricalNoArcCorr::get_bin_for_det_pos_pair(Bin& bin, const Detec dp.pos1().axial_coord(), dp.pos2().tangential_coord(), dp.pos2().axial_coord(), - this->get_tof_mash_factor() == 0 - ? 0 // use timing_pos==0 in the nonTOF case - : stir::round((float)dp.timing_pos() / this->get_tof_mash_factor())); + this->get_tof_mash_factor() == 0 ? 0 // use timing_pos==0 in the nonTOF case + : (int)(dp.timing_pos() / this->get_tof_mash_factor())); } void ProjDataInfoCylindricalNoArcCorr::get_det_pair_for_bin( @@ -166,7 +165,7 @@ ProjDataInfoCylindricalNoArcCorr::get_det_pos_pair_for_bin(DetectionPositionPair // lousy work around because types don't match (short/int). TODO remove! int t1, a1, t2, a2; get_det_pair_for_bin(t1, a1, t2, a2, bin); - if (bin.timing_pos_num() >= 0) + if (bin.timing_pos_num() - get_max_tof_pos_num() / 2.F >= 0) { dp.pos1().tangential_coord() = t1; dp.pos1().axial_coord() = a1; diff --git a/src/include/stir/recon_buildblock/DataSymmetriesForBins_PET_CartesianGrid.inl b/src/include/stir/recon_buildblock/DataSymmetriesForBins_PET_CartesianGrid.inl index 16f92a2e70..de459093c1 100644 --- a/src/include/stir/recon_buildblock/DataSymmetriesForBins_PET_CartesianGrid.inl +++ b/src/include/stir/recon_buildblock/DataSymmetriesForBins_PET_CartesianGrid.inl @@ -259,7 +259,7 @@ DataSymmetriesForBins_PET_CartesianGrid::find_sym_op_general_bin(int s, int segm view180, axial_pos_shift, z_shift, transform_z); // s < 0 } else // neg_plus90 - ///// + ///// if (segment_num < 0) { if (!do_symmetry_swap_s || s > 0) @@ -316,8 +316,8 @@ DataSymmetriesForBins_PET_CartesianGrid::find_sym_op_general_bin(int s, int segm else return new SymmetryOperation_PET_CartesianGrid_swap_ymy_zq(view180, axial_pos_shift, z_shift, transform_z); } // segment_num == 0 - // /*else{ if ( !do_symmetry_swap_s || s > 0 ) return new SymmetryOperation_PET_CartesianGrid_swap_xmx(); else - // return new SymmetryOperation_PET_CartesianGrid_swap_ymy(view180, axial_pos_shift, z_shift);}*/ + // /*else{ if ( !do_symmetry_swap_s || s > 0 ) return new SymmetryOperation_PET_CartesianGrid_swap_xmx(); + // else return new SymmetryOperation_PET_CartesianGrid_swap_ymy(view180, axial_pos_shift, z_shift);}*/ } else { @@ -326,7 +326,8 @@ DataSymmetriesForBins_PET_CartesianGrid::find_sym_op_general_bin(int s, int segm if (!do_symmetry_swap_segment || segment_num > 0) { if (do_symmetry_swap_s && s < 0) - return new SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy_zq(view180, axial_pos_shift, z_shift, transform_z); + return new SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy_zq( + view180, axial_pos_shift, z_shift, transform_z, proj_data_info_ptr->get_max_tof_pos_num()); else { if (z_shift == 0) @@ -341,14 +342,18 @@ DataSymmetriesForBins_PET_CartesianGrid::find_sym_op_general_bin(int s, int segm return new SymmetryOperation_PET_CartesianGrid_swap_zq(view180, axial_pos_shift, z_shift, transform_z); else*/ if (do_symmetry_swap_s && s < 0) - return new SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy(view180, axial_pos_shift, z_shift); + return new SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy( + view180, axial_pos_shift, z_shift, proj_data_info_ptr->get_max_tof_pos_num()); else return new SymmetryOperation_PET_CartesianGrid_swap_zq(view180, axial_pos_shift, z_shift, transform_z); // s > 0 } else // segment_num = 0 { + if (do_symmetry_swap_s && s < 0) - return new SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy(view180, axial_pos_shift, z_shift); + return new SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy( + view180, axial_pos_shift, z_shift, proj_data_info_ptr->get_max_tof_pos_num()); + else { if (z_shift == 0) @@ -462,7 +467,7 @@ DataSymmetriesForBins_PET_CartesianGrid::find_basic_bin( { // when swap_s, must invert timing pos for lor probs. Symmetry operation should correct bin tangential_pos_num *= -1; - timing_pos_num *= -1; + timing_pos_num = proj_data_info_ptr->get_max_tof_pos_num() - timing_pos_num; change = true; } if (do_symmetry_shift_z && axial_pos_num != 0) diff --git a/src/include/stir/recon_buildblock/PoissonLogLikelihoodWithLinearModelForMeanAndProjData.h b/src/include/stir/recon_buildblock/PoissonLogLikelihoodWithLinearModelForMeanAndProjData.h index 5ad9836700..7556a1c0af 100644 --- a/src/include/stir/recon_buildblock/PoissonLogLikelihoodWithLinearModelForMeanAndProjData.h +++ b/src/include/stir/recon_buildblock/PoissonLogLikelihoodWithLinearModelForMeanAndProjData.h @@ -174,7 +174,7 @@ class PoissonLogLikelihoodWithLinearModelForMeanAndProjData const ProjData& get_proj_data() const; const shared_ptr& get_proj_data_sptr() const; const int get_max_segment_num_to_process() const; - const int get_max_timing_pos_num_to_process() const; + const int get_max_num_central_timing_poss_to_process() const; const bool get_zero_seg0_end_planes() const; const ProjData& get_additive_proj_data() const; const shared_ptr& get_additive_proj_data_sptr() const; @@ -196,7 +196,7 @@ class PoissonLogLikelihoodWithLinearModelForMeanAndProjData int set_num_subsets(const int num_subsets) override; void set_proj_data_sptr(const shared_ptr&); void set_max_segment_num_to_process(const int); - void set_max_timing_pos_num_to_process(const int); + void set_max_num_central_timing_poss_to_process(const int); void set_zero_seg0_end_planes(const bool); // N.E. Changed to ExamData void set_additive_proj_data_sptr(const shared_ptr&) override; @@ -298,7 +298,8 @@ class PoissonLogLikelihoodWithLinearModelForMeanAndProjData //! the maximum absolute time-of-flight bin number to use in the reconstruction /*! convention: if -1, use get_max_tof_pos_num()*/ - int max_timing_pos_num_to_process; + int max_num_central_timing_poss_to_process; + int tof_bin_shift; /**********************/ ParseAndCreateFrom target_parameter_parser; diff --git a/src/include/stir/recon_buildblock/SymmetryOperations_PET_CartesianGrid.h b/src/include/stir/recon_buildblock/SymmetryOperations_PET_CartesianGrid.h index ea93d0431d..8704072712 100644 --- a/src/include/stir/recon_buildblock/SymmetryOperations_PET_CartesianGrid.h +++ b/src/include/stir/recon_buildblock/SymmetryOperations_PET_CartesianGrid.h @@ -299,14 +299,14 @@ class SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy_zq : public SymmetryOpera typedef SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy_zq self; public: - SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy_zq(const int num_views, - const int axial_pos_shift, - const int z_shift, - const int q) + SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy_zq( + const int num_views, const int axial_pos_shift, const int z_shift, const int q, const int max_tof_pos_num) : view180(num_views), axial_pos_shift(axial_pos_shift), z_shift(z_shift), - q(q) + q(q), + timing_shift(max_tof_pos_num) + {} inline void transform_bin_coordinates(Bin&) const override; @@ -322,6 +322,7 @@ class SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy_zq : public SymmetryOpera int axial_pos_shift; int z_shift; int q; + int timing_shift; }; class SymmetryOperation_PET_CartesianGrid_swap_xy_ymx_zq : public SymmetryOperation @@ -441,10 +442,14 @@ class SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy : public SymmetryOperatio typedef SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy self; public: - SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy(const int num_views, const int axial_pos_shift, const int z_shift) + SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy(const int num_views, + const int axial_pos_shift, + const int z_shift, + const int max_tof_pos_num) : view180(num_views), axial_pos_shift(axial_pos_shift), - z_shift(z_shift) + z_shift(z_shift), + timing_shift(max_tof_pos_num) {} inline void transform_bin_coordinates(Bin&) const override; @@ -459,6 +464,7 @@ class SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy : public SymmetryOperatio int view180; int axial_pos_shift; int z_shift; + int timing_shift; }; class SymmetryOperation_PET_CartesianGrid_swap_xmy_ymx_zq : public SymmetryOperation diff --git a/src/include/stir/recon_buildblock/SymmetryOperations_PET_CartesianGrid.inl b/src/include/stir/recon_buildblock/SymmetryOperations_PET_CartesianGrid.inl index c6a966f38b..86bab6438a 100644 --- a/src/include/stir/recon_buildblock/SymmetryOperations_PET_CartesianGrid.inl +++ b/src/include/stir/recon_buildblock/SymmetryOperations_PET_CartesianGrid.inl @@ -328,7 +328,7 @@ SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy_zq::transform_bin_coordinates(B { b.axial_pos_num() += axial_pos_shift; b.tangential_pos_num() *= -1; - b.timing_pos_num() *= -1; + b.timing_pos_num() = timing_shift - b.timing_pos_num(); } void @@ -514,7 +514,7 @@ SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy::transform_bin_coordinates(Bin& b.axial_pos_num() += axial_pos_shift; b.segment_num() *= -1; b.tangential_pos_num() *= -1; - b.timing_pos_num() *= -1; + b.timing_pos_num() = timing_shift - b.timing_pos_num(); } void SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy::transform_view_segment_indices(ViewSegmentNumbers& vs) const diff --git a/src/recon_buildblock/PoissonLogLikelihoodWithLinearModelForMeanAndProjData.cxx b/src/recon_buildblock/PoissonLogLikelihoodWithLinearModelForMeanAndProjData.cxx index 3cbd5832a3..2095e523a8 100644 --- a/src/recon_buildblock/PoissonLogLikelihoodWithLinearModelForMeanAndProjData.cxx +++ b/src/recon_buildblock/PoissonLogLikelihoodWithLinearModelForMeanAndProjData.cxx @@ -91,7 +91,7 @@ PoissonLogLikelihoodWithLinearModelForMeanAndProjData::set_defaults() this->input_filename = ""; this->max_segment_num_to_process = -1; - this->max_timing_pos_num_to_process = 0; + this->max_num_central_timing_poss_to_process = -1; // KT 20/06/2001 disabled // num_views_to_add=1; this->proj_data_sptr.reset(); // MJ added @@ -313,9 +313,9 @@ PoissonLogLikelihoodWithLinearModelForMeanAndProjData::get_max_segment_ template const int -PoissonLogLikelihoodWithLinearModelForMeanAndProjData::get_max_timing_pos_num_to_process() const +PoissonLogLikelihoodWithLinearModelForMeanAndProjData::get_max_num_central_timing_poss_to_process() const { - return this->max_timing_pos_num_to_process; + return this->max_num_central_timing_poss_to_process; } template @@ -412,10 +412,11 @@ PoissonLogLikelihoodWithLinearModelForMeanAndProjData::set_max_segment_ template void -PoissonLogLikelihoodWithLinearModelForMeanAndProjData::set_max_timing_pos_num_to_process(const int arg) +PoissonLogLikelihoodWithLinearModelForMeanAndProjData::set_max_num_central_timing_poss_to_process(const int arg) + { - this->already_set_up = this->already_set_up && (this->max_timing_pos_num_to_process == arg); - this->max_timing_pos_num_to_process = arg; + this->already_set_up = this->already_set_up && (this->max_num_central_timing_poss_to_process == arg); + this->max_num_central_timing_poss_to_process = arg; } template @@ -592,7 +593,10 @@ PoissonLogLikelihoodWithLinearModelForMeanAndProjData::set_up_before_se return Succeeded::no; } - this->max_timing_pos_num_to_process = this->proj_data_sptr->get_max_tof_pos_num(); + this->max_num_central_timing_poss_to_process = this->proj_data_sptr->get_max_tof_pos_num(); + // The following "shift"is used to estimate the maximum and minimum tof position number to process + // i.e. min_pos= num_tof_bins+shift and max_pos= num_tof_bins-shift if we use all than shift =0 + this->tof_bin_shift = (proj_data_sptr->get_num_tof_poss() - this->max_num_central_timing_poss_to_process) / 2; shared_ptr proj_data_info_sptr(this->proj_data_sptr->get_proj_data_info_sptr()->clone()); @@ -723,8 +727,8 @@ PoissonLogLikelihoodWithLinearModelForMeanAndProjData::actual_compute_s this->additive_proj_data_sptr, this->normalisation_sptr, caching_info_ptr, - -this->max_timing_pos_num_to_process, - this->max_timing_pos_num_to_process, + proj_data_sptr->get_min_tof_pos_num() + tof_bin_shift, + proj_data_sptr->get_max_tof_pos_num() - tof_bin_shift, add_sensitivity); } @@ -768,8 +772,8 @@ PoissonLogLikelihoodWithLinearModelForMeanAndProjData::actual_compute_o this->get_time_frame_definitions().get_start_time(this->get_time_frame_num()), this->get_time_frame_definitions().get_end_time(this->get_time_frame_num()), this->caching_info_ptr, - -this->max_timing_pos_num_to_process, - this->max_timing_pos_num_to_process); + proj_data_sptr->get_min_tof_pos_num() + tof_bin_shift, + proj_data_sptr->get_max_tof_pos_num() - tof_bin_shift); return accum; } @@ -782,10 +786,11 @@ sum_projection_data() const { float counts=0.0F; - + int min_timing_poss_to_process = proj_data_sptr->get_min_tof_pos_num() + tof_bin_shift; + int max_timing_poss_to_process = proj_data_sptr->get_max_tof_pos_num() - tof_bin_shift; for (int segment_num = -max_segment_num_to_process; segment_num <= max_segment_num_to_process; ++segment_num) { - for (int timing_pos_num = -max_timing_pos_num_to_process; timing_pos_num <= max_timing_pos_num_to_process; ++timing_pos_num) + for (int timing_pos_num = min_timing_poss_to_process; timing_pos_num <= max_timing_poss_to_process; ++timing_pos_num) { for (int view_num = proj_data_sptr->get_min_view_num(); view_num <= proj_data_sptr->get_max_view_num(); @@ -884,8 +889,8 @@ PoissonLogLikelihoodWithLinearModelForMeanAndProjData::add_subset_sensi this->get_time_frame_definitions().get_start_time(this->get_time_frame_num()), this->get_time_frame_definitions().get_end_time(this->get_time_frame_num()), this->caching_info_ptr, - use_tofsens ? -this->max_timing_pos_num_to_process : 0, - use_tofsens ? this->max_timing_pos_num_to_process : 0); + use_tofsens ? proj_data_sptr->get_min_tof_pos_num() + tof_bin_shift : 0, + use_tofsens ? proj_data_sptr->get_max_tof_pos_num() - tof_bin_shift : 0); std::transform(sensitivity.begin_all(), sensitivity.end_all(), diff --git a/src/recon_test/test_DataSymmetriesForBins_PET_CartesianGrid.cxx b/src/recon_test/test_DataSymmetriesForBins_PET_CartesianGrid.cxx index 0f68e53fa2..a3f1423458 100644 --- a/src/recon_test/test_DataSymmetriesForBins_PET_CartesianGrid.cxx +++ b/src/recon_test/test_DataSymmetriesForBins_PET_CartesianGrid.cxx @@ -123,13 +123,7 @@ DataSymmetriesForBins_PET_CartesianGridTests::run_tests_2_proj_matrices_1_bin(co { // SYM const Bin bin=*bin_iter; - cerr << "\nCurrent bin: \tsegment = " << bin.segment_num() << ", \taxial pos " << bin.axial_pos_num() - << ", \tview = " << bin.view_num() << ", \ttangential_pos_num = " << bin.tangential_pos_num() - << ", timing position index = " << bin.timing_pos_num() - << "\nSymm bin: \t\tsegment = " << elems_with_sym.get_bin().segment_num() << ", \taxial pos " - << elems_with_sym.get_bin().axial_pos_num() << ", \tview = " << elems_with_sym.get_bin().view_num() - << ", \ttangential_pos_num = " << elems_with_sym.get_bin().tangential_pos_num() - << ", timing position index = " << bin.timing_pos_num() << "\n"; + cerr << "\nCurrent bin: " << elems_no_sym.get_bin() << "\nSymm bin: " << elems_with_sym.get_bin() << "\n"; if (elems_no_sym != elems_with_sym) { diff --git a/src/test/test_proj_data_info.cxx b/src/test/test_proj_data_info.cxx index c02ada1f11..df9b1a072d 100644 --- a/src/test/test_proj_data_info.cxx +++ b/src/test/test_proj_data_info.cxx @@ -150,8 +150,9 @@ ProjDataInfoTests::test_generic_proj_data_info(ProjDataInfo& proj_data_info) check_if_equal(proj_data_info.get_max_tof_pos_num() - proj_data_info.get_min_tof_pos_num() + 1, proj_data_info.get_num_tof_poss(), "basic check on min/max/num_tof_pos_num"); - check_if_equal(proj_data_info.get_max_tof_pos_num() + proj_data_info.get_min_tof_pos_num(), + check_if_equal(proj_data_info.get_min_tof_pos_num(), 0, + "check on min/max_tof_pos_num being (almost) centred"); check_if_equal(proj_data_info.get_max_view_num() - proj_data_info.get_min_view_num() + 1, proj_data_info.get_num_views(), @@ -215,28 +216,26 @@ ProjDataInfoTests::test_generic_proj_data_info(ProjDataInfo& proj_data_info) { const Bin new_bin = proj_data_info.get_bin(lor, delta_time); + const bool views_are_close + = intabs(org_bin.view_num() - new_bin.view_num()) + < proj_data_info.get_num_views() - intabs(org_bin.view_num() - new_bin.view_num()); #if 1 // the differences need to also consider wrap-around in views, which would flip tangential pos and segment // and TOF bin - const int diff_segment_num - = intabs(org_bin.view_num() - new_bin.view_num()) - < proj_data_info.get_num_views() - intabs(org_bin.view_num() - new_bin.view_num()) - ? intabs(org_bin.segment_num() - new_bin.segment_num()) - : intabs(org_bin.segment_num() + new_bin.segment_num()); + const int diff_segment_num = views_are_close ? intabs(org_bin.segment_num() - new_bin.segment_num()) + : intabs(org_bin.segment_num() + new_bin.segment_num()); const int diff_view_num = min(intabs(org_bin.view_num() - new_bin.view_num()), proj_data_info.get_num_views() - intabs(org_bin.view_num() - new_bin.view_num())); const int diff_axial_pos_num = intabs(org_bin.axial_pos_num() - new_bin.axial_pos_num()); const int diff_tangential_pos_num - = intabs(org_bin.view_num() - new_bin.view_num()) - < proj_data_info.get_num_views() - intabs(org_bin.view_num() - new_bin.view_num()) - ? intabs(org_bin.tangential_pos_num() - new_bin.tangential_pos_num()) - : intabs(org_bin.tangential_pos_num() + new_bin.tangential_pos_num()); + = views_are_close ? intabs(org_bin.tangential_pos_num() - new_bin.tangential_pos_num()) + : intabs(org_bin.tangential_pos_num() + new_bin.tangential_pos_num()); const int diff_timing_pos_num - = intabs(org_bin.view_num() - new_bin.view_num()) - < proj_data_info.get_num_views() - intabs(org_bin.view_num() - new_bin.view_num()) - ? intabs(org_bin.timing_pos_num() - new_bin.timing_pos_num()) - : intabs(org_bin.timing_pos_num() + new_bin.timing_pos_num()); + = views_are_close ? intabs(org_bin.timing_pos_num() - new_bin.timing_pos_num()) + : intabs(org_bin.timing_pos_num() + - (proj_data_info.get_max_tof_pos_num() - new_bin.timing_pos_num())); + if (new_bin.get_bin_value() > 0) { if (diff_segment_num > max_diff_segment_num) @@ -286,28 +285,26 @@ ProjDataInfoTests::test_generic_proj_data_info(ProjDataInfo& proj_data_info) << ", y2=" << lor_as_points.p2().y() << ", x2=" << lor_as_points.p2().x() << std::endl; #endif const Bin new_bin = proj_data_info.get_bin(lor_as_points, proj_data_info.get_tof_delta_time(org_bin)); + const bool views_are_close + = intabs(org_bin.view_num() - new_bin.view_num()) + < proj_data_info.get_num_views() - intabs(org_bin.view_num() - new_bin.view_num()); #if 1 // the differences need to also consider wrap-around in views, which would flip tangential pos and segment - const int diff_segment_num - = intabs(org_bin.view_num() - new_bin.view_num()) - < proj_data_info.get_num_views() - intabs(org_bin.view_num() - new_bin.view_num()) - ? intabs(org_bin.segment_num() - new_bin.segment_num()) - : intabs(org_bin.segment_num() + new_bin.segment_num()); + const int diff_segment_num = views_are_close ? intabs(org_bin.segment_num() - new_bin.segment_num()) + : intabs(org_bin.segment_num() + new_bin.segment_num()); const int diff_view_num = min(intabs(org_bin.view_num() - new_bin.view_num()), proj_data_info.get_num_views() - intabs(org_bin.view_num() - new_bin.view_num())); const int diff_axial_pos_num = intabs(org_bin.axial_pos_num() - new_bin.axial_pos_num()); const int diff_tangential_pos_num - = intabs(org_bin.view_num() - new_bin.view_num()) - < proj_data_info.get_num_views() - intabs(org_bin.view_num() - new_bin.view_num()) - ? intabs(org_bin.tangential_pos_num() - new_bin.tangential_pos_num()) - : intabs(org_bin.tangential_pos_num() + new_bin.tangential_pos_num()); + = views_are_close ? intabs(org_bin.tangential_pos_num() - new_bin.tangential_pos_num()) + : intabs(org_bin.tangential_pos_num() + new_bin.tangential_pos_num()); const int diff_timing_pos_num - = intabs(org_bin.view_num() - new_bin.view_num()) - < proj_data_info.get_num_views() - intabs(org_bin.view_num() - new_bin.view_num()) - ? intabs(org_bin.timing_pos_num() - new_bin.timing_pos_num()) - : intabs(org_bin.timing_pos_num() + new_bin.timing_pos_num()); + = views_are_close ? intabs(org_bin.timing_pos_num() - new_bin.timing_pos_num()) + : intabs(org_bin.timing_pos_num() + - (proj_data_info.get_max_tof_pos_num() - new_bin.timing_pos_num())); + if (new_bin.get_bin_value() > 0) { if (diff_segment_num > max_diff_segment_num) diff --git a/src/test/test_time_of_flight.cxx b/src/test/test_time_of_flight.cxx index 66357f7e9e..1c0f7400cf 100644 --- a/src/test/test_time_of_flight.cxx +++ b/src/test/test_time_of_flight.cxx @@ -259,6 +259,7 @@ TOF_Tests::test_CListEventROOT() DetectionPositionPair<> det_pos; event.get_detection_position(det_pos); + LORAs2Points lor_2pts(event.get_LOR()); LORInAxialAndNoArcCorrSinogramCoordinates lor_sc; test_proj_data_info_sptr->get_LOR(lor_sc, bin); @@ -284,7 +285,7 @@ TOF_Tests::test_CListEventROOT() det_pos.pos2(), "CListEventROOT: get_detection_position with swapped detectors: equal timing_pos, but different pos2"); } - else if (det_pos_swapped.timing_pos() == -det_pos.timing_pos()) + else if (det_pos_swapped.timing_pos() == event.get_scanner_ptr()->get_max_num_timing_poss() - 1 - det_pos.timing_pos()) { check_if_equal( det_pos_swapped.pos2(),