StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
prepareGbPayload.h
1 #ifndef __LXGBX_H__
2 #define __LXGBX_H__
3 
4 // Emulate LXGBX in a single class
5 //
6 // To use
7 //
8 // 1. SEND_CONFIG time, call --> config()
9 // 2. for each event call --> lxgbx()
10 // 3. place an SFS file called "EventSummary"
11 // containing gbPayload first in the message to EVBX
12 // (immediately following the iccp2k header)
13 
14 #include <iccp2k.h>
15 #include <rtsSystems.h>
16 #include <RC_Config.h>
17 #include <rtsLog.h>
18 #include <time.h>
19 #include <daqFormats.h>
20 #include <daq100Decision.h>
21 #include <XMLCFG/SimpleXmlDoc.h>
22 #include <stdlib.h>
23 
24 class Lxgbx {
25  public:
26  int run_type;
27  int cl_run; // clusters for tpx
28  int raw_write; // raw write for tpx
29  UINT64 dets_in_run_mask;
30 
31  UINT64 tokenZeroTriggers;
32 
33 
34  struct evpCfg {
35  UINT32 groupdef[EVP_GROUP_MAX][2]; // [trigger group] [0 low mask, 1 highmask]
36  float rate[EVP_GROUP_MAX]; // -1 -> take every one, 0 -> take none
37  int policy;
38  } evpCfg;
39 
40  struct evpCtrs {
41  float runStartTime;
42  int cnt[EVP_GROUP_MAX];
43  } evpCtrs;
44 
45  Lxgbx() {};
46 
47  int configEvp(SimpleXmlDoc *xml, int divisor=1) {
48  // zero out counters...
49  evpCtrs.runStartTime = 0; // untill the first event!
50  memset(evpCtrs.cnt, 0, sizeof(evpCtrs.cnt));
51 
52  // do configuration
53  evpCfg.policy = xml->getParamI("trg_setup.extra.evp_policy");
54 
55  for(int i=0;i<EVP_GROUP_MAX;i++) {
56 
57  evpCfg.groupdef[i][0] = xml->getParamMask(0, "trg_setup.evpGroup[%d].definition", i);
58 
59  evpCfg.groupdef[i][1] = xml->getParamMask(1, "trg_setup.evpGroup[%d].definition", i);
60 
61  evpCfg.rate[i] = xml->getParamI("trg_setup.evpGroup[%d].rate", i);
62 
63  LOG(NOTE , "Groups[%d].rate = %f : def[0] = 0x%x def[1] = 0x%x",i,evpCfg.rate[i],evpCfg.groupdef[i][0],evpCfg.groupdef[i][1],0);
64 
65  if((evpCfg.rate[i] > 0.0) && (divisor > 1)) {
66  evpCfg.rate[i] /= (float)divisor;
67  }
68 
69  if((int)(evpCfg.rate[i]*1000) > 0) {
70  LOG(NOTE, "configEvp: rate[%d]*1000 = %d (0x%x-0x%x): divisor=%d",i,(int)(evpCfg.rate[i]*1000),evpCfg.groupdef[i][0],evpCfg.groupdef[i][1],divisor);
71  }
72  }
73 
74  return 0;
75  }
76 
77  /*
78  // divisor is for use in EVB where rate gets divided by number of evbs...
79  int configEvp(STAR_CFG *cfg, int divisor=1)
80  {
81  // zero out counters...
82  evpCtrs.runStartTime = 0; // untill the first event!
83  memset(evpCtrs.cnt, 0, sizeof(evpCtrs.cnt));
84 
85  // do configuration
86  EvpGroup *groups = cfg->trg_setup.evpGroup;
87  evpCfg.policy = cfg->trg_run.EvpPolicy;
88  for(int i=0;i<EVP_GROUP_MAX;i++) {
89 
90  evpCfg.groupdef[i][0] = groups[i].definition[0];
91  evpCfg.groupdef[i][1] = groups[i].definition[1];
92 
93  LOG(NOTE , "Groups[%d].rate = %f : def[0] = 0x%x def[1] = 0x%x",i,evpCfg.rate[i],evpCfg.groupdef[i][0],evpCfg.groupdef[i][1],0);
94 
95  evpCfg.rate[i] = groups[i].rate;
96  if((evpCfg.rate[i] > 0.0) && (divisor > 1)) {
97  evpCfg.rate[i] /= (float)divisor;
98  }
99 
100  if((int)(evpCfg.rate[i]*1000) > 0) {
101  LOG(NOTE, "configEvp: rate[%d]*1000 = %d (0x%x-0x%x): divisor=%d",i,(int)(evpCfg.rate[i]*1000),evpCfg.groupdef[i][0],evpCfg.groupdef[i][1],divisor);
102  }
103  }
104 
105  return 0;
106  }
107  */
108 
109  int config(SimpleXmlDoc *xml) {
110  int ret;
111 
112  ret = configEvp(xml);
113 
114  run_type = xml->getParamI("daq_setup.run_type");
115  cl_run = xml->getParamI("daq_setup.detectors[%d].cl_done",TPX_ID);
116  raw_write = xml->getParamI("daq_setup.detectors[%d].raw_write",TPX_ID);
117 
118  dets_in_run_mask = 0;
119 
120  for(int i=0;i<MAX_NODES;i++) {
121  int inrun = xml->getParamI("subsys_tasks.nodes[%d].inrun",i);
122 
123  if(!inrun) continue;
124 
125  UINT32 node = xml->getParamI("subsys_tasks.nodes[%d].node",i);
126 
127  LOG(DBG, "node = 0x%x", node,0,0,0,0);
128 
129  int sys = GET_SYSTEM(node);
130 
131  if(sys == DAQ_SYSTEM) continue;
132  if(sys == TRG_SYSTEM) continue;
133 
134  dets_in_run_mask |= (1ll<<sys);
135  }
136 
137  tokenZeroTriggers = 0;
138 
139  for(int i=0;i<TRIGGERS_MAX;i++) {
140  int inrun = xml->getParamI("trg_setup.triggers[%d].used", i);
141  if(!inrun) continue;
142 
143  if(xml->getParamI("trg_setup.triggers[%d].userdata.tokenZero", i)) {
144  tokenZeroTriggers |= (1ll<<i);
145  }
146  }
147 
148  LOG(NOTE, "dets_in_run_mask = 0x%llx",dets_in_run_mask,0,0,0,0);
149  return ret;
150  }
151 
152  /*
153  // Returns -1 if invalid configuration
154  int config(STAR_CFG *cfg)
155  {
156  int ret;
157 
158  ret = configEvp(cfg);
159 
160  run_type = cfg->daq_setup.run_type;
161  cl_run = cfg->daq_setup.detectors[TPX_ID].cl_done;
162  raw_write = cfg->daq_setup.detectors[TPX_ID].raw_write;
163 
164  dets_in_run_mask = 0;
165 
166  for(int i=0;i<MAX_NODES;i++) {
167  TASK *n = &cfg->subsys_tasks.nodes[i];
168  if(!n->inrun) continue;
169 
170  int sys = GET_SYSTEM(n->node);
171 
172  if(sys == DAQ_SYSTEM) continue;
173  if(sys == TRG_SYSTEM) continue;
174 
175  dets_in_run_mask |= (1<<sys);
176  }
177 
178  tokenZeroTriggers = 0;
179 
180  for(int i=0;i<TRIGGERS_MAX;i++) {
181  Trigger *t = &cfg->trg_setup.triggers[i];
182  if(t->userdata.tokenZero) {
183  tokenZeroTriggers |= (1<<i);
184  }
185  }
186 
187  return ret;
188  }
189  */
190 
191  double mygettime() {
192 #ifdef __vxworks
193  UINT32 sec = time(NULL);
194  float currtime = (float)sec;
195 #else
196  struct timeval tm;
197  gettimeofday(&tm, NULL);
198  double sec = tm.tv_sec;
199  double usec = tm.tv_usec;
200 
201  double currtime = sec + usec / 1000000.0;
202 
203  LOG(DBG, "currtime = %lf",currtime);
204 #endif
205 
206 
207  return currtime;
208  }
209 
210  UINT32 evpAssign(UINT32 trg_lo, UINT32 trg_hi)
211  {
212  static double resettime=0;
213  static long int seed = 0;
214 
215  double currtime = mygettime();
216 
217  if(seed == 0) {
218 #ifndef __vxworks
219 
220  seed = (long int)(currtime * 1e6);
221  srand48(seed);
222  LOG("JEFF", "seed48=%llx %d", seed, sizeof(seed),0,0,0);
223 #endif
224  }
225 
226  if(currtime > 15 + resettime) {
227 #ifdef __vxworks
228  resettime = currtime;
229 #else
230  resettime = currtime + drand48();
231 #endif
232  for(int i=0;i<EVP_GROUP_MAX;i++) {
233  evpCtrs.cnt[i] = 0;
234  }
235  }
236 
237  double et = currtime - resettime;
238  if(et < .01) et = .01;
239  LOG(NOTE, "currtime=%d resettime=%d et*1000=%d",(int)currtime,(int)resettime,(int)(et*1000),0,0);
240 
241  // get event group mask
242  UINT32 grpmask = 0;
243  for(int i=0;i<EVP_GROUP_MAX;i++) {
244  if((trg_lo & evpCfg.groupdef[i][0]) ||
245  (trg_hi & evpCfg.groupdef[i][1])) {
246  grpmask |= (1<<i);
247  }
248  }
249 
250  LOG(NOTE, "Event: et*1000=%d trg_lo=0x%x trg_hi=0x%x grpmask=0x%x",(int)(et*1000),trg_lo,trg_hi,grpmask,0);
251 
252  // get firemask (after rates)
253  UINT32 firemask = 0;
254  for(int i=0;i<EVP_GROUP_MAX;i++) {
255  if(!(grpmask & (1<<i))) continue;
256 
257  double r = ((double)evpCtrs.cnt[i]/et);
258  LOG(NOTE, "group[%d] rate*1000=%d",i, (int)(r * 1000),0,0,0);
259 
260  if(r < evpCfg.rate[i]) {
261  firemask |= (1<<i);
262 
263  LOG(NOTE, "EVP[%d]: r*1000=%d rate*1000=%d, cnt=%d et=%d",i,(int)(r*1000),(int)(evpCfg.rate[i]*1000),evpCtrs.cnt[i],(int)et);
264  }
265  else {
266  LOG(NOTE, "NOEVP[%d]: r*1000=%d rate*1000=%d, cnt=%d et=%d",i,(int)(r*1000),(int)(evpCfg.rate[i]*1000),evpCtrs.cnt[i],(int)et);
267  }
268 
269  if(evpCfg.rate[i] < 0) {
270  LOG(NOTE, "Set fire mask because of neg rate[%d]*1000 %d?",i,(int)(evpCfg.rate[i]*1000),0,0,0);
271  firemask |= (1<<i);
272  }
273  }
274 
275 
276  if(evpCfg.policy == 1) { // all events
277  LOG(NOTE, "Set fire mask because of take all",0,0,0,0,0);
278  firemask = 1;
279  }
280 
281  if(evpCfg.policy == 2) { // 10 hz
282  double r = ((double)evpCtrs.cnt[0]/et);
283  if(r < 10.0) {
284  LOG(NOTE, "Set fire mask because of 10hz",0,0,0,0,0);
285  firemask = 1;
286  }
287  else {
288  firemask = 0;
289  }
290  }
291 
292  for(int i=0;i<EVP_GROUP_MAX;i++) {
293  if(firemask & (1<<i)) evpCtrs.cnt[i]++;
294  }
295 
296  return firemask;
297  }
298 
299  // assume evtDescData comes in as big endian...
300  // assume other args are host endian
301  //
302  // l25abort --> 1 = l2 abort
303  // 2 = l2 timeout
304  int doEvent(gbPayload *pay, EvtDescData *evt, UINT32 l1trg_lo, UINT32 l2trg_lo, UINT32 l25abort, UINT32 token, UINT32 eventNumber, UINT32 l1trg_hi=0, UINT32 l2trg_hi=0)
305  {
306  pay->gbPayloadVersion = l2h32(GB_PAYLOAD_VERSION);
307  pay->eventNumber = l2h32(eventNumber);
308  pay->token = l2h32(token);
309 
310 
311  if(&pay->EventDescriptor == evt) {
312  LOG(NOTE, "Event descriptor is already in payload! Fine.",0,0,0,0,0);
313  }
314  else {
315  LOG(NOTE, "Event descriptor not in payload, copy it! %p %p", &pay->EventDescriptor, evt,0,0,0);
316  memcpy(&pay->EventDescriptor, evt, sizeof(EvtDescData));
317  }
318 
319  // The rest should be little endian
320  pay->L1summary[0] = l2h32(l1trg_lo);
321  pay->L1summary[1] = l2h32(l1trg_hi);
322  pay->L2summary[0] = l2h32(l2trg_lo);
323  pay->L3summary[0] = l2h32(l2trg_lo);
324  pay->L2summary[1] = l2h32(l2trg_hi);
325  pay->L3summary[1] = l2h32(l2trg_hi);
326 
327  LOG(NOTE, "l1: 0x%x/0x%x, l2: 0x%x/0x%x evtdesc->dets: 0x%x",
328  pay->L1summary[0],
329  pay->L1summary[1],
330  pay->L2summary[0],
331  pay->L2summary[1],
332  evt->actionWdDetectorBitMask);
333 
334 
335  pay->evp = l2h32(evpAssign(l2trg_lo, l2trg_hi));
336  pay->L3summary[3] = pay->evp;
337 
338 #ifdef __vxworks
339  struct timespec tm;
340  clock_gettime(CLOCK_REALTIME, &tm);
341  pay->sec = l2h32(tm.tv_sec);
342  pay->usec = l2h32(tm.tv_nsec * 1000);
343 #else
344  struct timeval tm;
345  gettimeofday(&tm, NULL);
346  pay->sec = tm.tv_sec;
347  pay->usec = tm.tv_usec;
348 #endif
349 
350  LOG(DBG, "Payload: ver=0x%x token=%d trgcmd=%d daqcmd=0x%x",
351  pay->gbPayloadVersion,
352  pay->EventDescriptor.TrgToken,
353  pay->EventDescriptor.actionWdTrgCommand,
354  pay->EventDescriptor.actionWdDaqCommand,0);
355 
356  pay->flags = daq100Decision(l2h32(pay->token), evt->actionWdDaqCommand, run_type, cl_run, raw_write);
357 
358  if(l25abort & 0x1) {
359  pay->flags |= EVBFLAG_L25ABORT;
360  }
361  if(l25abort & 0x2) {
362  pay->flags |= EVBFLAG_L25TIMEOUT;
363  }
364 
365  pay->flags = l2h32(pay->flags);
366 
367  UINT32 awdetmask = b2h16(evt->actionWdDetectorBitMask);
368  LOG(NOTE, "grp_mask = 0x%x",awdetmask,0,0,0,0);
369 
370  UINT64 detmask = grp2rts_mask(awdetmask);
371 
372 
373  LOG(NOTE, "potential det_mask = 0x%llx dets_in_run_mask 0x%llx",detmask,dets_in_run_mask,0,0,0);
374 
375  detmask &= dets_in_run_mask;
376  detmask |= (1ll<<TRG_SYSTEM);
377 
378  LOG(NOTE, "final det_mask = 0x%llx",detmask,0,0,0,0);
379 
380  pay->rtsDetMask = l2h64(detmask);
381 
382  LOG(NOTE, "super final det_mask = 0x%llx",pay->rtsDetMask,0,0,0,0);
383 
384  if(pay->flags & EVBFLAG_L25ABORT) {
385  LOG(DBG, "Sending L25Abort: token=%d event=%d 1l=0x%x l2=0x%x l2abort=%d",
386  token, eventNumber, l1trg_lo, l2trg_lo, l25abort);
387  }
388 
389 
390  LOG(DBG, "l1: 0x%x/0x%x, l2: 0x%x/0x%x",
391  pay->L1summary[0],
392  pay->L1summary[1],
393  pay->L2summary[0],
394  pay->L2summary[1],0);
395 
396  return 0;
397  }
398 
399  int prepareTokenZeroPayload(gbPayload *pay, int eventNumber)
400  {
401  memset(pay, 0, sizeof(gbPayload));
402 
403  // Set event descriptor... (in big endian)
404  EvtDescData *des = (EvtDescData *)pay->eventDesc;
405  des->TrgToken = b2h16(0);
406 
407 
408  // WRONG!
409  des->actionWdDetectorBitMask = b2h16(0);
410 
411  des->TrgDataFmtVer = FORMAT_VERSION & 0x000000ff;
412  //
413 
414  pay->gbPayloadVersion = l2h32(GB_PAYLOAD_VERSION);
415  pay->eventNumber = l2h32(eventNumber);
416  pay->token = 0;
417 
418  // The rest should be little endian
419  UINT32 tzt_lo = tokenZeroTriggers & 0xffffffff;
420  UINT32 tzt_hi = (tokenZeroTriggers >> 32) & 0xffffffff;
421 
422  pay->L1summary[0] = l2h32(tzt_lo);
423  pay->L1summary[1] = l2h32(tzt_hi);
424  pay->L2summary[0] = l2h32(tzt_lo);
425  pay->L2summary[1] = l2h32(tzt_hi);
426  pay->L3summary[0] = l2h32(tzt_lo);
427  pay->L3summary[1] = l2h32(tzt_hi);
428 
429  pay->evp = l2h32(1);
430  pay->L3summary[3] = pay->evp;
431 
432 #ifdef __vxworks
433  struct timespec tm;
434  clock_gettime(CLOCK_REALTIME, &tm);
435  pay->sec = l2h32(tm.tv_sec);
436  pay->usec = l2h32(tm.tv_nsec * 1000);
437 #else
438  struct timeval tm;
439  gettimeofday(&tm, NULL);
440  pay->sec = tm.tv_sec;
441  pay->usec = tm.tv_usec;
442 #endif
443 
444  // int detmask = grp2rts_mask(dets_in_run_mask);
445  UINT64 detmask = dets_in_run_mask | (1ll <<TRG_ID);
446  pay->rtsDetMask = l2h64(detmask);
447 
448  return 0;
449  }
450 };
451 
452 #endif