STIR 6.4.0
stir::RigidObject3DMotionFromPolaris Class Reference

A class for handling motion information from the Polaris tracker. More...

#include "stir_experimental/motion/RigidObject3DMotionFromPolaris.h"

Inheritance diagram for stir::RigidObject3DMotionFromPolaris:

Public Member Functions

RigidObject3DTransformation compute_average_motion_in_tracker_coords_rel_time (const double start_time, const double end_time) const override
 
RigidObject3DTransformation get_motion_in_tracker_coords_rel_time (const double time) const override
 get motion in tracker coordinates
 
std::vector< double > get_rel_time_of_samples (const double start_time, const double end_time) const override
 Info on when the motion was determined.
 
void set_mask_for_tags (const unsigned int mask_for_tags)
 set mask to be able to ignore one or more channels in the listmode gating data
 
Succeeded synchronise () override
 Synchronise motion tracking file and listmode file.
 
double secs_since_1970_to_rel_time (std::time_t) const override
 
const RigidObject3DTransformationget_transformation_to_scanner_coords () const override
 
const RigidObject3DTransformationget_transformation_from_scanner_coords () const override
 
void set_transformation_from_scanner_coords (const RigidObject3DTransformation &) override
 
Succeeded set_mt_file (const std::string &mt_filename)
 
Succeeded set_list_mode_data_file (const std::string &lm_filename)
 
void set_defaults () override
 Set defaults before parsing.
 
void initialise_keymap () override
 Initialise all keywords.
 
bool post_processing () override
 This will be called at the end of the parsing.
 
double get_max_time_offset_deviation () const
 Gets boundaries to determine when the time offset is out of bounds.
 
void set_max_time_offset_deviation (const double v)
 Sets boundaries to determine when the time offset is out of bounds.
 
double get_max_time_drift_deviation () const
 Gets boundaries to determine when the time drift is too large.
 
void set_max_time_drift_deviation (const double v)
 Sets boundaries to determine when the time drift is too large.
 
- Public Member Functions inherited from stir::RegisteredParsingObject< RigidObject3DMotionFromPolaris, RigidObject3DMotion, RigidObject3DMotion >
std::string get_registered_name () const override
 Returns Derived::registered_name.
 
std::string parameter_info () override
 Returns a string with all parameters and their values, in a form suitable for parsing again.
 
- Public Member Functions inherited from stir::RigidObject3DMotion
virtual RigidObject3DTransformation get_motion_in_scanner_coords_rel_time (const double time) const
 get motion in scanner coordinates
 
virtual RigidObject3DTransformation compute_average_motion_in_tracker_coords (const AbsTimeInterval &) const
 
virtual RigidObject3DTransformation compute_average_motion_in_scanner_coords (const AbsTimeInterval &) const
 
virtual RigidObject3DTransformation compute_average_motion_in_scanner_coords_rel_time (const double start_time, const double end_time) const
 
- Public Member Functions inherited from stir::ParsingObject
 ParsingObject (const ParsingObject &)
 
ParsingObjectoperator= (const ParsingObject &)
 
bool parse (std::istream &f)
 
bool parse (const char *const filename)
 
void ask_parameters ()
 

Static Public Member Functions

static RigidObject3DTransformation make_transformation_from_polaris_data (Polaris_MT_File::Record const &record)
 Convert from Polaris transformation to STIR conventions.
 
- Static Public Member Functions inherited from stir::RegisteredParsingObject< RigidObject3DMotionFromPolaris, RigidObject3DMotion, RigidObject3DMotion >
static RigidObject3DMotionread_from_stream (std::istream *)
 Construct a new object (of type Derived) by parsing the istream.
 
- Static Public Member Functions inherited from stir::RegisteredObject< RigidObject3DMotion >
static RigidObject3DMotionread_registered_object (std::istream *in, const std::string &registered_name)
 Construct a new object (of a type derived from Root, its actual type determined by the registered_name parameter) by parsing the istream.
 
static RigidObject3DMotionask_type_and_parameters ()
 ask the user for the type, and then calls read_registered_object(0, type)
 
static void list_registered_names (std::ostream &stream)
 List all possible registered names to the stream.
 

Static Public Attributes

static const char *const registered_name = "Motion From Polaris"
 Name which will be used when parsing a MotionTracking object.
 

Additional Inherited Members

- Protected Types inherited from stir::RegisteredObject< RigidObject3DMotion >
typedef RigidObject3DMotion *(* RootFactory) (std::istream *)
 The type of a root factory is a function, taking an istream* as argument, and returning a Root*.
 
typedef FactoryRegistry< std::string, RootFactory, interfile_lessRegistryType
 The type of the registry.
 
virtual void set_key_values ()
 This will be called before parsing or parameter_info is called.
 
- Static Protected Member Functions inherited from stir::RegisteredObject< RigidObject3DMotion >
static RegistryTyperegistry ()
 Static function returning the registry.
 
KeyParser parser
 

Detailed Description

A class for handling motion information from the Polaris tracker.

Implements synchronisation by comparing gate data in the list mode file with the numbers stored in the Polaris .mt file. Computes both time offset and clock drift. Synchronisation is stored in a .sync file. If present, this file is read and actual synchronisation is skipped. (This is useful, as the synchronisation is slow as it walks through the whole list mode file).

Parsing info
The class can parse a file for the coordinate transformation that goes from scanner to tracker coordinates. This file has to have the following format.
  Move from scanner to tracker coordinates:=
   conventions := q0qzqyqx and left-handed
   transformation:= \
    {{-0.00525584, -0.0039961, 0.999977,0.00166456},\
     {-1981.93, 20.1226, 3.96638}}
 end:=
