ICP  1
events_tool.cpp
Go to the documentation of this file.
1 // events_tool.cpp : Defines the entry point for the console application.
2 //
3 
5 
6 #include "stdafx.h"
7 #include "../newicp/icputils.h"
8 #include "../newicp/event_store.h"
9 #include "../newicp/TCPEventStreamDefs.h"
10 #include "../newicp/isisraw.h"
11 #include "../nexus/NeXusFile.hpp"
12 
13 class EventsToolApp : public Poco::Util::Application, public ISIS::Base
14 {
15 public:
16  EventsToolApp() : Poco::Util::Application() { }
17  virtual int main(const std::vector<std::string>& args);
18 protected:
19  void initialize(Poco::Util::Application& self)
20  {
21  loadConfiguration();
22  Application::initialize(self);
23  setLoggerName("EventsToolApp");
24  }
25 
26  void uninitialize()
27  {
28  Poco::Util::Application::uninitialize();
29  }
30 
31  void defineOptions(Poco::Util::OptionSet& options);
32  void displayHelp();
33  void handleHelp(const std::string& name, const std::string& value);
34  int convertRawToEvents(const std::string& raw_file, int run_number);
35  int processNeXusFile(const std::string& nexus_file);
36  int liveData(const std::string& host);
37 };
38 
39 
40 int _tmain(int argc, _TCHAR* argv[])
41 {
42  EventsToolApp app;
43  app.init(argc, argv);
44  int ret = app.run();
45  return ret;
46 }
47 
48 void EventsToolApp::defineOptions(Poco::Util::OptionSet& options)
49 {
50  Application::defineOptions(options);
51 
52  options.addOption(Poco::Util::Option("help", "h", "display help information")
53  .required(false)
54  .repeatable(false)
55  .callback(Poco::Util::OptionCallback<EventsToolApp>(this, &EventsToolApp::handleHelp))
56  );
57 
58  options.addOption(Poco::Util::Option("run-number", "r", "specify run number")
59  .required(false)
60  .repeatable(false)
61  .argument("value")
62  .binding("events_tool.run_number")
63  );
64 
65  options.addOption(Poco::Util::Option("file", "f", "specify raw file")
66  .required(false)
67  .repeatable(false)
68  .argument("file")
69  .binding("events_tool.raw_file")
70  );
71 
72  options.addOption(Poco::Util::Option("event-dir", "d", "specify directory for event files")
73  .required(false)
74  .repeatable(false)
75  .argument("value")
76  .binding("events_tool.event_dir")
77  );
78 
79  options.addOption(Poco::Util::Option("nxfile", "n", "specify nexus file")
80  .required(false)
81  .repeatable(false)
82  .argument("file")
83  .binding("events_tool.nexus_file")
84  );
85 
86  options.addOption(Poco::Util::Option("live", "l", "live data host")
87  .required(false)
88  .repeatable(false)
89  .argument("value")
90  .binding("events_tool.live_host")
91  );
92 
93 // options.addOption(Option("config-file", "f", "load configuration data from a file")
94 // .required(false)
95 // .repeatable(true)
96 // .argument("file")
97 // .callback(OptionCallback<InstCtrlApp>(this, &EventsToolApp::handleConfig)));
98 
99 // options.addOption(Option("bind", "b", "bind option value to test.property")
100 // .required(false)
101 // .argument("value")
102 // .validator(new IntValidator(0, 100))
103 // .binding("test.pro
104 }
105 
107 {
108  Poco::Util::HelpFormatter helpFormatter(options());
109  helpFormatter.setCommand(commandName());
110  helpFormatter.setUsage("OPTIONS");
111  helpFormatter.setHeader(
112  "A sample application that demonstrates some of the features "
113  "of the Poco::Util::Application class.");
114  helpFormatter.format(std::cout);
115 }
116 
117 void EventsToolApp::handleHelp(const std::string& name, const std::string& value)
118 {
119 // _helpRequested = true;
120  displayHelp();
121  stopOptionsProcessing();
122 }
123 
124 static uint64_t all_events_c = 0;
125 static uint64_t good_events_c = 0;
126 
127 static std::map<int,uint64_t> raw_protons;
128 static std::map<int,uint64_t> good_protons;
129 static std::map<int,uint64_t> raw_events;
130 static std::map<int,uint64_t> good_events;
131 static std::map<int,int> first_data_frame;
132 
133 static Poco::Mutex the_mutex;
134 
135 static void all_event_callback(const DAEEventHeader* head, const DetectorEvent32* det_ev, int n, int event_source_id, const int* mapping)
136 {
137  Poco::Mutex::ScopedLock _lock(the_mutex);
138  all_events_c += n;
139 }
140 
141 //static std::map<int,int> spec_map;
142 
143 static void good_event_callback(const DAEEventHeader* head, const DetectorEvent32* det_ev, int n, int event_source_id, const int* mapping)
144 {
145  Poco::Mutex::ScopedLock _lock(the_mutex);
146  int code;
147  for(int i=0; i<n; ++i)
148  {
149  code = 1000 * det_ev[i].spectrum + event_source_id;
150  if ( first_data_frame.find(code) == first_data_frame.end() )
151  {
152  first_data_frame[code] = head->frame_number;
153  }
154  }
155  good_events_c += n;
156 }
157 
158 
159 static void convert_good_event_callback(const DAEEventHeader* head, const DetectorEvent32* det_ev, int n, int event_source_id, const int* mapping)
160 {
161  Poco::Mutex::ScopedLock _lock(the_mutex);
162  good_events_c += n;
163 // if (event_source_id == 2)
164 // {
165 // for(int i=0; i<n; ++i)
166 // {
167 // ++(spec_map[det_ev[i].spectrum]);
168 // }
169 // }
170 }
171 
172 static void all_frame_callback(const DAEEventHeader* head, int event_source_id)
173 {
174  Poco::Mutex::ScopedLock _lock(the_mutex);
175 // std::cerr << "Frame " << head->frame_number << " time " << DAEEventList::DAETimeAsString(head->time) << std::endl;
176  raw_protons[head->frame_number] = head->protons;
177  raw_events[head->frame_number] += head->num_events;
178 }
179 
180 static void good_frame_callback(const DAEEventHeader* head, int event_source_id)
181 {
182  Poco::Mutex::ScopedLock _lock(the_mutex);
183  good_protons[head->frame_number] = head->protons;
184  good_events[head->frame_number] += head->num_events;
185 }
186 
187 #define PPP_TO_UAMPH 1.738E-6
188 
189 int EventsToolApp::main(const std::vector<std::string>& args)
190 {
191 // Poco::Logger::root().setLevel(Poco::Message::PRIO_TRACE); // default for new loggers
192  Poco::Logger::root().setLevel(Poco::Message::PRIO_INFORMATION); // default for new loggers
193  logger().setLevel(Poco::Message::PRIO_TRACE); // sets for current application logger
194 
195  if (loadAppConfig("isisicp") != 0)
196  {
197  return Poco::Util::Application::EXIT_CONFIG;
198  }
199  if (loadAppConfig("events_tool") != 0)
200  {
201  return Poco::Util::Application::EXIT_CONFIG;
202  }
203 
204  int run_number = Poco::Util::Application::instance().config().getInt("events_tool.run_number", -1);
205  std::string raw_file = Poco::Util::Application::instance().config().getString("events_tool.raw_file","");
206  std::string nexus_file = Poco::Util::Application::instance().config().getString("events_tool.nexus_file","");
207  std::string live_host = Poco::Util::Application::instance().config().getString("events_tool.live_host","");
208 
209  if (live_host.size() > 0)
210  {
211  return liveData(live_host);
212  }
213  if (raw_file.size() > 0)
214  {
215  return convertRawToEvents(raw_file, run_number);
216  }
217  if (nexus_file.size() > 0)
218  {
219  return processNeXusFile(nexus_file);
220  }
221  EventStore es;
223  es.addFileInputSource(run_number, info);
224  LOGSTR_INFORMATION("Info file says " << info.raw_frames << " raw frames and " << info.raw_events << " raw events");
229  es.start();
230  while (!es.endHeaderSeen())
231  {
232  Sleep(500);
233  }
234  es.stop(false);
235  LOGSTR_INFORMATION("Found " << raw_protons.size() << " raw frames and " << good_protons.size() << " good frames");
236  LOGSTR_INFORMATION("Found " << all_events_c << " and " << sum_map_values(raw_events) << " raw events");
237  LOGSTR_INFORMATION("Found " << good_events_c << " and " << sum_map_values(good_events) << " good events");
238  uint64_t raw_ppp = sum_map_values(raw_protons);
239  uint64_t good_ppp = sum_map_values(good_protons);
240  LOGSTR_INFORMATION("Raw uAmpH " << raw_ppp * PPP_TO_UAMPH << " good uAmpH " << good_ppp * PPP_TO_UAMPH);
241  for(std::map<int,int>::const_iterator it = first_data_frame.begin(); it != first_data_frame.end(); ++it)
242  {
243  int es = it->first % 1000;
244  int spec = it->first / 1000;
245  LOGSTR_INFORMATION("Source id " << es << " spectrum " << spec << " first data frame " << it->second);
246  }
247  return 0;
248 }
249 
250 int EventsToolApp::convertRawToEvents(const std::string& raw_file, int run_number)
251 {
252  int i, ndet;
253  DAEstatus status;
254  ISISRAW *ir = new ISISRAW;
255  ir->readFromFile(raw_file.c_str());
256  ir->printInfo(std::cout);
257  ndet = ir->i_det;
258  EventStore es;
259  std::vector<int> cards(ndet);
260  std::copy(ir->crat, ir->crat + ndet, cards.begin());
261  std::sort(cards.begin(), cards.end());
262  std::vector<int>::iterator new_end = std::unique(cards.begin(), cards.end());
263  cards.resize(new_end - cards.begin());
264  time_t run_start = time(NULL);
265  for(i=0; i<cards.size(); ++i)
266  {
267  es.addRawFileInputSource(ir, cards[i], run_start);
268  }
269  es.setOutputFileName(run_number, true, status);
271  es.start();
272  while (!es.endHeaderSeen())
273  {
274  Sleep(500);
275  }
276  es.stop(false);
277  LOGSTR_INFORMATION("good events " << good_events_c);
278 // LOGSTR_INFORMATION("spec_map[15] " << spec_map[15]);
279  return 0;
280 }
281 
282 int EventsToolApp::processNeXusFile(const std::string& nexus_file)
283 {
284  NeXus::File nxfile(nexus_file);
285  std::vector<uint64_t> event_index;
286  nxfile.openPath("/raw_data_1/detector_1_events/event_index");
287  nxfile.getData(event_index);
288  int nframes = event_index.size(); // event_index.size();
289  nframes = std::min(nframes, 2400);
290  int nframes_stuff = std::min(nframes, 100);
291  uint64_t iend = event_index[nframes-1];
292  std::cerr << "Reading " << nframes << " frames and " << iend << " events from " << nexus_file << std::endl;
293  std::vector<uint32_t> event_id(iend);
294  nxfile.openPath("/raw_data_1/detector_1_events/event_id");
295 // nxfile.getData(event_id);
296  std::vector<int> istart, isize;
297  istart.push_back(0);
298  isize.push_back(iend);
299  nxfile.getSlab(&(event_id[0]), istart, isize);
300 
301  std::vector<int> crat, spec;
302  nxfile.openPath("/raw_data_1/isis_vms_compat/CRAT");
303  nxfile.getData(crat);
304  nxfile.openPath("/raw_data_1/isis_vms_compat/SPEC");
305  nxfile.getData(spec);
306 
307  nxfile.close();
308 
309  std::map<int,int> crat_map;
310  for(int i=0; i<spec.size(); ++i)
311  {
312  crat_map[spec[i]] = crat[i];
313  }
314 
315 
316  std::cerr << "Starting to process events" << std::endl;
317 
318  uint32_t maxspec = 0;
319  for(uint32_t i=0; i < nframes-1; ++i) // i is frame number
320  {
321  for(uint64_t j=event_index[i]; j < event_index[i+1]; ++j) // j is index of events for frame i
322  {
323  maxspec = std::max(maxspec, event_id[j]);
324  }
325  }
326  std::cout << " Frames " << nframes << " max spec number " << maxspec << std::endl;
327 
328  typedef std::vector< std::vector<uint32_t> > stuff_t;
329  stuff_t stuff(nframes_stuff, 0);
330  std::vector<int> first_counts(maxspec+1, -1), last_counts(maxspec+1, -1), counts_per_frame(nframes, 0);
331  for(uint32_t i=0; i<nframes_stuff; ++i)
332  {
333  stuff[i].resize(maxspec+1, 0);
334  }
335  for(uint32_t i=0; i < nframes-1; ++i) // i is frame number
336  {
337  for(uint64_t j=event_index[i]; j < event_index[i+1]; ++j) // j is index of events for frame i
338  {
339  ++(counts_per_frame[i]);
340  if ( first_counts[event_id[j]] == -1 )
341  {
342  first_counts[event_id[j]] = i;
343  }
344  last_counts[event_id[j]] = i;
345  if ( i < nframes_stuff )
346  {
347  ++(stuff[i][event_id[j]]);
348  }
349  }
350  }
351  for(uint32_t i=0; i < nframes; ++i) // frame
352  {
353 // std::cout << "Total counts in frame " << i << " = " << std::accumulate(stuff[i].begin(), stuff[i].end(), 0) << std::endl;
354  std::cout << "Total counts in frame " << i << " = " << counts_per_frame[i] << std::endl;
355  }
356  for(uint32_t j=0; j <= maxspec; ++j) // spectra
357  {
358  std::cout << "Spec " << j << " card " << crat_map[j] << " first counts frame " << first_counts[j] << " last counts frame " << last_counts[j] << std::endl;
359 // if (last_counts[j] != -1)
360 // {
361 // std::cout << "Spec " << j << " first counts frame " << first_counts[j] << " last counts frame " << last_counts[j] << std::endl;
362 // }
363  }
364 // for(uint32_t j=77830; j <= maxspec; ++j)
365 // {
366 // std::cout << "* Per frame distribution for spec " << j << std::endl;
367 // for(uint32_t i=0; i < nframes; ++i) // frame
368 // {
369 // std::cout << "Frame " << i << " counts " << stuff[i][j] << std::endl;
370 // }
371 // }
372 // if ( stuff[i].find(j) != stuff[i].end() )
373 // {
374 // std::cout << "Frame " << i << " spectra " << j << " counts " << stuff[i][j] << std::endl;
375 // }
376  return 0;
377 }
378 
380 int EventsToolApp::liveData(const std::string& host)
381 {
382  static char* junk_buffer[10000];
383  Poco::Net::StreamSocket s;
384  unsigned port = 10000;
385  Poco::Net::SocketAddress address(host, port);
386  s.connect(address);
388  while( s.available() < sizeof(setup) )
389  {
390  Poco::Thread::sleep(1000);
391  }
392  s.receiveBytes(&setup, sizeof(setup));
393  if ( !setup.isValid() )
394  {
395  throw std::runtime_error("version wrong");
396  }
397  std::cerr << "run number " << setup.head_setup.run_number << std::endl;
399  while(true)
400  {
401  while(s.available() < sizeof(events.head))
402  {
403  Poco::Thread::sleep(100);
404  }
405  s.receiveBytes(&events.head, sizeof(events.head));
406  if ( !events.head.isValid() )
407  {
408  throw std::runtime_error("corrupt stream - you should reconnect");
409  }
410  if ( !(events.head.type == TCPStreamEventHeader::Neutron) )
411  {
412  throw std::runtime_error("corrupt stream - you should reconnect");
413  }
414  s.receiveBytes(junk_buffer, events.head.length - sizeof(events.head));
415  while(s.available() < sizeof(events.head_n))
416  {
417  Poco::Thread::sleep(100);
418  }
419  s.receiveBytes(&events.head_n, sizeof(events.head_n));
420  if ( !events.head_n.isValid() )
421  {
422  throw std::runtime_error("corrupt stream - you should reconnect");
423  }
424  s.receiveBytes(junk_buffer, events.head_n.length - sizeof(events.head_n));
425  events.data.resize(events.head_n.nevents);
426  int nread = 0;
427  while( nread < events.head_n.nevents )
428  {
429  int ntoread = s.available() / sizeof(TCPStreamEventNeutron);
430  if ( ntoread > (events.head_n.nevents - nread) )
431  {
432  ntoread = events.head_n.nevents - nread;
433  }
434  if (ntoread > 0)
435  {
436  s.receiveBytes(&(events.data[nread]), ntoread * sizeof(TCPStreamEventNeutron));
437  nread += ntoread;
438  }
439  else
440  {
441  Poco::Thread::sleep(100);
442  }
443  }
444  if (!events.isValid())
445  {
446  throw std::runtime_error("corrupt stream - you should reconnect");
447  }
448  TCPStreamEventHeader& head = events.head;
449  TCPStreamEventHeaderNeutron& head_n = events.head_n;
450  std::cerr << "Read " << nread << " events for frame number " << head_n.frame_number << " time " << head_n.frame_time_zero << std::endl;
451  for(int i=0; i<std::min(10,nread); ++i)
452  {
453  std::cerr << events.data[i].time_of_flight << " " << events.data[i].spectrum << std::endl;
454  }
455  }
456  s.close();
457  return 0;
458 }
static void all_event_callback(const DAEEventHeader *head, const DetectorEvent32 *det_ev, int n, int event_source_id, const int *mapping)
void initialize(Poco::Util::Application &self)
Definition: events_tool.cpp:19
std::list< boost::signals2::connection > addGoodFrameCallback(const FrameCallbackSlotType &slot)
uint32_t num_events
Definition: dae_events.h:60
static std::map< int, uint64_t > raw_protons
fixed header marker for DAEEventHeader
Definition: dae_events.h:44
void defineOptions(Poco::Util::OptionSet &options)
Definition: events_tool.cpp:48
float frame_time_zero
time offset from run_start of this frame, in seconds
int readFromFile(const char *filename)
Definition: isisraw.cpp:1239
static std::map< int, uint64_t > raw_events
static void good_event_callback(const DAEEventHeader *head, const DetectorEvent32 *det_ev, int n, int event_source_id, const int *mapping)
int convertRawToEvents(const std::string &raw_file, int run_number)
static std::map< int, int > first_data_frame
int printInfo(std::ostream &os)
Definition: isisraw.cpp:1284
static void good_frame_callback(const DAEEventHeader *head, int event_source_id)
static Poco::Mutex the_mutex
void setOutputFileName(int run_number, bool new_run, DAEstatus &status)
void handleHelp(const std::string &name, const std::string &value)
static void convert_good_event_callback(const DAEEventHeader *head, const DetectorEvent32 *det_ev, int n, int event_source_id, const int *mapping)
virtual int main(const std::vector< std::string > &args)
static std::map< int, uint64_t > good_protons
static uint64_t good_events_c
static void all_frame_callback(const DAEEventHeader *head, int event_source_id)
unsigned protons
Definition: dae_events.h:63
void stop(bool immediate)
uint32_t nevents
number of TCPStreamEvent() structures in this packet
std::list< boost::signals2::connection > addAllFrameCallback(const FrameCallbackSlotType &slot)
this structure is part of a sequence of neutron events, which are all from the same ISIS frame ...
static std::map< int, uint64_t > good_events
int i_det
Definition: isisraw.h:269
std::list< boost::signals2::connection > addGoodEventCallback(const EventCallbackSlotType &slot)
#define LOGSTR_INFORMATION(__arg)
Definition: IsisBase.h:78
bool endHeaderSeen()
static uint64_t all_events_c
void uninitialize()
Definition: events_tool.cpp:26
structure describing an individual neutron event following on from a TCPStreamEventHeaderNeutron ...
int loadAppConfig(const std::string &app_name)
load a config file from ../../.. i.e. from c:/labview modules/dae if we are in c:/labview modules/dae...
Definition: icputils.cpp:866
TCPStreamEventHeaderNeutron head_n
details of ISIS frame data was collected in and the number of neutron events in this packet ...
std::vector< TCPStreamEventNeutron > data
list of neutron events
int run_number
run number from ISISCRPT_STRUCT
uint32_t frame_number
Definition: dae_events.h:49
unsigned spectrum
Definition: dae_events.h:79
uint32_t length
packet size in bytes
uint32_t length
this packet size in bytes
U sum_map_values(const std::map< T, U > &m)
Definition: icputils.h:507
void setLoggerName(const std::string &logger_name)
Definition: IsisBase.h:17
uint32_t type
StreamDataType
TCPStreamEventHeaderSetup head_setup
void displayHelp()
int _tmain(int argc, _TCHAR *argv[])
Definition: newicp.cpp:11
void addRawFileInputSource(ISISRAW *iraw, int source_id, time_t run_start)
layout of initial data packet send on initial connection and on a state change e.g. run number changes
void start()
int liveData(const std::string &host)
connect to an event mode control progam and read live events
int processNeXusFile(const std::string &nexus_file)
void addFileInputSource(int run_number, FileEventSourceInfo &info)
std::list< boost::signals2::connection > addAllEventCallback(const EventCallbackSlotType &slot)
int * crat
Definition: isisraw.h:290
TCPStreamEventHeader head
uint32_t frame_number
ISIS frame number, 0 being first frame of run.
#define PPP_TO_UAMPH