Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow KeyParser keyword with colon #1267

Merged
merged 2 commits into from
Oct 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions documentation/release_5.2.htm
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ <h3>Changed functionality</h3>
hard-coded variables for the Siemens mMR have been removed. Further testing of this functionality is still required however.
<br /><a href="https://github.com/UCL/STIR/pull/1182/">PR #1182</a>.
</li>
<li>Interfile header parsing now correctly identifies keywords that contain a colon by checking for <tt>:=</tt>./li>
</ul>

<h3>New functionality</h3>
Expand Down
53 changes: 36 additions & 17 deletions src/IO/InterfileHeaderSiemens.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/*!
\file
\ingroup InterfileIO
\brief implementations for the stir::InterfileHeaderSiemens class
\brief implementations for the stir::InterfileHeaderSiemens classes

\author Kris Thielemans
\author PARAPET project
Expand Down Expand Up @@ -163,6 +163,36 @@ void InterfileHeaderSiemens::set_type_of_data()
}


void
InterfileHeaderSiemens::ignore_Siemens_date_and_time_keys(const std::string& keyword)
{
ignore_key(keyword + " date (yyyy:mm:dd)");
ignore_key(keyword + " time (hh:mm:ss GMT+00:00)");
ignore_key(keyword + " time (hh:mm:ss GMT+01:00)");
ignore_key(keyword + " time (hh:mm:ss GMT+02:00)");
ignore_key(keyword + " time (hh:mm:ss GMT+03:00)");
ignore_key(keyword + " time (hh:mm:ss GMT+04:00)");
ignore_key(keyword + " time (hh:mm:ss GMT+05:00)");
ignore_key(keyword + " time (hh:mm:ss GMT+06:00)");
ignore_key(keyword + " time (hh:mm:ss GMT+07:00)");
ignore_key(keyword + " time (hh:mm:ss GMT+08:00)");
ignore_key(keyword + " time (hh:mm:ss GMT+09:00)");
ignore_key(keyword + " time (hh:mm:ss GMT+10:00)");
ignore_key(keyword + " time (hh:mm:ss GMT+11:00)");
ignore_key(keyword + " time (hh:mm:ss GMT-01:00)");
ignore_key(keyword + " time (hh:mm:ss GMT-02:00)");
ignore_key(keyword + " time (hh:mm:ss GMT-03:00)");
ignore_key(keyword + " time (hh:mm:ss GMT-04:00)");
ignore_key(keyword + " time (hh:mm:ss GMT-05:00)");
ignore_key(keyword + " time (hh:mm:ss GMT-06:00)");
ignore_key(keyword + " time (hh:mm:ss GMT-07:00)");
ignore_key(keyword + " time (hh:mm:ss GMT-08:00)");
ignore_key(keyword + " time (hh:mm:ss GMT-09:00)");
ignore_key(keyword + " time (hh:mm:ss GMT-10:00)");
ignore_key(keyword + " time (hh:mm:ss GMT-11:00)");
}


/**********************************************************************/

InterfileRawDataHeaderSiemens::InterfileRawDataHeaderSiemens()
Expand Down Expand Up @@ -205,13 +235,11 @@ InterfileRawDataHeaderSiemens::InterfileRawDataHeaderSiemens()
ignore_key("%listmode header file");
ignore_key("%listmode data file");
ignore_key("%compressor version");
ignore_key("%study date (yyyy");
ignore_key("%study time (hh");
ignore_Siemens_date_and_time_keys("%study");
ignore_key("isotope gamma halflife (sec)");
ignore_key("isotope branching factor");
ignore_key("radiopharmaceutical");
ignore_key("%tracer injection date (yyyy");
ignore_key("%tracer injection time (hh");
ignore_Siemens_date_and_time_keys("%tracer injection");
ignore_key("relative time of tracer injection (sec)");
ignore_key("tracer activity at time of injection (bq)");
ignore_key("injected volume (ml)");
Expand All @@ -223,8 +251,7 @@ InterfileRawDataHeaderSiemens::InterfileRawDataHeaderSiemens()
ignore_key("method of scatter correction");
ignore_key("%method of random correction");
ignore_key("%decay correction");
ignore_key("%decay correction reference date (yyyy");
ignore_key("%decay correction reference time (hh");
ignore_Siemens_date_and_time_keys("%decay correction reference");
ignore_key("decay correction factor");
ignore_key("scatter fraction (%)");
ignore_key("scan data type description");
Expand Down Expand Up @@ -542,11 +569,7 @@ InterfileNormHeaderSiemens::InterfileNormHeaderSiemens()
is_arccorrected = false; // norm data is never arc-corrected

