Treatment session - topasmc/dicom-interface GitHub Wiki

The RTI implements hierarchical structure, e.g., Treatment session, Treatment machine, Beamline, and Beamsouce. Among these, Treatment session is placed top of this hierarchy and in charge of:

  • Parsing DICOM informations, RTIP and RTIBTR.
  • Loading a treatment machine, which match to user's input or found in RTIP/RTIBTR.
  • Passing the number or name of the beam to be simulated to treatment machine
  • Returning the beam line geometries to MC engine.
  • Returning the beam source to MC engine.
template<typename T>
class treatment_session {
protected:
    
    ///< Sequence tag dictionary for modality specific
    const std::map<const std::string, const gdcm::Tag>* seq_tags_ ;

    ///< RT Modality type, e.g., RTPLAN, RTRECORD, IONPLAN, IONRECORD
    rti::modality_type  mtype_ ;

    ///< machine name, e.g., institution_name:machine_name
    std::string machine_name_ ; 

    rti::treatment_machine<T>* tx_machine_ = nullptr;

    ///< top level DICOM dataset, either RTIP or RTIBTR
    rti::dataset* rti_ds_ = nullptr;  
    
public:
    treatment_session(
        std::string file_for_tx_machine, //DICOM file of RTIP or RTIBTR
        std::string m_name  = "",        //machine name, if null, machine name is searched in RTIP
        std::string mc_code = "topas:3.0.1") //mc code information is an optional.

   bool 
   create_machine(std::string machine_name, std::string mc_code)

   template<typename S>
   rti::beamline<T> 
   get_beamline(S beam_id)
   
   template<typename S>
   rti::coordinate_transform<T> 
   get_coordinate(S beam_id)

   template<typename S>
   rti::beamsource<T> 
   get_beamsource(S beam_id, const rti::coordinate_transform<T> coord, float scale, T sid)

Treatment session is supposed to interact with Monte Carlo engine. This is instantiated by an input DICOM-RT Ion either plan (RTIP) or beam delivery log (RTIBTR). See the overall diagram in Figure 1 in Home.

Treatmemt session returns beamline and beamsource to Monte Carlo code.

What users need to do for registering their own beam model, i.e., treatment machine is to edit create_machine method. This is explained in Tutorial page.

Treatment machine


Treatment machine is a class that holds site or system specific DICOM conversion for beam limiting devices and beam sources. To do so, users need to inherit and override necessary methods.

Figure UML diagram of treatment_machine class

Methods you can use for site-specific DICOM handling or beam calibrations are:

  • characterize_rangeshifter
  • characterize_aperture

Methods you can use for site-specific DICOM handling depending on MODULATED beam delivery technique are

  • characterize_beamlet(const rti::beam_module_ion::spot s)
  • characterize_history(const rti::beam_module_ion::spot s)

Methods you can use for site-specific DICOM handling depending on MODULATED_SPEC or UNIFORM delivery technique are

  • characterize_beamlet(const rti::beam_module_ion::spot0, const rti::beam_module_ion::spot1)
  • characterize_history(const rti::beam_module_ion::spot0, const rti::beam_module_ion::spot1)

As the spot's position in these technique changes within spot0 and spot1, its position should be sampled from the distribution function. Follows are the example of uniform line-scanning. It's similar with spot-scanning delivery technique but this example phsp_6d_fanbeam is used because this phsp distribution generates random position between spot0 and spot1.

virtual
    rti::beamlet<T>
    characterize_beamlet(
        const rti::beam_module_ion::spot& s0,
        const rti::beam_module_ion::spot& s1)
    {
        //energy distribution
        auto energy = new rti::const_1d<T>({s0.e},{0});

        //Direction of X/Y at isocenter
	rti::vec3<T> dir0(std::atan(s0.x/treatment_machine_ion<T>::SAD_[0]),
                          std::atan(s0.y/treatment_machine_ion<T>::SAD_[1]),
                         -1.0);
	rti::vec3<T> dir1(std::atan(s1.x/treatment_machine_ion<T>::SAD_[0]),
                          std::atan(s1.y/treatment_machine_ion<T>::SAD_[1]),
                         -1.0);

        //New position at source position (source_to_isocenter_mm)
        rti::vec3<T> pos0(0, 0, rti::treatment_machine_ion<T>::source_to_isocenter_mm_);
        pos0.x = (treatment_machine_ion<T>::SAD_[0] - pos0.z) * dir0.x ;
        pos0.y = (treatment_machine_ion<T>::SAD_[1] - pos0.z) * dir0.y ;
	
	rti::vec3<T> pos1(0, 0, rti::treatment_machine_ion<T>::source_to_isocenter_mm_);
        pos1.x = (treatment_machine_ion<T>::SAD_[0] - pos1.z) * dir1.x ;
        pos1.y = (treatment_machine_ion<T>::SAD_[1] - pos1.z) * dir1.y ;

	std::array<T,6> spot_pos_range = {pos0.x, pos1.x, pos0.y, pos1.y, pos0.z, pos1.z};
        std::array<T,6> spot_sigma     = {s.fwhm_x, s.fwhm_y, 0.0, 0.0, 0.0, 0.0};
        std::array<T,2> corr           = {0.0, 0.0};

	//spot direction mean is calculated from the sampled position between x0 and x1
	//so passing spot-range to a specialized distribution for handling this case is prefered option.
	auto spot_= new rti::phsp_6d_fanbeam<T>(spot_pos_range, spot_sigma, corr, treatment_machine_ion<T>::SAD_);

        return rti::beamlet<T>(energy, spot_);
    }

Beamline

A beamline class is nothing but a contain for beam-limiting geometries used in a plan. So this may or may not have a limiting devices. So MC code should check this beamline before to create a geometry.

template <typename T>
class beamline {
protected:
    /// A container for components
    std::vector<rti::geometry*> geometries_;
    /// A coordinate transform. 
    /// \note not sure we need this in future.
    rti::coordinate_transform<T> p_coord_;

Beamsource

Beamsource belongs to a treatment machine and is supposed to be calibrated w.r.t this treatment machine. For more information about Beamsource, see here.

⚠️ **GitHub.com Fallback** ⚠️