ICP  1
dae_events.cpp
Go to the documentation of this file.
1 #include "stdafx.h"
2 #include "isisvme.h"
3 #include "dae_events.h"
4 
6 void DAEEventList::checkEvents(const isisU32_t* buffer, uint32_t len, DAEstatus& status)
7 {
8  unsigned len_done = 0, len_bit = 1;
9  while(len > 0 && len_bit > 0)
10  {
11  len_bit = checkEventsFrame(buffer, len, status);
12  buffer += len_bit;
13  len -= len_bit;
14  len_done += len_bit;
15  }
16  if (len != 0)
17  {
18  throw std::exception("incomplete frame in buffer");
19  }
20 }
21 
23 {
24  int code = checkEventHeaderImpl(head);
25  if (code != 0)
26  {
27  std::string error_message;
28  getEventHeaderErrorMessage(head, code, error_message);
29  throw std::runtime_error(error_message);
30  }
31 }
32 
33 int DAEEventList::checkEventHeader(const DAEEventHeader* head, std::string& error_message)
34 {
35  int code = checkEventHeaderImpl(head);
36  if (code != 0)
37  {
38  getEventHeaderErrorMessage(head, code, error_message);
39  }
40  return code;
41 }
42 
45 {
46  int ret = 0x0;
48  {
49  ret += 0x1;
50  }
51  if ( (head->marker1 != EndOfRunMarker) && (head->marker1 != AllValuesFilledInMarker) )
52  {
53  if ( (head->marker1 == DummyHeaderMarker) || (head->marker1 == DummyEndOfRunMarker) )
54  {
55  ret += 0x20;
56  }
57  else
58  {
59  ret += 0x2;
60  }
61  }
62  if ( (head->marker1 == EndOfRunMarker) && (head->num_events != 0) )
63  {
64  ret += 0x4;
65  }
67  {
68  ret += 0x8;
69  }
70  if ( head->info.header_length % 2 != 0 )
71  {
72  ret += 0x10;
73  }
74  return ret;
75 }
76 
77 void DAEEventList::getEventHeaderErrorMessage(const DAEEventHeader* head, unsigned code, std::string& error_message)
78 {
79  std::ostringstream oss;
80  if (code & 0x1)
81  {
82  oss << "marker0=0x" << std::hex << head->marker0 << std::dec << ". ";
83  }
84  if (code & 0x2)
85  {
86  oss << "marker1=0x" << std::hex << head->marker1 << std::dec << ". ";
87  }
88  if (code & 0x4)
89  {
90  oss << "end run header: num_events=" << head->num_events << " (!= 0). ";
91  }
92  if (code & 0x8)
93  {
94  oss << "header_length field: " << head->info.header_length << " != " << DAE_EVENT_HEADER_WORDS << ". ";
95  }
96  if (code & 0x10)
97  {
98  oss << "header size: " << head->info.header_length << " is not an even number of 32bit words. ";
99  }
100  if (code & 0x20)
101  {
102  oss << "marker1=0x" << std::hex << head->marker1 << std::dec << " (Dummy). ";
103  }
104  error_message = oss.str();
105 }
106 
107 
108 
109 
111 int DAEEventList::findValidEventHeaderOffset(const isisU32_t* buffer, uint32_t len, DAEstatus& status)
112 {
113  std::string error_message;
114  if (len < DAE_EVENT_HEADER_WORDS) // need to check here as subtracting unsigned values could cause a problem in for loop
115  {
116  return -1;
117  }
118  for(int i=0; i < (len - DAE_EVENT_HEADER_WORDS); ++i)
119  {
120  if (buffer[i] == DAEEventHeaderFixedMarker)
121  {
122  if (checkEventHeader(reinterpret_cast<const DAEEventHeader*>(buffer+i), error_message) == 0)
123  {
124  return i;
125  }
126  }
127  }
128  return -1;
129 }
130 
135 uint32_t DAEEventList::getCompleteFramesLen(const isisU32_t* buffer, uint32_t len, DAEstatus& status)
136 {
137  unsigned n = 0;
138  while( (len - n) > DAE_EVENT_HEADER_WORDS )
139  {
140  const DAEEventHeader* head = reinterpret_cast<const DAEEventHeader*>(buffer + n);
141  checkEventHeader(head);
142  unsigned frame_len = DAE_EVENT_HEADER_WORDS + head->num_events;
143  if (n + frame_len > len)
144  {
145  break;
146  }
147  n += frame_len;
148  }
149  return n;
150 }
151 
155 uint32_t DAEEventList::checkEventsFrame(const isisU32_t* buffer, uint32_t len, DAEstatus& status)
156 {
157  if (len < DAE_EVENT_HEADER_WORDS)
158  {
159  throw std::exception("short frame - no header");
160  }
161  const DAEEventHeader* head = reinterpret_cast<const DAEEventHeader*>(buffer);
162  checkEventHeader(head);
163  int n = head->num_events;
164  int frame_len = head->info.header_length + n;
165  if ( frame_len > len )
166  {
167  throw std::exception("short frame - not enough events");
168  }
169 // DetectorEvent32* ev = reinterpret_cast<DetectorEvent32*>(buffer + head->info.header_length);
170 // for(int i=0; i<n; ++i)
171 // {
172 // ev[i].spectrum;
173 // ev[i].time_channel;
174 // }
175  return frame_len;
176 }
177 
180 {
181  checkEventHeader(head);
182  if (head->marker1 == EndOfRunMarker)
183  {
184  return true;
185  }
186  else
187  {
188  return false;
189  }
190 }
191 
192 void DAEEventList::DAETimeToSystemTime(const DAEEventHeader::DAETime& daetime, SYSTEMTIME& systime)
193 {
194  FILETIME filetime;
195  DAETimeToFILETIME(daetime, filetime);
196  if (FileTimeToSystemTime(&filetime, &systime) == 0)
197  {
198  memset(&systime, 0, sizeof(systime)); // error in FileTimeToSystemTime
199  }
200 }
201 
202 void DAEEventList::SystemTimeToDAETime(const SYSTEMTIME& systime, DAEEventHeader::DAETime& daetime)
203 {
204  FILETIME filetime;
205  if (SystemTimeToFileTime(&systime, &filetime) != 0)
206  {
207  FILETIMEToDAETime(filetime, daetime);
208  }
209  else
210  {
211  memset(&daetime, 0, sizeof(daetime)); // error in SystemTimeToFileTime
212  }
213 }
214 
215 void DAEEventList::DAETimeToFILETIME(const DAEEventHeader::DAETime& daetime, FILETIME& filetime)
216 {
217  ULARGE_INTEGER ularge;
218  ularge.LowPart = daetime.low;
219  ularge.HighPart = daetime.high;
220  ularge.QuadPart /= 5; // convert from 20ns to 100ns units
221  filetime.dwLowDateTime = ularge.LowPart;
222  filetime.dwHighDateTime = ularge.HighPart;
223 }
224 
225 template <typename T>
226 void DAEEventList::DAETimeToOffset(const DAEEventHeader::DAETime& daetime, time_t base, T& offset)
227 {
228  SYSTEMTIME systime;
229  DAETimeToSystemTime(daetime, systime);
230  Poco::Timestamp base_timestamp = Poco::Timestamp::fromEpochTime(base);
231  Poco::DateTime dae_dt(systime.wYear, systime.wMonth, systime.wDay, systime.wHour, systime.wMinute, systime.wSecond, systime.wMilliseconds);
232  offset = static_cast<T>(dae_dt.timestamp() - base_timestamp) / static_cast<T>(1000000); // Poco::Timestamp::TimeDiff is in microseconds
233 }
234 
235 template void DAEEventList::DAETimeToOffset(const DAEEventHeader::DAETime& daetime, time_t base, float& offset);
236 //template void DAEEventList::DAETimeToOffset(const DAEEventHeader::DAETime& daetime, time_t base, double& offset);
237 
238 void DAEEventList::OffsetToDAETime(time_t base, double offset, DAEEventHeader::DAETime& daetime)
239 {
240  Poco::Timestamp base_timestamp = Poco::Timestamp::fromEpochTime(base);
241  base_timestamp += static_cast<int64_t>(offset * 1.0e6); // Poco::Timestamp::TimeDiff is in microseconds
242  Poco::DateTime dae_dt(base_timestamp);
243  SYSTEMTIME systime;
244  systime.wYear = static_cast<WORD>(dae_dt.year());
245  systime.wMonth = static_cast<WORD>(dae_dt.month());
246  systime.wDay = static_cast<WORD>(dae_dt.day());
247  systime.wHour = static_cast<WORD>(dae_dt.hour());
248  systime.wMinute = static_cast<WORD>(dae_dt.minute());
249  systime.wSecond = static_cast<WORD>(dae_dt.second());
250  systime.wMilliseconds = static_cast<WORD>(dae_dt.millisecond());
251  SystemTimeToDAETime(systime, daetime);
252 }
253 
254 
255 void DAEEventList::FILETIMEToDAETime(const FILETIME& filetime, DAEEventHeader::DAETime& daetime)
256 {
257  ULARGE_INTEGER ularge;
258  ularge.LowPart = filetime.dwLowDateTime;
259  ularge.HighPart = filetime.dwHighDateTime;
260  ularge.QuadPart *= 5; // convert from 100ns to 20ns units
261  daetime.low = ularge.LowPart;
262  daetime.high = ularge.HighPart;
263 }
264 
267 {
268  std::string s1, s2;
269  SYSTEMTIME systime; // SYSTEMTIME is in UTC
270  DAETimeToSystemTime(daetime, systime);
271  Poco::format(s1, "%04u-%02u-%02u",
272  static_cast<unsigned>(systime.wYear), static_cast<unsigned>(systime.wMonth), static_cast<unsigned>(systime.wDay));
273  Poco::format(s2, "%sT%02u:%02u:%02u.%u", s1, static_cast<unsigned>(systime.wHour),
274  static_cast<unsigned>(systime.wMinute), static_cast<unsigned>(systime.wSecond),
275  static_cast<unsigned>(systime.wMilliseconds)); // all the casts seem to be required - just using "%uh" didn't work
276  return s2;
277 }
278 
279 void DAEEventList::printEventHeader(const DAEEventHeader* head, std::ostream& os)
280 {
281  std::string err_str;
282  if (checkEventHeader(head, err_str) != 0)
283  {
284  os << "Frame header invalid: " << err_str << "\n";
285  }
286  os << "Frame " << head->frame_number << "\n";
287  os << "Num events " << head->num_events << "\n";
288  os << "Time " << DAETimeAsString(head->time) << "\n";
289 }
290 
291 void DAEEventList::printDetectorEvents(const DetectorEvent32* events, int n, std::ostream& os)
292 {
293  for(int i=0; i<n; ++i)
294  {
295  os << "time channel " << events[i].time_channel << " spectrum " << events[i].spectrum << std::endl;
296  }
297 }
static int checkEventHeaderImpl(const DAEEventHeader *head)
return 0x20 if dummy header present
Definition: dae_events.cpp:44
static void printEventHeader(const DAEEventHeader *head, std::ostream &os)
Definition: dae_events.cpp:279
uint32_t num_events
Definition: dae_events.h:60
uint32_t marker1
should always be DAEEventHeaderFixedMarker
Definition: dae_events.h:47
fixed header marker for DAEEventHeader
Definition: dae_events.h:44
unsigned long isisU32_t
Definition: isisvme_types.h:8
static const int DAEEventHeaderFixedMarker
Definition: dae_events.h:40
static void OffsetToDAETime(time_t base, double offset, DAEEventHeader::DAETime &daetime)
Definition: dae_events.cpp:238
static void getEventHeaderErrorMessage(const DAEEventHeader *head, unsigned code, std::string &error_message)
Definition: dae_events.cpp:77
unsigned header_length
Definition: dae_events.h:11
static void DAETimeToFILETIME(const DAEEventHeader::DAETime &daetime, FILETIME &filetime)
Definition: dae_events.cpp:215
static void DAETimeToSystemTime(const DAEEventHeader::DAETime &daetime, SYSTEMTIME &systime)
Definition: dae_events.cpp:192
static uint32_t getCompleteFramesLen(const isisU32_t *buffer, uint32_t len, DAEstatus &status)
Definition: dae_events.cpp:135
static void SystemTimeToDAETime(const SYSTEMTIME &systime, DAEEventHeader::DAETime &daetime)
Definition: dae_events.cpp:202
DAEEventHeaderInfo info
should be DAEEventHeaderMarker
Definition: dae_events.h:48
static int findValidEventHeaderOffset(const isisU32_t *buffer, uint32_t len, DAEstatus &status)
returns index of start of a valid event header, -1 on error
Definition: dae_events.cpp:111
uint32_t marker0
Definition: dae_events.h:46
struct DAEEventHeader::DAETime time
static void printDetectorEvents(const DetectorEvent32 *events, int n, std::ostream &os)
Definition: dae_events.cpp:291
static void DAETimeToOffset(const DAEEventHeader::DAETime &daetime, time_t base, T &offset)
Definition: dae_events.cpp:226
static std::string DAETimeAsString(const DAEEventHeader::DAETime &daetime)
return as ISO8601 format string
Definition: dae_events.cpp:266
unsigned time_channel
Definition: dae_events.h:78
uint32_t frame_number
Definition: dae_events.h:49
static const unsigned DAE_EVENT_HEADER_WORDS
Definition: dae_events.h:102
unsigned spectrum
Definition: dae_events.h:79
static void FILETIMEToDAETime(const FILETIME &filetime, DAEEventHeader::DAETime &daetime)
Definition: dae_events.cpp:255
static bool isEndRunHeader(const DAEEventHeader *head, DAEstatus &status)
check whether an event frame header is a special enf of frame header
Definition: dae_events.cpp:179
static void checkEvents(const isisU32_t *buffer, uint32_t maxlen, DAEstatus &status)
checks that buffer corresponds to a copmplete set of event frames
Definition: dae_events.cpp:6
static uint32_t checkEventsFrame(const isisU32_t *buffer, uint32_t maxlen, DAEstatus &status)
Definition: dae_events.cpp:155
static void checkEventHeader(const DAEEventHeader *head)
Definition: dae_events.cpp:22