ignore_key("data description");
ignore_key("%expiration date (yyyy:mm:dd)");
ignore_key("%expiration time (hh:mm:ss GMT-05:00)");
// currently keywords are truncated at :
ignore_key("%expiration time (hh");
ignore_key("%expiration date (yyyy");
ignore_Siemens_date_and_time_keys("%expiration");
ignore_key("%raw normalization scans description");

// remove some standard keys, which Siemens has replaced with similar names
Expand All @@ -573,11 +596,7 @@ InterfileNormHeaderSiemens::InterfileNormHeaderSiemens()
ignore_key("%global scanner calibration factor");
add_key("%scanner quantification factor (Bq*s/ECAT counts)",& calib_factor);
add_key("%cross calibration factor",& cross_calib_factor);
ignore_key("%calibration date (yyyy:mm:dd)");
ignore_key("%calibration time (hh:mm:ss GMT+00:00)");
// currently keywords are truncated at :
ignore_key("%calibration time (hh");
ignore_key("%calibration date (yyyy");
ignore_Siemens_date_and_time_keys("%calibration");

// isotope things are vectorised in norm files and not in other raw data, so we could
// fix that, but as we are not interested in it anyway (tends to be Ge-68), let's just ignore it.
Expand Down
8 changes: 6 additions & 2 deletions src/buildblock/KeyParser.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,12 @@ string
KeyParser::get_keyword(const string& line) const
{
// keyword stops at either := or an index []
// TODO should check that = follows : to allow keywords with colons in there
const string::size_type eok = line.find_first_of(":[",0);
string::size_type eok = line.find_first_of(":[",0);
// check that = follows : to allow keywords containing colons
while (line[eok] == ':' && eok+1 < line.size() && line[eok+1] != '=')
{
eok = line.find_first_of(":[", eok+1);
}
return line.substr(0,eok);
}

Expand Down
13 changes: 13 additions & 0 deletions src/include/stir/IO/InterfileHeaderSiemens.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,19 @@ class InterfileHeaderSiemens : public InterfileHeader
protected:
// Returns false if OK, true if not.
virtual bool post_processing();
//! ignore multiple GMT times
/*!
Siemens uses keywords like
\verbatim
%study date (yyyy:mm:dd") := ...
%study time (hh:mm:ss GMT+00:00) := ...
\endvarbatim
You can ignore this for all (?) time zones by using
\code
ignore_Siemens_date_and_time_keys("%study");
\endcode
*/
void ignore_Siemens_date_and_time_keys(const std::string& keyword);

private:

Expand Down
12 changes: 6 additions & 6 deletions src/include/stir/KeyParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ public :
\brief A class to parse Interfile headers

Currently, Interfile 3.3 parsing rules are hard-coded, with
some extensions.
some extensions. Note that some functions such as `get_keyword()` are `virtual`
such that a derived class could use non-Interfile parsing (but this might need
more work).

KeyParser reads input line by line and parses each line separately.
It allows for '\\r' at the end of the line (as in files
Expand Down Expand Up @@ -349,16 +351,14 @@ protected :


//! convert 'rough' keyword into a standardised form
/*! \todo Implementation note: this function is non-static such that it can
be overloaded. Probably a template with a function object would be
better. */
/*! Calls standardise_interfile_keyword().
. */
virtual std::string
standardise_keyword(const std::string& keyword) const;


//! gets a keyword from a string
/*! Implementation note: this function is non-static as it uses
standardise_keyword().
/*! Find `:=` or `[`. Note that the returned keyword is not standardised yet.
*/
virtual std::string
get_keyword(const std::string&) const;
Expand Down