STIR  6.2.0
SAFIRCListmodeInputFileFormat.h
Go to the documentation of this file.
1 /* SAFIRCListmodeInputFileFormat.h
2 
3  Class defining input file format for coincidence listmode data for SAFIR.
4 
5  Copyright 2015 ETH Zurich, Institute of Particle Physics
6  Copyright 2020 Positrigo AG, Zurich
7 
8  Licensed under the Apache License, Version 2.0 (the "License");
9  you may not use this file except in compliance with the License.
10  You may obtain a copy of the License at
11 
12  http://www.apache.org/licenses/LICENSE-2.0
13 
14  Unless required by applicable law or agreed to in writing, software
15  distributed under the License is distributed on an "AS IS" BASIS,
16  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  See the License for the specific language governing permissions and
18  limitations under the License.
19  */
20 
31 #ifndef __stir_IO_SAFIRCListmodeInputFileFormat_H__
32 #define __stir_IO_SAFIRCListmodeInputFileFormat_H__
33 
34 #include <algorithm>
35 #include <cstring>
36 #include <string>
37 #include <iostream>
38 
39 #include "boost/algorithm/string.hpp"
40 
42 #include "stir/info.h"
43 #include "stir/error.h"
44 #include "stir/utilities.h"
45 #include "stir/ParsingObject.h"
46 
49 
50 START_NAMESPACE_STIR
51 
79 template <class EventDataType>
80 class SAFIRCListmodeInputFileFormat : public InputFileFormat<ListModeData>, public ParsingObject
81 {
82 public:
84  const std::string get_name() const override { return "SAFIR Coincidence Listmode File Format"; }
85 
87  bool can_read(const FileSignature& signature, std::istream& input) const override
88  {
89  return false; // cannot read from istream
90  }
91 
94  bool can_read(const FileSignature& signature, const std::string& filename) const override
95  {
96  // Looking for the right key in the parameter file
97  std::ifstream par_file(filename.c_str());
98  std::string key;
99  std::getline(par_file, key, ':');
101  if (key != std::string("clistmodedatasafir parameters"))
102  {
103  return false;
104  }
105  if (!actual_do_parsing(filename))
106  return false;
107  std::ifstream data_file(listmode_filename.c_str(), std::ios::binary);
108  char* buffer = new char[32];
109  data_file.read(buffer, 32);
110  bool cr = false;
111  // depending on used template, check header of listmode file for correct format
112  if (std::is_same<EventDataType, CListEventDataSAFIR>::value)
113  {
114  cr = (!strncmp(buffer, "MUPET CListModeData\0", 20) || !strncmp(buffer, "SAFIR CListModeData\0", 20));
115  }
116  else if (std::is_same<EventDataType, CListEventDataNeuroLF>::value)
117  {
118  cr = !strncmp(buffer, "NeuroLF CListModeData\0", 20);
119  }
120  else
121  {
122  warning("SAFIRCListModeInputFileFormat was initialised with an unexpected template.");
123  }
124 
125  if (!cr)
126  {
127  warning("SAFIRCListModeInputFileFormat tried to read file " + listmode_filename
128  + " but it seems to have the wrong signature.");
129  }
130 
131  delete[] buffer;
132  return cr;
133  }
134 
135  std::unique_ptr<data_type> read_from_file(std::istream& input) const override
136  {
137  error("read_from_file for SAFIRCListmodeData with istream not implemented %s:%d. Sorry", __FILE__, __LINE__);
138  return unique_ptr<data_type>();
139  }
140 
141  std::unique_ptr<data_type> read_from_file(const std::string& filename) const override
142  {
143  info("SAFIRCListmodeInputFileFormat: read_from_file(" + std::string(filename) + ")");
144  actual_do_parsing(filename);
145  return std::unique_ptr<data_type>(new CListModeDataSAFIR<CListRecordSAFIR<EventDataType>>(
146  listmode_filename, crystal_map_filename, template_proj_data_filename, lor_randomization_sigma));
147  }
148 
149 protected:
150  typedef ParsingObject base_type;
151  mutable std::string listmode_filename;
152  mutable std::string crystal_map_filename;
153  mutable std::string template_proj_data_filename;
154  mutable double lor_randomization_sigma;
155 
156  bool actual_can_read(const FileSignature& signature, std::istream& input) const override
157  {
158  return false; // cannot read from istream
159  }
160 
161  void initialise_keymap() override
162  {
163  base_type::initialise_keymap();
164  this->parser.add_start_key("CListModeDataSAFIR Parameters");
165  this->parser.add_key("listmode data filename", &listmode_filename);
166  this->parser.add_key("crystal map filename", &crystal_map_filename);
167  this->parser.add_key("template projection data filename", &template_proj_data_filename);
168  this->parser.add_key("LOR randomization (Gaussian) sigma", &lor_randomization_sigma);
169  this->parser.add_stop_key("END CListModeDataSAFIR Parameters");
170  }
171 
172  void set_defaults() override
173  {
174  base_type::set_defaults();
175  crystal_map_filename = "";
176  template_proj_data_filename = "";
177  lor_randomization_sigma = 0.0;
178  }
179 
180  bool actual_do_parsing(const std::string& filename) const
181  {
182  // Ugly const_casts here, but I don't see an other nice way to use the parser
183  if (const_cast<SAFIRCListmodeInputFileFormat<EventDataType>*>(this)->parse(filename.c_str()))
184  {
185  info(const_cast<SAFIRCListmodeInputFileFormat<EventDataType>*>(this)->parameter_info());
186  return true;
187  }
188  else
189  return false;
190  }
191 
192  bool post_processing() override
193  {
194  if (!file_exists(listmode_filename))
195  return true;
196  else if (!file_exists(template_proj_data_filename))
197  return true;
198  else
199  {
200  return false;
201  }
202  return true;
203  }
204 
205 private:
206  bool file_exists(const std::string& filename)
207  {
208  std::ifstream infile(filename.c_str());
209  return infile.good();
210  }
211 };
212 END_NAMESPACE_STIR
213 #endif
bool can_read(const FileSignature &signature, std::istream &input) const override
Checks in binary data file for correct signature.
Definition: SAFIRCListmodeInputFileFormat.h:87
void initialise_keymap() override
Initialise all keywords.
Definition: SAFIRCListmodeInputFileFormat.h:161
A class to read/store the file signature.
Definition: FileSignature.h:34
This file declares various utility functions.
Declaration of class stir::InputFileFormat.
Declaration of class stir::CListModeDataSAFIR.
Class for reading SAFIR coincidence listmode data.
Definition: SAFIRCListmodeInputFileFormat.h:80
void info(const STRING &string, const int verbosity_level=1)
Use this function for writing informational messages.
Definition: info.h:51
A base class for objects that want to be able to parse parameter files.
Definition: ParsingObject.h:44
Declaration of class stir::ParsingObject.
bool post_processing() override
This will be called at the end of the parsing.
Definition: SAFIRCListmodeInputFileFormat.h:192
Declaration of stir::error()
Base-class for file-formats for reading.
Definition: InputFileFormat.h:39
Declaration of class stir::CListEventSAFIR and stir::CListRecordSAFIR with supporting classes...
void set_defaults() override
Set defaults before parsing.
Definition: SAFIRCListmodeInputFileFormat.h:172
string standardise_interfile_keyword(const string &keyword)
Put a (Interfile) keyword into a standard form.
Definition: interfile_keyword_functions.cxx:28
void warning(const char *const s,...)
Print warning with format string a la printf.
Definition: warning.cxx:41
Declaration of stir::info()
Class for reading SAFIR listmode data with variable geometry.
Definition: CListModeDataSAFIR.h:60
bool can_read(const FileSignature &signature, const std::string &filename) const override
Checks in binary data file for correct signature (can be either "SAFIR CListModeData", "NeuroLF CListModeData" or "MUPET CListModeData").
Definition: SAFIRCListmodeInputFileFormat.h:94
void error(const char *const s,...)
Print error with format string a la printf and throw exception.
Definition: error.cxx:42
std::unique_ptr< data_type > read_from_file(std::istream &input) const override
read data from a stream
Definition: SAFIRCListmodeInputFileFormat.h:135
std::unique_ptr< data_type > read_from_file(const std::string &filename) const override
read data from a filename
Definition: SAFIRCListmodeInputFileFormat.h:141