ICP  1
NeXusEventCallback.h
Go to the documentation of this file.
1 #ifndef NeXusEventCallback_H
2 #define NeXusEventCallback_H
3 
4 #include "nexuswriter.h"
5 
6 typedef std::map< std::string,std::vector<int> > int_map_t;
7 typedef std::map< std::string,std::vector<uint32_t> > uint_map_t;
8 typedef std::map< std::string,std::vector<float> > float_map_t;
9 
10 class NeXusEventCallback;
11 
13 {
15  Poco::Event& ev;
18  int nev;
21  NeXusWorkerData(NeXusEventCallback* object_, Poco::Event& ev_, const DAEEventHeader* head_, int event_source_id_, int nev_, const int_map_t& event_id_, const float_map_t& event_time_offset_) :
22  object(object_), ev(ev_), head(head_), event_source_id(event_source_id_), nev(nev_), event_id(event_id_), event_time_offset(event_time_offset_) { }
23 };
24 
25 class NeXusWorker : public GenericWorker<NeXusWorkerData>
26 {
27 public:
28  virtual void doWork(NeXusWorkerData* data);
29  NeXusWorker(Poco::NotificationQueue& queue) : GenericWorker<NeXusWorkerData>(queue) { }
30 };
31 
33 {
34  friend class NeXusWorker;
35 public:
36  NeXusEventCallback(const ISISCRPT_STRUCT* crpt, IXNeXusFile* file, const std::vector<int>& ev_source_ids);
37  void allEventCallback(const DAEEventHeader* head, const DetectorEvent32* det_ev, int n, int event_source_id, const int* mapping);
38  void allFrameCallback(const DAEEventHeader* head, int event_source_id);
39  void noFrameCallbackEnd(bool end_present, NoFrameCallbackMode mode, int event_source_id);
40  void noFrameCallbackNull(bool end_present, NoFrameCallbackMode mode, int event_source_id);
41  void finish();
42  void flush();
45  static float getTimeOffset(const ISISCRPT_STRUCT* crpt, const DetectorEvent32* det_ev, int event_source_id, int tr, int i);
46 
47 private:
48  Poco::NotificationQueue m_queue;
50  Poco::Thread m_worker_thread;
51 
55 
56  uint64_t m_good_uamph_sum;
57  uint64_t m_raw_uamph_sum;
59  uint64_t m_raw_events_sum;
60 
61  static const int INVALID_FRAME_MARKER;
62 
63  void close();
64  Poco::MemoryPool m_mempool;
65  std::string m_entry_name;
66  static const int m_nexus_chunk_length;
67  template<typename T>
69  {
70  public:
71  typedef boost::pool_allocator<T,boost::default_user_allocator_new_delete,boost::details::pool::default_mutex,100000> alloc;
72  };
73 // typedef std::map< std::string,std::vector<int,myallocator<int>::alloc> > int_map_t;
74 // typedef std::map< std::string,std::vector<float,myallocator<float>::alloc> > float_map_t;
77  static Poco::Mutex m_frame_callback_mutex;
78  static Poco::Mutex m_event_write_mutex;
79  static Poco::Condition m_event_write_cond;
82  typedef std::map< std::string, std::vector<IXNeXusFile*> > det_file_t;
84 
88 
93  std::vector<float> m_frame_time;
94  std::vector<float> m_frame_proton_charge;
95  std::map<int,uint32_t> m_frame_events_raw;
96  std::vector<int> m_frame_number;
97  std::vector<int> m_frame_period;
98  std::vector<int> m_good_frame;
99 // std::map<int,int> m_first_data_frame;
101  NXlogWriter<int> m_vetoing; // 1 if vetoing (raw frame)
103  std::vector<int> m_det_id;
104  typedef boost::bimap<std::string,int> det_name_t;
107  typedef std::map< int,std::pair<int,time_t> > card_frame_t;
109  typedef std::map<std::string,std::map<int,int>> frame_events_write_t;
111  std::map<std::string,uint64_t> m_events_write_total;
112  std::map<std::string,int> m_det_tr;
113  std::set<std::string> m_event_det; // list of names of event mode detectors
114  int getSpectrum(const DetectorEvent32* det_ev, int event_source_id, int i);
115  void writeEvents(const DAEEventHeader* head, int event_source_id, int nev, const int_map_t& event_id, const float_map_t& event_time_offset);
116  void writeEventsImpl(const DAEEventHeader* head, int event_source_id, int nev, const int_map_t& event_id, const float_map_t& event_time_offset);
117  int currentWriteFrame() const;
118  void updateCurrentWriteFrame(int frame, int event_source_id);
119  void makeDetName(int spec, std::string& det_name);
120  void openDataGroup(IXNeXusFile* nx, const std::string& name, bool create_zero_size_if_missing = false);
121  void closeDataGroup(IXNeXusFile* nx, const std::string& name);
122  void openDataGroup(const std::string& name, bool create_zero_size_if_missing = false) { return openDataGroup(m_file, name, create_zero_size_if_missing); }
123  void closeDataGroup(const std::string& name) { return closeDataGroup(m_file, name); }
124  int getRefEventDetCard(const std::vector<int>& ev_source_ids);
125  float getTimeOffset(const DetectorEvent32* det_ev, int event_source_id, int tr, int i) { return getTimeOffset(m_crpt, det_ev, event_source_id, tr, i); }
126  void processDataDae(const DAEEventHeader* head, const DetectorEvent32* det_ev, int n, int event_source_id);
127 };
128 
130 inline int NeXusEventCallback::getSpectrum(const DetectorEvent32* det_ev, int event_source_id, int i)
131 {
132  return m_crpt->dae1SpecForCard(event_source_id, det_ev[i].spectrum);
133 }
134 
136 {
137  data->object->writeEventsImpl(data->head, data->event_source_id, data->nev, data->event_id, data->event_time_offset);
138  data->ev.set();
139 }
140 
141 #if 0
142 #define PHI 0x9e3779b9
143 
144 static uint32_t Q[4096], c = 362436;
145 
146 static void init_rand(uint32_t x)
147 {
148  int i;
149 
150  Q[0] = x;
151  Q[1] = x + PHI;
152  Q[2] = x + PHI + PHI;
153 
154  for (i = 3; i < 4096; i++)
155  Q[i] = Q[i - 3] ^ Q[i - 2] ^ PHI ^ i;
156 }
157 
158 static uint32_t rand_cmwc(void)
159 {
160  uint64_t t, a = 18782LL;
161  static uint32_t i = 4095;
162  uint32_t x, r = 0xfffffffe;
163  i = (i + 1) & 4095;
164  t = a * Q[i] + c;
165  c = (t >> 32);
166  x = t + c;
167  if (x < c) {
168  x++;
169  c++;
170  }
171  return (Q[i] = r - x);
172 }
173 #endif
174 
177 inline float NeXusEventCallback::getTimeOffset(const ISISCRPT_STRUCT* crpt, const DetectorEvent32* det_ev, int /*event_source_id*/, int tr, int i)
178 {
179  static bool random_shift = Poco::Util::Application::instance().config().getBool("isisicp.randomeventbinshift", true);
180  int tc_index = static_cast<int>(det_ev[i].time_channel) - 1;
181  float tim = 0.0;
182  if ( tc_index >= 0 && tc_index < crpt->ntc[tr-1] )
183  {
184  if (random_shift)
185  {
186  tim = crpt->rtcb[tr-1][tc_index] +
187  (crpt->rtcb[tr-1][tc_index+1] - crpt->rtcb[tr-1][tc_index]) * ((float)rand() / (float)(RAND_MAX+1));
188  }
189  else
190  {
191  tim = (crpt->rtcb[tr-1][tc_index] + crpt->rtcb[tr-1][tc_index+1]) / 2.0; // average bin boundaries for event time
192  }
193  }
194  return tim;
195 }
196 
197 
198 #endif /* NeXusEventCallback_H */
void allEventCallback(const DAEEventHeader *head, const DetectorEvent32 *det_ev, int n, int event_source_id, const int *mapping)
void noFrameCallbackNull(bool end_present, NoFrameCallbackMode mode, int event_source_id)
int getSpectrum(const DetectorEvent32 *det_ev, int event_source_id, int i)
returns -1 if spectrum out of range
std::map< std::string, std::vector< uint32_t > > uint_map_t
void openDataGroup(IXNeXusFile *nx, const std::string &name, bool create_zero_size_if_missing=false)
Poco::MemoryPool m_mempool
void closeDataGroup(const std::string &name)
static const int m_nexus_chunk_length
number of items in NeXus event list data chunk
void openDataGroup(const std::string &name, bool create_zero_size_if_missing=false)
float rtcb[ISISCRPT_MAX_NTRG][ISISCRPT_MAX_TIMECHANB]
Definition: isiscrpt.h:344
std::vector< float > m_frame_time
monitor events we did not save to file, instead just saving histograms
int m_is_vetoing
last period number seen, used for change period log
float_map_t m_se_float_values
fixed header marker for DAEEventHeader
Definition: dae_events.h:44
int currentWriteFrame() const
void makeDetName(int spec, std::string &det_name)
NeXusEventCallback * object
std::set< std::string > m_event_det
std::vector< float > m_frame_proton_charge
int m_good_frames
1 yes, 0 no (-1 means unknown, but just used for initialisation)
const int_map_t & event_id
static const int INVALID_FRAME_MARKER
static Poco::Mutex m_event_write_mutex
void updateCurrentWriteFrame(int frame, int event_source_id)
Poco::NotificationQueue m_queue
void allFrameCallback(const DAEEventHeader *head, int event_source_id)
this will get called for each frame for EACH event source
static Poco::Mutex m_frame_callback_mutex
int m_current_period
frame number we are currently processing
NeXusWorker(Poco::NotificationQueue &queue)
void processDataDae(const DAEEventHeader *head, const DetectorEvent32 *det_ev, int n, int event_source_id)
std::vector< int > m_frame_period
std::map< int, std::pair< int, time_t > > card_frame_t
boost::bimap< std::string, int > det_name_t
SimpleStore< int_map_t > m_int_map_store
NeXusWorkerData(NeXusEventCallback *object_, Poco::Event &ev_, const DAEEventHeader *head_, int event_source_id_, int nev_, const int_map_t &event_id_, const float_map_t &event_time_offset_)
const ISISCRPT_STRUCT * m_crpt
std::map< std::string, std::vector< IXNeXusFile * > > det_file_t
std::map< std::string, std::vector< int > > int_map_t
void writeEventsImpl(const DAEEventHeader *head, int event_source_id, int nev, const int_map_t &event_id, const float_map_t &event_time_offset)
static Poco::Condition m_event_write_cond
static float getTimeOffset(const ISISCRPT_STRUCT *crpt, const DetectorEvent32 *det_ev, int event_source_id, int tr, int i)
float getTimeOffset(const DetectorEvent32 *det_ev, int event_source_id, int tr, int i)
std::map< std::string, int > m_det_tr
const DAEEventHeader * head
boost::pool_allocator< T, boost::default_user_allocator_new_delete, boost::details::pool::default_mutex, 100000 > alloc
int dae1SpecForCard(int pos, int dae2_spec) const
if spectrum is out of range, returns -1
Definition: isiscrpt.h:684
std::map< std::string, std::map< int, int > > frame_events_write_t
frame_events_write_t m_frame_events_write
std::vector< int > m_good_frame
unsigned time_channel
Definition: dae_events.h:78
void writeEvents(const DAEEventHeader *head, int event_source_id, int nev, const int_map_t &event_id, const float_map_t &event_time_offset)
Poco::Event & ev
SimpleStore< float_map_t > m_float_map_store
virtual void doWork(NeXusWorkerData *data)
std::vector< int > m_frame_number
std::map< int, uint32_t > m_frame_events_raw
NoFrameCallbackMode
Definition: event_store.h:20
NXlogWriter< int > m_vetoing
NXlogWriter< int > m_period
int getRefEventDetCard(const std::vector< int > &ev_source_ids)
void noFrameCallbackEnd(bool end_present, NoFrameCallbackMode mode, int event_source_id)
std::vector< int > m_det_id
NeXusEventCallback(const ISISCRPT_STRUCT *crpt, IXNeXusFile *file, const std::vector< int > &ev_source_ids)
LONGLONG m_monitor_events_not_saved
events discarded as outside tcb time window
std::map< std::string, uint64_t > m_events_write_total
const float_map_t & event_time_offset
Poco::Thread m_worker_thread
void closeDataGroup(IXNeXusFile *nx, const std::string &name)
if name is null string, do nothing
std::map< std::string, std::vector< float > > float_map_t