Skip to content

Conversation

@SomayehSaghamanesh
Copy link

Changes in this pull request

Added two models of SAFIR scanners (generic geometry) to stir's scanners list.
Added two utilities to convert and trim projections.

Testing performed

STIR-6 build tests were performed successfully without any error. Tests for SAFIR I/II data conversion and image reconstructions were performed successfully.

Related issues

issue #1501

Checklist before requesting a review

  • I have performed a self-review of my code
  • [] I have added docstrings/doxygen in line with the guidance in the developer guide
  • I have implemented unit tests that cover any new or modified functionality (if applicable)
  • The code builds and runs on my machine
  • [] documentation/release_XXX.md has been updated with any functionality change (if applicable)

@SomayehSaghamanesh SomayehSaghamanesh changed the title Safir scanners updates SAFIR scanners updates Feb 10, 2025
Copy link
Collaborator

@KrisThielemans KrisThielemans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry for delay!

I believe that the 2 utilities were written by Parisa. I'd therefore prefer that the commit is owner by her. I can fix that, if you're ok with this.

Also, the trim_projdata functionality is already in SSRB I think, so I'd prefer to cut that one out. ok?

@SomayehSaghamanesh
Copy link
Author

SomayehSaghamanesh commented Nov 12, 2025 via email

@KrisThielemans
Copy link
Collaborator

Since we have used this utility quite a lot in our pipeline and I haven't changed it, could we keep having this extra utility as well? I think it doesn't really hurt to have two of them.

I'm trying to reduce the STIR code-base :-).

Could you check if using

SSRB -t num_tangential_poss_to_trim output_filename input_projdata_name 

works the same? If not, I'll keep it.

@KrisThielemans
Copy link
Collaborator

Also, could you merge master here, and then add something brief in the release_6.4.htm (if you can do this quickly) and the STIR_UsersGuilde.text?. thanks!

@KrisThielemans KrisThielemans self-assigned this Nov 12, 2025
@SomayehSaghamanesh
Copy link
Author

SomayehSaghamanesh commented Nov 12, 2025 via email

@KrisThielemans
Copy link
Collaborator

Discussion on that problem is in #1508 and #1507. I cannot see how this is related to the trimming, and am now even more reluctant to include that utility I'm afraid. Sorry.

Feel free to keep the utility in your own version of STIR of course.

Without the trim utility (and the updates to the doc), I'd be happy to merge. Is it ok to push to your branch to fix ownership?

@KrisThielemans
Copy link
Collaborator

I'm confused TBH. I can't spot the difference between SSRB and the trim utility, e.g.

out_proj_data_info_sptr->set_num_tangential_poss(in_proj_data_info.get_num_tangential_poss() - num_tang_poss_to_trim);

Do you have any idea why SSRB fails but trim_projdata doesn't?

I've tried with some test data to set num_tangential_poss in the .hs equal to num_detectors_per_ring, and SSRB is fine with it.

sorry to be such a pain, but actually these utilities seem to need more updates (TOF etc), and it is going to take more time to do this (and extra work to keep it up-to-date).

Comment on lines +15 to +34
#include "stir/utilities.h"
#include "stir/Bin.h"

#include <fstream>
#include <iostream>
#include "stir/ProjDataFromStream.h"
#include "stir/Viewgram.h"
#include "stir/IO/read_from_file.h"
#include "stir/SegmentByView.h"
#include "stir/ProjDataInterfile.h"
#include "stir/ProjDataInfo.h"
#include "stir/LORCoordinates.h"

#include "stir/GeometryBlocksOnCylindrical.h"
#include "stir/DetectionPosition.h"
#include "stir/CartesianCoordinate3D.h"
#include "stir/DetectorCoordinateMap.h"
#include <boost/make_shared.hpp>
#include "stir/CPUTimer.h"
#include "stir/shared_ptr.h"
Copy link
Collaborator

@KrisThielemans KrisThielemans Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

most of these headers are not used. Certainly not the boost one. Please cut as much as you can.

#include "stir/shared_ptr.h"


#ifndef STIR_NO_NAMESPACES
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this #ifdef. we're on C++-17 now

shared_ptr<ProjDataInfo> in_pdi_ptr(in_pd_ptr->get_proj_data_info_sptr()->clone());
shared_ptr<ProjDataInfo> out_pdi_ptr(template_pd_ptr->get_proj_data_info_sptr()->clone());
ProjDataInterfile out_proj_data(template_pd_ptr->get_exam_info_sptr(), out_pdi_ptr, output_filename+".hs");
write_basic_interfile_PDFS_header(output_filename+".hs", out_proj_data);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this


timer0.start();

assert(in_pdi_ptr->get_min_segment_num()==-1*in_pdi_ptr->get_max_segment_num());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove. this isn't relevant here.

Comment on lines +69 to +88
// keep sinograms out of the loop to avoid reallocations
// initialise to something because there's no default constructor
Viewgram<float> viewgram_blk = out_proj_data.get_empty_viewgram(out_proj_data.get_min_view_num(),seg);
Viewgram<float> viewgram_cyl = in_pd_ptr->get_empty_viewgram(in_pd_ptr->get_min_view_num(),seg);

for(int view=in_pdi_ptr->get_min_view_num(); view<=in_pdi_ptr->get_max_view_num();++view)
{
viewgram_blk = out_proj_data.get_empty_viewgram(view,seg);
viewgram_cyl = in_pd_ptr->get_viewgram(view,seg);

for(int ax=in_pdi_ptr->get_min_axial_pos_num(seg); ax<=in_pdi_ptr->get_max_axial_pos_num(seg);++ax)
{
for(int tang=in_pdi_ptr->get_min_tangential_pos_num(); tang<=in_pdi_ptr->get_max_tangential_pos_num(); ++tang)
{
viewgram_blk[ax][tang] = viewgram_cyl[ax][tang];
}
}
if (!(out_proj_data.set_viewgram(viewgram_blk)== Succeeded::yes))
warning("Error set_segment for projdata_symm %d\n", seg);
}
Copy link
Collaborator

@KrisThielemans KrisThielemans Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can shorten this a bit, and make it ready for TOF along the lines of

SegmentIndices seg_indices(seg); // TODO add TOF here later
auto seg_blk = out_proj_data.get_empty_segment_by_view(seg_indices);
const auto seg_cyl= out_proj_data.get_segment_by_view(seg_indices);
std::copy(seg_cyl.begin_all(), seg_cyl.end_all(), seg_blk.begin_all());

which means we need to #include "stir/SegmentIndices.h" and <algorithm>.

Obviously, the naming of the variables isn't quite correct, as we don't know what the type is, but fine.

\ingroup utilities

\brief This program takes a projection data from one type and converts it to another type.
\author Parisa Khateri
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as I'm asking you to clean this up, please add yourself. We'll forget about fixing the ownership for this file, as it's going to be very short.

std::string output_filename=argv[1];
shared_ptr<ProjData> in_pd_ptr = ProjData::read_from_file(argv[2]);
shared_ptr<ProjData> template_pd_ptr = ProjData::read_from_file(argv[3]);

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ideally add a check that get_num_tof_poss()==0 and if not, call error

@SomayehSaghamanesh
Copy link
Author

SomayehSaghamanesh commented Dec 2, 2025 via email

@SomayehSaghamanesh
Copy link
Author

I will go through the changes and let you know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants