RawDAQData.h
Go to the documentation of this file.
1 #ifndef RAWDAQDATA_BASE_H
2 #define RAWDAQDATA_BASE_H
3 #include "DAQDataFormats/FunctionBind.h" // Macros for function pointer bindings
4 
5 #include <iostream> /* Iostream for printing */
6 #include <stdint.h> // uint32_t, etc
7 #include <stdlib.h> // exit
8 #include <vector>
9 
10 /// Versioning is implemented
11 #define DAQDATAFORMATS_VERSIONING_IS_IMPLEMENTED
12 
13 /// Define a macros to make accessing the raw buffer easier
14 /// All DAQDataFormats use this macro, so we'll just have one definition here
15 #ifndef RAWBUFF32
16 #define RAWBUFF32 ((uint32_t*)_Buffer)
17 #define RAWBUFF16 ((uint16_t*)_Buffer)
18 #endif
19 
20 /// calling functionIsNotAllowed
21 #define GENERATE_FUNCTION_IS_NOT_ALLOWED functionIsNotAllowed(__FUNCTION__)
22 
23 
24 //--------------------
25 /// Debugging macros
26 //#define DEBUGGING
27 
28 #ifdef DEBUGGING
29 #warning "Debugging is turned on. Please uncomment out DEBUGGING constant!"
30 #define EXECUTE_ON_DEBUG(x) x
31 #define PRINT_ON_DEBUG(x) do { std::cout<<x<<"\n"; } while (0)
32 #else
33 // Swallow semicolon
34 #define EXECUTE_ON_DEBUG(x) static_assert(true, "Null statement")
35 #define PRINT_ON_DEBUG(x) static_assert(true, "Null statement")
36 #endif
37 
38 /// This is for hard debugging
39 #ifndef COUT
40 #define COUT(xx) std::cout<<__PRETTY_FUNCTION__<<xx; std::cout<<"\n";
41 #endif
42 
43 //--------------------
44 
45 
46 namespace novadaq{
47 namespace datalogger{
48  class DataBlockReader;
49 }}
50 
51 
52 /*!
53  The RawDAQData class is a virtual class definition that
54  all the NOVA DAQ data format classes inherit from.
55 
56  All RawDAQData class decendants must impliment:
57 
58  A writeData method that writes the objects data in a
59  packed format to a memory location.
60 
61  A readData method that reads the objects data in a
62  packed format from a memory location.
63 
64  and
65 
66  A sizeofdata method that returns the native size of the
67  packed data object in 32bit words
68 
69 */
70 namespace daqdataformats {
71 
72  typedef int32_t version_t;// can be negative. For example, -1 = undefined
73 
74  typedef enum {
75  rds_error = -1,
79 
80  namespace rawdaqdataformat {
81  static const version_t DAQDATAFORMAT_UNKNOWN_VERSION = -1;
82  }// end of namespace rawnano
83 
84 class RawDAQData {
85  protected:
86  RawDAQData (); //!< Default Constructor.
87  RawDAQData (version_t);
88  RawDAQData (version_t, sizeofdata_t);
89  RawDAQData (version_t, bool use_setBufferSourceUnknownVersion);
90  RawDAQData (version_t, bool use_setBufferSourceUnknownVersion, sizeofdata_t);
92  RawDAQData (version_t, init_t);
93  RawDAQData (version_t, init_t, sizeofdata_t);
96  /// Deep copy
97  RawDAQData (const RawDAQData&);
98 
99  public:
100  virtual ~RawDAQData();
101 
102  public:
103 
104  /// Deep copy from the DAQDataFormat
105  virtual void copy (const RawDAQData&);
106 
107  /// Shallow copy from the external buffer
108  virtual void copy (const void* buffer); //! Shallow copy constructor
109 
110  // Data I/O Methods
111  // Read method that read the raw formated data block from the target memory
112  void* readData(const void* buffer);
113  /// Read from the buffer if the size of data is known
114  void* readData(const void* buffer, const uint32_t size_of_data) {return readDataGeneral(buffer, size_of_data);}
115  /// From the File descriptor
116  virtual readDataStatus readData(const int fd);
117 
118  /// General write method that writes the raw formated data block to the target memory
119  /// We are not going to overload it, so no need to declare virtual
120  void* writeData(const void* buffer) const; //!< Write Data to target memory location. Return is the address of the end of the write. NULL on error.
121  ssize_t writeData(const int fd ) const; //!< Write Data to target file descriptor. Return is the number of bytes written. -1 on error.
122 
123  //---------------------------------------------------------
124  /// Calculate CRC of _Buffer (after skipping last skip_last_words words) using CRC32c algorythm with 0x8F6E37A0 polynomial.
125  /// Usually use skip_last_words=1 as the _Buffer has an CRC in the end
126  /// If on calculates with skip_last_words=0 (with CRC at the end), it should calculate to Zero (Property of Check Sum)
127  uint32_t calculateCheckSum(const uint32_t skip_last_words) const;
128 
129  /// Get method for the pointer to the internal buffers
130  /// We are not going to overload it, so no need to declare virtual
131  void* getBuffer() const { return _Buffer; }; /* This is evil. You shouldn't expose the buffer point. However, we allow it. */
132 
133  /// We are not going to overload these funtions, so no need to declare them virtual
134  bool setBufferSource (const void*); //!< Set The Buffer pointer to a given location.
135  bool resetBufferSource(); //! reset _Buffer to point to InternalBuffer
136  virtual bool clear(); //!< Clear Internal Buffer
137  bool reset(); //!< Reset
138 
139  /// Is buffer internal
140  /// We are not going to overload it, so no need to declare virtual
141  bool isInternalBuffer() const { return (_Buffer == (void*)(&_InternalBuffer[0])); }
142 
143  /// Functions that need to be defined in each class
144  /// Initialize DAQDataFormats class
145  void init() {};
146  /// Method for printing the content of the Buffer
147  void print(std::ostream& os=std::cout) const;
148  /// print into the string
149  void print(std::string& output_string) const;
150  /// Sizeof method for the current data block. Returns the size of the data block in 32bit words.
151  uint32_t sizeofdata() const;
152 
153  /// Add the CRC into the end of fBuffer. CRC of all but the last words of the _Buffer
154  virtual bool addCheckSum();
155 
156  //------------- Internal methods for DAQDataFormats. Can't be used by users
157  protected:
158 
159  /// General ReadData method when the sizeofdata is known
160  void* readDataGeneral(const void* buffer);
161 
162  /// Method which returns the version of the DataFormat given the pointer to the buffer
163  /// It has to be implemented for all DataFormats.
164  virtual version_t figureOutTheVersion(const void* buffer) const = 0;
165 
166  /// If the buffer should be internal, check it's pointers and reassign them
167  bool checkBufferInternalness();
168 
169  /// Function where we set all function pointers. At this point we don't know it
170  /// It is to be derived in the final user readable class
171  virtual bool setFunctionPointers() = 0;
172 
173 
174  /// Set BufferSource of the input DataFormat and return pointer to the position right after the end of its buffer
175  void* setBufferSourceGeneral(RawDAQData&, const void*);
176  bool setBufferSourceUnknownVersion(const void*);
177 
178  /// Reserve space for the internal buffer to some predetermined size
179  bool reserveInternalBuffer(const uint32_t size_of_data);
180 
181  /// Add Zeros to internal buffer
182  bool addToInternalBuffer(const uint32_t size_of_data_to_add);
183 
184 
185  /// Resize the internal buffer
186  bool resizeInternalBuffer(const uint32_t size_of_data);
187 
188  /// Conversions from bool to int and backwards
189  /// We are not going to overload it, so no need to declare virtual
190  uint32_t boolToUint32_t (const bool number ) const { return ((number) ? 1 : 0); }
191  bool uint32_tToBool (const uint32_t number ) const { return ((number) ? true : false); }
192 
193  /// Print methods
194  /// Generic print
195  void printGeneral(std::ostream& os=std::cout) const;
196  /// Displays the data _Buffer
197  /// Customazible for debugging purpose
198  void printBuffer (std::ostream& os = std::cout
199  ,const bool print_offset = true /* Print offset from the address of the _Buffer */
200  ,const bool print_ascii = true /* Print ASCII of the content of the Buffer */
201  ,const bool print_buffer_address = false /* Print Buffer Address */
202  ,const bool print_internal_buffer = false /* Print Internal Buffer Info */
203  ,const bool print_size_of_data = false /* Print Size Of Data */
204  ,const std::string separation_between_lines = "\n" /* Separation symbol between lines */
205  ,const uint32_t cols = 4 /* Number of columns in a line */
206  ) const;
207  /// Print word from Buffer
208  void printWord (const uint32_t iword, const bool is_bynary_printing, std::ostream& os=std::cout) const; ///! Print the i-th word of _Buffer, is_bynary_printing: true = bynary, false = HEX
209  void printWordBinary(const uint32_t word, std::ostream& os=std::cout) const;
210  void printWordHex (const uint32_t word, std::ostream& os=std::cout) const;
211  void printBinary (const void* buffer0, const uint32_t size, std::ostream& os=std::cout) const;
212  void printHex (const void* buffer0, const uint32_t size, std::ostream& os=std::cout) const;
213  void printUnknownVersion(std::ostream& out_stream=std::cout) const { out_stream<<"DAQDataFormat is of unknown version"<<std::endl;}
214 
215  /// Generic readData methods
216  void* readDataGeneral(const void* buffer, const uint32_t size_of_data_to_read);
217  void* readDataGeneral(const void* buffer, const uint32_t size_of_data_to_read, const uint32_t buffer_start_position);
218 
219  /// One can call this function from another function, which usage is not allowed (for a particular version).
220  bool functionIsNotAllowed(const std::string function="", const std::string message="") const;
221 
222  /// General routines for the default constructor of main class for fixed size data formats,
223  /// like RawNanoSliceHeader, Timing marker etc. (they can be different from version to version though)
224  /// But the difference is that we want to clear out the internal buffer for them,
225  /// whereas for floating data formats don't need to have that, since the data may be overwritten anyways
226  void defaultConstructorFixedSize();
227  void defaultConstructorFixedSize(init_t);
228 
229  /// General routines for the default constructor of main class for floating size data formats,
230  /// like RawNanoSlice, RawEvent etc.
231  /// We don't need to initialize internal buffer
232  void defaultConstructorFloatingSize();
233  void defaultConstructorFloatingSize(init_t);
234 
235 
236  /// Read data from the unknown version
237  void* readDataUnknownVersion(const void* buffer);
238 
239  /// is current _version unknown?
240  bool isVersionUnknown() const { return isVersionUnknown(_version);}
241  /// is input version unknown?
242  bool isVersionUnknown(const version_t version) const { return (version == rawdaqdataformat::DAQDATAFORMAT_UNKNOWN_VERSION);}
243 
244  /// Get uint64_t from low and hi word
245  uint64_t getUint64_t(uint32_t low_word , uint32_t hi_word) const;
246  bool getLoAndHi (uint64_t input_data, uint32_t& output_low_word, uint32_t& output_hi_word) const;
247 
248  /*
249  uint64_t getUint64_t(const DELEGATE(RawDAQData, function_get_low_word, uint32_t),
250  const DELEGATE(RawDAQData, function_get_hi_word , uint32_t)
251  )const;
252  */
253 
254  bool setUint64_t(uint64_t value,
255  DELEGATE(RawDAQData, function_set_low_word, bool, uint32_t),
256  DELEGATE(RawDAQData, function_set_hi_word , bool, uint32_t)
257  );
258 
259  /// Generating exception message as the version of DAQDataFormat is greater than the maximum allowed
260  std::string generateExceptionForWrongVersion(version_t maximum_version) const;
261 
262  /// Need to perform these operations in Deep Copy constructor
263  void lastOperationsInDeepCopy(const RawDAQData& copy_in);
264 
265  //------------- Private methods for RawDAQData. Can't be used by derived classes
266  private:
267 
268  /// Default constructor methods with custom reset_buffer_source method
269  /// so that one can use resetBufferSource or clear
270  void defaultConstructorGeneral(resetBufferSource_t);
271  void defaultConstructorGeneral(init_t, resetBufferSource_t);
272 
273  protected:
274 
275  /// All data formats need to have _Buffer and a Data structure. _Buffer will be common.
276  void* _Buffer;//!< The internal Buffer for each data format
277  //!< Generalized pointer to the buffer holding the packed data
278  //!< This pointer is used in performing generalized read/write calls
279  //!< and should be set during initialization
280 
281  /// The internal buffer to hold data.
282  /// Not always needed. A data format may have an external buffer.
283  std::vector <uint32_t> _InternalBuffer;
284 
285  /// Auxillary variable that holds whether the buffer should be external or internal
287 
288  /// DataFormat Version.
289  version_t _version;
290 
291  /// Some common function pointers used in each DAQDataFormats class
292  Init_t (_function_init);
293  Sizeofdata_t (_function_sizeofdata);
294  Print_t (_function_print);
295  ReadData_t (_function_readData);
296  SetBufferSource_t (_function_setBufferSource);
297 
298  /// These variables are only for Debugging purposes
299  EXECUTE_ON_DEBUG(std::string _dataFormatClassName);
300  EXECUTE_ON_DEBUG(std::string _dataFormatConstructor);
301 
302 
303  friend class novadaq::datalogger::DataBlockReader;
304 
305 };// end of RawDAQData class
306 
307 /// operator << so that one can put print it into an output stream directly
308 std::ostream& operator << (std::ostream& os, const daqdataformats::RawDAQData& dataformat);
309 
310 /// Method to calculate a shifts from a given mask.
311 /// The method is private for DAQDataFormats. Used by calculateShiftsFromMasks().
312 /// This method should not be used by any DAQDataFormat
313 uint32_t calculateShiftFromAGivenMask (const uint32_t mask);
314 
315 }// end of daqdataformats namespace
316 #endif /* RAWDAQDATA_BASE_H */
bool uint32_tToBool(const uint32_t number) const
Definition: RawDAQData.h:191
#define sizeofdata_t
Definition: FunctionBind.h:30
bool isVersionUnknown(const version_t version) const
is input version unknown?
Definition: RawDAQData.h:242
version_t _version
DataFormat Version.
Definition: RawDAQData.h:289
bool isVersionUnknown() const
is current _version unknown?
Definition: RawDAQData.h:240
void * _Buffer
All data formats need to have _Buffer and a Data structure. _Buffer will be common.
Definition: RawDAQData.h:276
#define EXECUTE_ON_DEBUG(x)
Debugging macros.
Definition: RawDAQData.h:34
vector< vector< double > > clear
#define Print_t(FUNC)
Definition: FunctionBind.h:23
#define Sizeofdata_t(FUNC)
Definition: FunctionBind.h:22
#define SetBufferSource_t(FUNC)
Definition: FunctionBind.h:25
void * getBuffer() const
Definition: RawDAQData.h:131
void * readData(const void *buffer, const uint32_t size_of_data)
Read from the buffer if the size of data is known.
Definition: RawDAQData.h:114
bool _shouldBufferBeInternal
Auxillary variable that holds whether the buffer should be external or internal.
Definition: RawDAQData.h:286
::xsd::cxx::tree::buffer< char > buffer
Definition: Database.h:179
const XML_Char int const XML_Char * value
Definition: expat.h:331
const int cols[3]
uint32_t boolToUint32_t(const bool number) const
Definition: RawDAQData.h:190
bool print
std::vector< uint32_t > _InternalBuffer
Definition: RawDAQData.h:283
bool isInternalBuffer() const
Definition: RawDAQData.h:141
#define print_t
Definition: FunctionBind.h:31
#define resetBufferSource_t
Definition: FunctionBind.h:34
OStream cout
Definition: OStream.cxx:6
const XML_Char * version
Definition: expat.h:187
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
#define setBufferSource_t
Definition: FunctionBind.h:33
#define ReadData_t(FUNC)
Definition: FunctionBind.h:24
#define Init_t(FUNC)
Definition: FunctionBind.h:21
uint32_t calculateShiftFromAGivenMask(const uint32_t mask)
Definition: RawDAQData.cpp:993
#define readData_t
Definition: FunctionBind.h:32
int32_t version_t
Definition: RawDAQData.h:72
void printUnknownVersion(std::ostream &out_stream=std::cout) const
Definition: RawDAQData.h:213
static const version_t DAQDATAFORMAT_UNKNOWN_VERSION
Definition: RawDAQData.h:81
Class to hold the data from the FEBs in correct formats.
#define init_t
Definition: FunctionBind.h:29
#define DELEGATE(CLASS, FUNC, OUTPUT,...)
Delegate (or function pointer)
Definition: FunctionBind.h:16
std::ostream & operator<<(std::ostream &os, const daqdataformats::RawDAQData &dataformat)
operator << so that one can put print it into an output stream directly