StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
daq_det.cxx
1 #include <assert.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <arpa/inet.h> // for htonl
5 #include <dlfcn.h> // shared lib support
6 #include <errno.h>
7 
8 #include <rtsLog.h>
9 #include <rts.h>
10 #include <rtsSystems.h>
11 #include <daqFormats.h>
12 
13 #include <SFS/sfs_index.h>
14 
15 #include "daqReader.h"
16 #include "daq_det.h"
17 #include "daq_dta.h"
18 
19 
20 //static
21 daq_det_factory *daq_det_factory::pseudo_factories[48] ;
22 daq_det_factory *daq_det_factory::det_factories[48] ;
23 
24 
25 //static
26 daq_det *daq_det_factory::make_det(int wh)
27 {
28  daq_det_factory *use_factory = 0 ;
29  char libname[64] ;
30 
31  libname[0] = 0 ; // cautious...
32 
33  if(wh < 0) { // super-special rare pseudo det cases; deal by hand...
34  switch(wh) {
35  case -BTOW_ID :
36  sprintf(libname,"libdaq_emc.so") ;
37  break ;
38  case -L3_ID :
39  sprintf(libname,"libdaqhlt.so") ;
40  break ;
41  case -SVT_ID : //itpc_pseud
42  sprintf(libname,"libitpc.so") ;
43  break ;
44 // case -L4_ID:
45 // sprintf(libname,"libdaql4.so");
46 // break;
47  }
48  }
49  else {
50  sprintf(libname,"libdaq_%s.so",rts2name(wh)) ;
51  }
52 
53  // dets are in uppercase, turn all to lowercase...
54  for(u_int i=0;i<strlen(libname);i++) {
55  libname[i] = tolower(libname[i]) ;
56  }
57 
58  LOG(NOTE,"factory for det %d, lib %s",wh,libname) ;
59 
60  if(wh < 0) { // is this a pseudo det?
61  wh = -wh ; // reverse sign!
62  use_factory = pseudo_factories[wh] ;
63  }
64  else { // normal det
65  use_factory = det_factories[wh] ;
66  }
67 
68  //LOG(TERR,"make_det: %d %p",wh,use_factory) ;
69 
70  if(use_factory == 0) { // not inserted? need shared lib load...
71 #if 0 // this was never completed...
72 #ifdef __ROOT__
73  gSomething->Loadsomething(libname) ;
74 #else
75  // shared lib load not done yet, let it fail...
76  #if 0
77  errno = 0 ;
78  void *handle = dlopen("../DAQ_SC/libdaq_sc.so", RTLD_LAZY | RTLD_GLOBAL) ;
79  if(handle == 0) {
80  LOG(ERR,"dlopen failed for %s [%s]",libname,dlerror()) ;
81  }
82  else {
83  LOG(NOTE,"dlopen OK for det %d, lib %s",wh,libname) ;
84  }
85  #endif
86 #endif
87 #endif
88  }
89 
90  if(use_factory == 0) { // still nothing???
91  LOG(ERR,"Can't load or find detector %d,libname %s",wh,libname) ;
92  }
93 
94  assert(use_factory) ; // what else...
95 
96  LOG(NOTE,"factory for %d: calling create",wh) ;
97 
98  return use_factory->create() ;
99 }
100 
101 
102 int daq_det::endianess = 0 ; // the executing machine is little endian (0)
103 
104 
105 daq_det::daq_det(daqReader *rts_caller)
106 {
107  name = sfs_name = "(generic)" ;
108  rts_id = -1 ; // this should be correctly overriden in the member
109  caller = rts_caller ;
110  present = 0 ;
111 
112  SetMode(0) ;
113  m_Debug = 0 ;
114 
115  def_sector = def_rdo = -1 ; // assume ALL sectors and RDOs..
116 
117  in_buffer = 0 ;
118  out_buffer = 0 ;
119  in_bytes = 0 ;
120  out_bytes = 0 ;
121 
122  if(htonl(0x12345678) != 0x12345678) {
123  endianess = 0 ; // little ;
124  }
125  else {
126  endianess = 1 ; // big
127  }
128 
129 
130  LOG(DBG,"daq_det: %s [%d], caller %p: endianess %c",name,rts_id,caller,endianess?'B':'L') ;
131 
132  return ;
133 }
134 
135 
136 daq_det::~daq_det()
137 {
138  LOG(DBG,"~daq_det: %s [%d]",name,rts_id) ;
139 
140 #ifndef PP_MVME
141  if(caller) {
142  LOG(DBG,"Before de_insert(%d)",rts_id) ;
143  caller->de_insert(rts_id) ;
144  LOG(DBG,"After de_insert(%d)",rts_id) ;
145  }
146 #endif
147  return ;
148 }
149 
150 
151 unsigned int daq_det::get_global_event_num()
152 {
153  if(caller) return caller->seq ;
154 
155  return 0 ; // unknown...
156 };
157 
158 void daq_det::managed_by(class daqReader *c)
159 {
160  caller = c ;
161 
162  assert(caller) ;
163 #ifndef PP_MVME
164  caller->insert(this, rts_id) ;
165 #endif
166 }
167 
168 int daq_det::Make()
169 {
170  present = 0 ; // assume not...
171 
172 
173  if(presence()) { // this is SFS presence...
174  present |= DET_PRESENT_SFS ; // in sfs: 1
175  LOG(NOTE,"%s(SFS %s): present via SFS",name,sfs_name) ;
176  }
177  else if(legacyDetp(rts_id, caller->mem)) {
178  present |= DET_PRESENT_DATAP ; // in datap: 2
179  LOG(NOTE,"%s(SFS %s): present via DATAP",name,sfs_name) ;
180  }
181 
182  if(present) {
183  evt_num++ ; // nah, this is not really event number but let it stay...
184  }
185  else {
186  LOG(DBG, "%s: not found",name) ;
187  }
188 
189  return present ;
190 }
191 
192 int daq_det::Init()
193 {
194  present = 0 ;
195  evt_num = 0 ;
196  run_num = 0 ;
197 
198  LOG(DBG,"Init: %s[%d], sfs_name %s",name,rts_id,sfs_name) ;
199 
200  return 0 ;
201 }
202 
203 int daq_det::InitRun(int run_number)
204 {
205  run_num = run_number ;
206  evt_num = 0 ;
207  present = 0 ;
208 
209  LOG(DBG,"InitRun: %s [%d]: run %09u",name,rts_id,run_number) ;
210 
211  return 0 ;
212 }
213 
214 int daq_det::FinishRun(int old_run_number)
215 {
216 
217  LOG(DBG,"FinishRun: %s [%d]: run %09u",name,rts_id,old_run_number) ;
218 
219  return 0 ;
220 }
221 
222 void daq_det::help() const
223 {
224  printf("***************** %s: %s ******************\n",name,GetCVS()) ;
225 
226 }
227 
228 /*
229  This checks SFS presence!
230 */
231 int daq_det::presence()
232 {
233 
234  int pres = 0 ;
235 
236  if(caller==0) { // in case we are running online, there is no "caller" so assume presence!
237  LOG(NOTE,"no caller? %s",name) ;
238  pres = 1 ;
239  goto ret_here;
240  }
241 
242 #ifdef PP_MVME
243  pres = 1 ;
244  goto ret_here ;
245 #else
246  if(caller->sfs == 0) goto ret_here ; // no sfs?
247 
248  if(caller->sfs->opendirent((char *)sfs_name)) { // gotcha!
249  pres = 1 ;
250  }
251  else {
252  pres = 0 ;
253  }
254 #endif
255  ret_here: ;
256 
257  LOG(DBG,"sfs presence(%s): %d",sfs_name,pres) ;
258 
259  return pres ;
260 
261 } ;
262 
263 
264 
265 int daq_det::get_token(char *addr, int words)
266 {
267  daq_trg_word trgs[128] ;
268 
269  int ret = get_l2(addr, words, trgs, 1) ;
270  if(ret == 0) {
271  LOG(ERR,"No triggers?") ;
272  return -1000 ;
273  }
274 
275 
276  if(trgs[0].t==0) {
277  LOG(ERR,"Token 0 not allowed but I will try to use the other triggers...") ;
278  trgs[0].t = 4097 ;
279  }
280 
281 
282  return trgs[0].t ;
283 
284 }
285 
286 
287 int daq_det::get_l2(char *buff, int buff_bytes, daq_trg_word *trg, int prompt)
288 {
289 
290  LOG(ERR,"%s: get_l2() not written!",name) ;
291  return 0 ;
292 }
293 
294 int daq_det::bad_sanity()
295 {
296  return 0 ;
297 }
298 
299 daq_dta *daq_det::get(const char *bank,int c1, int c2, int c3, void *p1, void *p2)
300 {
301  LOG(ERR,"%s [%d]: get() not written!",name,rts_id) ;
302 
303  return 0 ;
304 }
305 
306 
307 daq_dta *daq_det::put(const char *bank,int c1, int c2, int c3, void *p1, void *p2)
308 {
309  LOG(ERR,"%s: put() not written!",name) ;
310 
311  return 0 ;
312 }
313 
314 
315 
316 // helpers
317 int checkBank(const char *in, const char *expect)
318 {
319  char buff[12] ;
320 
321  memcpy(buff,in,8) ;
322  buff[9] = 0 ;
323 
324  /* SPECIAL HACK for i.e. 2000 DATA
325  In 2000 the DATAP bank was "DATAP" and not the usual "DATAP "
326 
327 
328  */
329  if(strcmp(buff,"DATAP")==0) {
330  memcpy(buff,CHAR_DATAP,8) ;
331  }
332 
333  if(memcmp(buff,expect,strlen(expect))) {
334  LOG(ERR,"Read \"%s\", expect \"%s\"",buff,expect) ;
335  return -1 ;
336  }
337  else {
338  LOG(DBG,"Found \"%s\", as expected...",expect) ;
339  }
340 
341  return 0 ;
342 }
343 
344 /*
345  Returns pointer to the DETP banks using
346  legacy DATAP/DATAPX banks...
347 */
348 int *legacyDetp(int rts_id, char *m)
349 {
350  struct DATAP *datap = (struct DATAP *)m ; // assume we are pointed to DATAP
351  struct DATAPX *datapx ;
352  int *ret_p ;
353 
354  int len, off ;
355  int id ;
356 
357 
358  if(datap == 0) {
359  LOG(DBG,"No DATAP: I would need it for %s [%d]",rts2name(rts_id),rts_id) ;
360  return 0 ;
361  }
362 
363  int swapdatap = 0 ;
364  int swapdatapx = 0 ;
365 
366 
367  LOG(DBG,"Checking for %s",rts2name(rts_id)) ;
368 
369  // verify bank
370  if(checkBank(datap->bh.bank_type, CHAR_DATAP) < 0) {
371  return 0 ;
372  }
373 
374  LOG(DBG,"Here...") ;
375  // set order
376  if(datap->bh.byte_order != DAQ_RAW_FORMAT_ORDER) swapdatap = 1;
377 
378  for(int i=0;i<10;i++) {
379  if(datap->det[i].len) {
380  LOG(DBG,"Found DATAP ix %d: [%s]",i,rts2name(i)) ;
381  }
382  }
383 
384  // ugly special cases which need override...
385  switch(rts_id) {
386  case BSMD_ID :
387  id = BTOW_ID ;
388  break ;
389  case ESMD_ID :
390  id = ETOW_ID ;
391  break ;
392  default :
393  id = rts_id ;
394  break ;
395  }
396 
397  ret_p = 0 ; // assume not found...
398 
399  // navigate to DETP
400  if(id < 10) { // DATAP
401  len = qswap32(swapdatap, datap->det[id].len) ;
402  off = qswap32(swapdatap, datap->det[id].off) ;
403 
404  LOG(DBG, "Checking for datap: len=%d off=%d",len,off);
405 
406  if((len == 0) || (off == 0)) {
407  return 0 ;
408  }
409 
410  // navigate to DETP
411  LOG(DBG,"%s [%d] found in this event",rts2name(rts_id),rts_id) ;
412  ret_p = ((int *)datap + off) ;
413  }
414  else { // DATAPX
415 
416  len = qswap32(swapdatap, datap->det[EXT_ID].len) ;
417  off = qswap32(swapdatap, datap->det[EXT_ID].off) ;
418 
419  LOG(DBG, "Checking for datapx: len=%d off=%d",len,off);
420 
421  if((len == 0) || (off == 0)) {
422  return 0 ;
423  }
424 
425  // navigate to datapx
426  datapx = (struct DATAPX *)((int *)datap + off) ;
427 
428  // verify bank
429  if(checkBank(datapx->bh.bank_type, CHAR_DATAPX) < 0) {
430  return 0 ;
431  }
432 
433  if(datapx->bh.byte_order != DAQ_RAW_FORMAT_ORDER) swapdatapx = 1;
434 
435  for(int i=0;i<22;i++) {
436  if(datapx->det[i].len) {
437  LOG(DBG,"Found DATAPX ix %d: ID %d [%s]",i,i+10,rts2name(i+10)) ;
438  }
439  }
440 
441 
442  len = qswap32(swapdatapx, datapx->det[id-10].len) ;
443  off = qswap32(swapdatapx, datapx->det[id-10].off) ;
444 
445 
446  if((len == 0) || (off == 0)) {
447  return 0 ;
448  }
449 
450  // navigate to DETP
451  LOG(DBG,"%s [%d] found in this event",rts2name(rts_id),rts_id) ;
452  ret_p = ((int *)datapx + off) ;
453 
454  }
455 
456 
457  if(ret_p == 0) return 0 ;
458 
459  // special case for EMCs: we need to discern the SMDs....
460  EMCP *emcp = (EMCP *) ret_p ;
461 
462 
463  switch(rts_id) {
464  case BTOW_ID :
465  case ETOW_ID :
466  LOG(DBG,"[BE]TOW: %p: %d, %d",emcp,emcp->sec[0].len, emcp->sec[1].len) ;
467  if(emcp->sec[0].len) ; // do nothing...
468  else ret_p = 0 ; // however, it is still possible that they are in trigger's bank
469  break ;
470  case BSMD_ID :
471  case ESMD_ID :
472  LOG(DBG,"[BE]SMD: %p: %d, %d",emcp,emcp->sec[0].len, emcp->sec[1].len) ;
473  if(emcp->sec[1].len) ; // do nothing ...
474  else ret_p = 0 ;
475  break ;
476  }
477 
478  if(ret_p) LOG(DBG,"%s [%d] found in this event",rts2name(rts_id),rts_id) ;
479 
480  return ret_p ;
481 }
482