Obviously the numbers will depend on your systems.
Todo
move synchronisation out of this class

Member Function Documentation

◆ make_transformation_from_polaris_data()

RigidObject3DTransformation stir::RigidObject3DMotionFromPolaris::make_transformation_from_polaris_data ( Polaris_MT_File::Record const & record)
static

Convert from Polaris transformation to STIR conventions.

Convert from Polaris transformation to STIR conventions

The Polaris records info as q0 qx qy qz tx ty tz, where the coordinate system is right-handed (see the Polaris manual). The STIR coordinate system is left-handed. We do take a coordinate transformation into account when applying Polaris transformations to scanner coordinates. However, that coordinate transformation uses RigidObject3DTransformation, and hence cannot swap right-handed to left-handed. So, we convert the Polaris transformation to a left-handed transformation by swapping x and y.

The exact form then depends heavily on conventions in RigidObject3DTransformation, which currently takes its info as

Quaternion<float>(q0,qZ,qY,qX), CartesianCoordinate3D<float>(tZ,tY,tX)
a templated class for 3-dimensional coordinates.
Definition CartesianCoordinate3D.h:53

where I've used capitals to denote the left-handed coordinate system:

x=Y,y=X,z=Z.

Some careful checks in e.g. Mathematica then show that

qx=qY,qy=qX,qz=qZ.

This not so obvious as it sounds as there is a potential sign here. For instance, the Polaris convention uses a quaternion (0,x,y,z) for a point, while RigidObject3DTransformation uses (0,z,y,x) (see the point2quat function in RigidObject3DTransformation.cxx ). So, effectively there are 2 coordinate swaps between Polaris conventions and RigidObject3DTransformation:

Quaternion<float>(q0,qZ,qY,qX) = Quaternion<float>(q0,qz,qx,qy)

and qz,qx,qy is an even permutation of qx,qy,qz

References make_transformation_from_polaris_data().

Referenced by get_motion_in_tracker_coords_rel_time(), and make_transformation_from_polaris_data().

◆ compute_average_motion_in_tracker_coords_rel_time()

RigidObject3DTransformation stir::RigidObject3DMotionFromPolaris::compute_average_motion_in_tracker_coords_rel_time ( const double start_time,
const double end_time ) const
overridevirtual

◆ get_motion_in_tracker_coords_rel_time()

RigidObject3DTransformation stir::RigidObject3DMotionFromPolaris::get_motion_in_tracker_coords_rel_time ( const double time) const
overridevirtual

◆ get_rel_time_of_samples()

std::vector< double > stir::RigidObject3DMotionFromPolaris::get_rel_time_of_samples ( const double start_time,
const double end_time ) const
overridevirtual

Info on when the motion was determined.

Will return a vector of doubles filled with the sampling times between start_time and end_time.

Todo
Really only makes sense for motion tracking that happens via sampling. One could imagine having simulated motion, and then this function wouldn't make a lot of sense. So, it probably should be moved to a derived class SampledRigidObject3DMotion or so.

Implements stir::RigidObject3DMotion.

References get_rel_time_of_samples().

Referenced by get_rel_time_of_samples().

◆ synchronise()

Succeeded stir::RigidObject3DMotionFromPolaris::synchronise ( )
overridevirtual

Synchronise motion tracking file and listmode file.

Implements stir::RigidObject3DMotion.

References stir::KeyParser::add_start_key(), stir::get_filename(), stir::read_from_file(), stir::round(), synchronise(), and stir::warning().

Referenced by post_processing(), and synchronise().

◆ secs_since_1970_to_rel_time()

double stir::RigidObject3DMotionFromPolaris::secs_since_1970_to_rel_time ( std::time_t secs) const
overridevirtual

◆ get_transformation_to_scanner_coords()

const RigidObject3DTransformation & stir::RigidObject3DMotionFromPolaris::get_transformation_to_scanner_coords ( ) const
overridevirtual

◆ get_transformation_from_scanner_coords()

const RigidObject3DTransformation & stir::RigidObject3DMotionFromPolaris::get_transformation_from_scanner_coords ( ) const
overridevirtual

◆ set_transformation_from_scanner_coords()

void stir::RigidObject3DMotionFromPolaris::set_transformation_from_scanner_coords ( const RigidObject3DTransformation & new_move_from_scanner_coords)
overridevirtual

◆ set_defaults()

void stir::RigidObject3DMotionFromPolaris::set_defaults ( )
overridevirtual

Set defaults before parsing.

Reimplemented from stir::RigidObject3DMotion.

References stir::RigidObject3DMotion::set_defaults(), and set_defaults().

Referenced by set_defaults().

◆ initialise_keymap()

void stir::RigidObject3DMotionFromPolaris::initialise_keymap ( )
overridevirtual

Initialise all keywords.

Reimplemented from stir::RigidObject3DMotion.

References stir::RigidObject3DMotion::initialise_keymap(), and initialise_keymap().

Referenced by initialise_keymap().

◆ post_processing()

bool stir::RigidObject3DMotionFromPolaris::post_processing ( )
overridevirtual

This will be called at the end of the parsing.

Returns
false if everything OK, true if not

Reimplemented from stir::RigidObject3DMotion.

References stir::KeyParser::add_start_key(), stir::norm(), stir::RigidObject3DMotion::post_processing(), post_processing(), synchronise(), and stir::warning().

Referenced by post_processing().

◆ get_max_time_drift_deviation()

double stir::RigidObject3DMotionFromPolaris::get_max_time_drift_deviation ( ) const
inline

Gets boundaries to determine when the time drift is too large.

deviation is measured as fabs(time_drift-1)


The documentation for this class was generated from the following files: