GSI Object Oriented Online Offline (Go4)  GO4-6.1.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
TGo4MbsSource.cxx
Go to the documentation of this file.
1 // $Id: TGo4MbsSource.cxx 3063 2021-03-12 15:27:09Z linev $
2 //-----------------------------------------------------------------------
3 // The GSI Online Offline Object Oriented (Go4) Project
4 // Experiment Data Processing at EE department, GSI
5 //-----------------------------------------------------------------------
6 // Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
7 // Planckstr. 1, 64291 Darmstadt, Germany
8 // Contact: http://go4.gsi.de
9 //-----------------------------------------------------------------------
10 // This software can be used under the license agreements as stated
11 // in Go4License.txt file which is part of the distribution.
12 //-----------------------------------------------------------------------
13 
14 #include "TGo4MbsSource.h"
15 
16 #include <cstdlib>
17 
18 #include "TClass.h"
19 #include "TSystem.h"
20 
21 #include "TGo4MbsEvent.h"
22 #include "TGo4MbsSourceParameter.h"
23 #include "TGo4AnalysisImp.h"
24 
25 #include "TGo4Log.h"
28 #include "TGo4EventEndException.h"
29 
30 const UInt_t TGo4MbsSource::fguLONGBYCHAR = sizeof(Int_t) / sizeof(Char_t);
31 const UInt_t TGo4MbsSource::fguSHORTBYCHAR = sizeof(Short_t) / sizeof(Char_t);
32 const UInt_t TGo4MbsSource::fguLONGBYSHORT = sizeof(Int_t) / sizeof(Short_t);
33 const UInt_t TGo4MbsSource::fguEVHEBYCHAR = sizeof(s_evhe) / sizeof(Char_t);
34 
35 Bool_t TGo4MbsSource::gbPollingMode = kFALSE;
36 
38  TGo4EventSource(par->GetName()),
39  fiMode(mode),
40  fiRetryCnt(par->GetRetryCnt()),
41  fxEvent(0), fxBuffer(0), fxInfoHeader(0),
42  fbIsOpen(kFALSE), fbDataCopyMode(kFALSE),
43  fuEventCounter(0), fbFirstEvent(kTRUE),
44  fuStartEvent(par->GetStartEvent()) ,
45  fuStopEvent(par->GetStopEvent()),
46  fuEventInterval(par->GetEventInterval()),
47  fiTimeout(par->GetTimeout()),
48  fbPollingMode(kFALSE),
49  fiPort(par->GetPort())
50 {
52  GO4TRACE((15,"TGo4MbsSource::TGo4MbsSource(const char*, Int_t)",__LINE__, __FILE__));
53  // Open() call will be done by subclasses ctors, so we can overwrite Open() method
54  //std::cout <<"TGo4MbsSource with data copy mode="<<fbDataCopyMode << std::endl;
55 }
56 
57 
58 TGo4MbsSource::TGo4MbsSource(const char* name, Int_t mode) :
59  TGo4EventSource(name),
60  fiMode(mode),
61  fiRetryCnt(0),
62  fxEvent(0), fxBuffer(0), fxInfoHeader(0),
63  fbIsOpen(kFALSE), fbDataCopyMode(kFALSE),
64  fuEventCounter(0), fbFirstEvent(kTRUE),
65  fuStartEvent(0) ,fuStopEvent(0), fuEventInterval(0),
66  fiTimeout(-1), fbPollingMode(kFALSE), fiPort(0)
67 {
69  GO4TRACE((15,"TGo4MbsSource::TGo4MbsSource(const char*, Int_t)",__LINE__, __FILE__));
70 
72 
73  // Open() call will be done by subclasses ctors, so we can overwrite Open() method
74  //std::cout <<"TGo4MbsSource with data copy mode="<<fbDataCopyMode << std::endl;
75 }
76 
77 
79  TGo4EventSource("default mbs source"),
80  fiMode(0),
81  fiRetryCnt(0),
82  fxEvent(0), fxBuffer(0), fxInfoHeader(0),
83  fbIsOpen(kFALSE), fbDataCopyMode(kFALSE),
84  fuEventCounter(0), fbFirstEvent(kTRUE),
85  fuStartEvent(0) ,fuStopEvent(0), fuEventInterval(0),
86  fiTimeout(-1), fbPollingMode(kFALSE), fiPort(0)
87 {
89  GO4TRACE((15,"TGo4MbsSource::TGo4MbsSource()",__LINE__, __FILE__));
90 }
91 
93 {
94  GO4TRACE((15,"TGo4MbsSource::~TGo4MbsSource()",__LINE__, __FILE__));
95  Close();
97 }
98 
100 {
101  gbPollingMode = on;
102 }
103 
104 void TGo4MbsSource::SetPrintEvent(Int_t num, Int_t sid, Int_t longw, Int_t hexw, Int_t dataw)
105 {
106  fxPrEventPar.fiNum = num;
107  fxPrEventPar.fiSid = sid;
108  fxPrEventPar.fiLong = longw;
109  fxPrEventPar.fiHex = hexw;
110  fxPrEventPar.fiData = dataw;
111 }
112 
114 {
115  return cl->InheritsFrom(TGo4MbsEvent::Class());
116 }
117 
119 {
120  Int_t rev = NextEvent();
121  if(rev != GETEVT__SUCCESS) {
122  TGo4Log::Debug(" Mbs Event -- !!! NextEvent() error: %s !!! ", GetErrMess());
123  return kFALSE;
124  }
125 
126  BuildMbsEvent((TGo4MbsEvent*) dest);
127  return kTRUE;
128 }
129 
130 
132 {
133  GO4TRACE((12,"TGo4MbsSource::BuildMbsEvent(TGo4MbsEvent*)",__LINE__, __FILE__));
134  TGo4MbsSubEvent* subtarget=0;
135  if(fxEvent!=0 && GetEventStatus()==GETEVT__SUCCESS) {
136  // check for printevent mode here:
137  if(fxPrEventPar.fiNum>0) {
139  (s_evhe *) fxEvent,
144  std::cout << std::endl; // flush std::cout buffer
146  }
147  // we have a valid event, proceed
148  Char_t* endofevent = (Char_t*) (fxEvent) +
150  //std::cout << "end of event "<< endofevent << std::endl;
151  target->SetValid(kTRUE); // reset target if previously was set to false
152  target->SetDlen(fxEvent->l_dlen);
153  target->SetType(fxEvent->i_type);
154  target->SetSubtype(fxEvent->i_subtype);
155 
156 
157  //**************************************************************************
158  //**************************************************************************
159  // Event Type 10:
160  if(fxEvent->i_type==10) {
161  s_ves10_1* subevent; // pointer to subevent
162  Char_t* subevtpointer; // dito, in bytes
163  target->SetTrigger(fxEvent->i_trigger);
164  target->SetCount(fxEvent->l_count);
165  target->SetDummy(fxEvent->i_dummy);
166  Int_t totalsubdatalength=0; // check counter for total datalength of subevents
167  if(fxEvent->l_dlen > 4) {
168  // we have subevent data after the event header, proceed:
169  subevent = (s_ves10_1*) (fxEvent + 1);
170  // first subevent header starts after event header
171  // loop over subevents:
172  Int_t datalength = 0; // direct dlen from subevent header (in Short_t!)
173  // Int_t fieldlength=0; // actual size of the target Int_t data field
174  while((datalength = subevent->l_dlen) >0 ) {
175  totalsubdatalength+=datalength-2+sizeof(s_ves10_1)/sizeof(Short_t);
176  if(datalength>fxEvent->l_dlen) {
177  TGo4Log::Debug(" !!! MbsSource -- SUBEVENTS LENGTH mismatch!!! skipping event #%d",fxEvent->l_count);
178  TGo4Log::Debug("\t sub dlen:%d, event dlen:%d ",datalength-2, fxEvent->l_dlen-4);
179  target->SetValid(kFALSE);
180  break;
181  }
182  Int_t * subeventid= (Int_t *) (subevent) + 2; // full id starts 2 ints after subevent head anyway
183  //Int_t* subeventid= (Int_t*) &(subevent->i_procid); // full id is lw from control, subcrate, procid fields - some compilers complain here!
184  Short_t* data = (Short_t*) (subevent+1); // data starts after subevent header
185  subtarget = target->AddSubEvent(*subeventid, data, datalength, fbDataCopyMode); // find subevent that matches id and fill it
186  subtarget->SetType(subevent->i_type); // need to set ids manually afterwards
187  subtarget->SetSubtype(subevent->i_subtype);
188  subevtpointer = (Char_t*) (subevent) +
189  datalength * fguSHORTBYCHAR + fguEVHEBYCHAR;
190  subevent = (s_ves10_1*) subevtpointer;
191  if ((Char_t*) subevent >= endofevent) {
192  //std::cout << "found end of event, breaking.."<< std::endl;
193  break;
194  }
195  } // while((datalength=subevent->l_dlen) >0)
196  if(totalsubdatalength!=fxEvent->l_dlen-4) {
197  TGo4Log::Debug(" !!! MbsSource -- SUBEVENTS TOTAL LENGTH mismatch!!! disabling event #%d",fxEvent->l_count);
198  TGo4Log::Debug("\t subdlen sum:%d, event dlen:%d ",totalsubdatalength, fxEvent->l_dlen-4);
199  target->SetValid(kFALSE);
200  }
201  } else { // if(fxEvent->dlen>4)
202  // sorry, no subevents after event header
203  TGo4Log::Debug(" !!! MbsSource -- NO SUBEVENTS!!! ");
204  SetErrMess("!!! BuildMbsEvent: -- NO SUBEVENTS!!!");
205  throw TGo4EventTimeoutException(this); // no subevts=timeout
206  } // end if (fxEvent->dlen>0)
207  } else
208  //**************************************************************************
209  //**************************************************************************
210  // Event Type 4:
211  if(fxEvent->i_type==4) {
212  // std::cout <<"found event type 4" << std::endl;
213  s_evhe* eventfourone= (s_evhe*) fxEvent; // points to event 4 1 start
214  // copy pseudo event header information to our target:
215  target->SetTrigger(4);
216  target->SetCount(1);
217  target->SetDummy(0);
218  if(fxEvent->l_dlen > 0) {
219  Int_t subeventid= 4; // arbitrarily defined here for type 4,1
220  Short_t* data = (Short_t*) (eventfourone+1); // data starts after subevent header
221  Int_t datalength=eventfourone->l_dlen+2; // length of later subevent header (in Short_t!)
222  // add 2 to direct dlen from 4,1 event header to account subevent header
223  subtarget = target->AddSubEvent(subeventid, data, datalength, fbDataCopyMode); // find subevent that matches id and fill it
224  subtarget->SetType(4);
225  subtarget->SetSubtype(1);
226  } else { // if(fxEvent->dlen>0)
227  // sorry, no subevents after event header
228  TGo4Log::Debug(" !!! MbsSource -- NO Data in event 4,1!!! ");
229  SetErrMess("!!! BuildMbsEvent: -- NO Data in event 4,1!!!");
230  throw TGo4EventTimeoutException(this); // no data=timeout
231  } // end if (fxEvent->dlen>0)
232  } else {
233  TGo4Log::Debug(" !!! Mbs Source -- ERROR: Unknown event type %d !!! ",fxEvent->i_type);
234  throw TGo4EventErrorException(this);
235  } //if(fxEvent->i_type==...)
236 
237  } else {
238  // somethings wrong, display error message from f_evt_error()
239  TGo4Log::Debug(" !!! Mbs Source -- ERROR: %s !!! ",GetErrMess());
240  throw TGo4EventErrorException(this);
241  } //if(fxEvent!=0 && GetEventStatus()==GETEVT__SUCCESS)
242 }
243 
244 
245 TGo4MbsSubEvent* TGo4MbsSource::BuildMbsSubEvent(TGo4MbsEvent * target, Int_t fullID, Short_t* source, Int_t datalength)
246 {
247  // code moved into TGo4MbsEvent class, method kept for compatibility
248 
249  return target->AddSubEvent(fullID, source, datalength, fbDataCopyMode);
250 }
251 
253 {
256 }
257 
259 {
260 
261 frombegin:
262 
263  GO4TRACE((12,"TGo4MbsSource::NextEvent()",__LINE__, __FILE__));
264  // skip and sample mode introduced without changed gsievt functions for first tests
265  ULong_t eventstep;
266 
267  if (fbFirstEvent) {
268  fbFirstEvent = kFALSE;
269  eventstep = fuStartEvent + 1;
270  TGo4Log::Info("MBS source:: First event = %lu step = %lu\n", fuStartEvent, fuEventInterval);
271 
272  } else
273  if(fuEventInterval > 0)
274  eventstep = fuEventInterval;
275  else
276  eventstep = 1;
277 
278  // test if we had reached the last event:
281  else {
282  // check possible overflow of our counter:
283  if(fuEventCounter+eventstep<fuEventCounter)
284  {
285  TGo4Log::Warn("TGo4MbsSource::NextEvent(): Overflow of eventcounter at %d, reset to 0",fuEventCounter),
286  fuEventCounter=0;
287  }
288 
289  while (eventstep > 0) {
290  // retrieve the event, skip all events until end of the step
291  Int_t status = f_evt_get_event(fxInputChannel,
292  (Int_t **) (void*) &fxEvent,
293  (Int_t **) (void*) &fxBuffer);
294 
295  if (fbPollingMode && (status == GETEVT__TIMEOUT))
297 
298  SetEventStatus(status);
299  if(status!=0) break;
300  eventstep--;
301  fuEventCounter++;
302  }
303  }
304 
305  if(GetEventStatus()!=0) {
306  char buffer[TGo4EventSource::fguTXTLEN];
307  f_evt_error(GetEventStatus(),buffer,1); // provide text message for later output
308  SetErrMess(Form("%s name:%s", buffer, GetName()));
309  }
310 
311  switch(GetEventStatus()) {
312  case 0:
313  return 0;
314  case GETEVT__TIMEOUT:
315  throw TGo4EventTimeoutException(this);
316  break;
317  case GETEVT__NOMORE:
318  throw TGo4EventEndException(this);
319  break;
320  default: {
322 
323  printf("Error code %d mess %s\n", GetEventStatus(), GetErrMess());
324 
325  Close();
326  Int_t cnt = fiRetryCnt;
327 
328  while (cnt-->0) {
329  gSystem->Sleep(1000);
330 
331  //if (TGo4Analysis::Instance())
332  // if (TGo4Analysis::Instance()->IsStopWorking()) return GetEventStatus();
333  try {
334  Open();
335  if (fbIsOpen) {
336  printf("Retry %d successful\n", cnt);
337  fflush(stdout);
338  goto frombegin;
339  }
340  } catch (TGo4EventErrorException &) {
341  }
342  printf("Retry %d failed\n", cnt);
343  fflush(stdout);
344  }
345  }
346 
347  throw TGo4EventErrorException(this);
348  break;
349  }
350  }
351 
352  TGo4Log::Error("MbsSource::NextEvent -- NEVER COME HERE");
353  return GetEventStatus();
354 }
355 
357 {
358  GO4TRACE((12,"TGo4MbsSource::Open()",__LINE__, __FILE__));
359 
360  if(fbIsOpen) return -1;
361  //std::cout << "Open of TGo4MbsSource"<< std::endl;
362  // open connection/file
363 
364  char name[5000];
365  strncpy(name, GetName(), sizeof(name) - 1);
366  int nport = fiPort;
367 
368  char* separ = strrchr(name, ':');
369  if ((nport<=0) && (separ!=0) && (GetMode() != GETEVT__FILE)) {
370  if ((sscanf(separ+1,"%d",&nport)==1) && (nport>0)) {
371  *separ = 0;
372  } else {
373  nport = fiPort;
374  }
375  }
376 
377  Int_t status = f_evt_source_port(nport);
378  SetCreateStatus(status);
380  char buffer[TGo4EventSource::fguTXTLEN];
381  f_evt_error(GetCreateStatus(), buffer, 1); // provide text message for later output
382  SetErrMess(Form("%s name:%s port:%d", buffer, name, nport));
383  throw TGo4EventErrorException(this);
384  }
385 
386  fbPollingMode = gbPollingMode && ((fiMode==GETEVT__STREAM) || (fiMode==GETEVT__TRANS) || (fiMode==GETEVT__REVSERV) || (fiMode==GETEVT__EVENT));
387  f_evt_timeout(fxInputChannel, fiTimeout); // have to set timeout before open now JAM
388 
389  status = f_evt_get_open(
390  fiMode,
391  name,
393  (Char_t**) ((void*) &fxInfoHeader), // suppress type-punned pointer warning
394  0,
395  0);
396  SetCreateStatus(status);
398  char buffer[TGo4EventSource::fguTXTLEN];
399  f_evt_error(GetCreateStatus(),buffer,1); // provide text message for later output
400  SetErrMess(Form("%s name:%s", buffer, GetName()));
401  fbIsOpen = kFALSE;
402  throw TGo4EventErrorException(this);
403  } else {
404  TGo4Log::Debug(" Mbs Source -- opened input from type %d: %s . Timeout=%d s",
405  fiMode, GetName(), fiTimeout);
406  fbIsOpen = kTRUE;
407 
408  // only remote event server implement internally polling, stream server makes return timeout itself
409  if (fbPollingMode && (fiMode==GETEVT__REVSERV))
411  }
412  return status;
413 }
414 
416 {
417  GO4TRACE((12,"TGo4MbsSource::Close()",__LINE__, __FILE__));
418  if(!fbIsOpen) return -1;
419  //std::cout << "Close of TGo4MbsSource"<< std::endl;
420  Int_t rev = GetCreateStatus();
421  // close connection/file
422  if(rev == GETEVT__SUCCESS) {
424  fbIsOpen=kFALSE;
425  }
426 
427  return rev;
428 }
429 
431 {
433 }
#define GETEVT__SUCCESS
Definition: f_evt.h:131
void SetCount(Int_t count)
Definition: TGo4MbsEvent.h:151
TGo4MbsSubEvent * AddSubEvent(Int_t fullID, Short_t *source, Int_t datalength, Bool_t copydata=kFALSE)
INTS4 f_evt_type(s_bufhe *ps_bufhe, s_evhe *ps_evhe, INTS4 l_subid, INTS4 l_long, INTS4 l_hex, INTS4 l_data)
Definition: f_evt.c:298
s_evt_channel * fxInputChannel
INTS4 f_evt_get_close(s_evt_channel *ps_chan)
Definition: f_evt.c:1101
#define GETEVT__TIMEOUT
Definition: f_evt.h:140
static Bool_t gbPollingMode
void SetValid(Bool_t on)
INTS4 f_evt_get_open(INTS4 l_mode, CHARS *pc_server, s_evt_channel *ps_chan, CHARS **ps_info, INTS4 l_sample, INTS4 l_param)
Definition: f_evt.c:552
INTS4 f_evt_timeout(s_evt_channel *ps_chan, INTS4 l_sec)
Definition: f_evt.c:1833
s_filhe * fxInfoHeader
void SetCreateStatus(Int_t status)
Definition: s_evhe.h:32
const char * GetErrMess() const
s_evt_channel * f_evt_control()
Definition: f_evt.c:2816
INTS2 i_type
Definition: s_ve10_1.h:38
static void Warn(const char *text,...)
Definition: TGo4Log.cxx:300
Bool_t fbPollingMode
Bool_t fbDataCopyMode
virtual Bool_t CheckEventClass(TClass *cl)
INTS4 f_evt_source_port(INTS4 l_port)
Definition: f_evt.c:486
INTS4 f_evt_error(INTS4 l_error, CHARS *pc_dest, INTS4 l_out)
Definition: f_evt.c:1586
#define GETEVT__EVENT
Definition: f_evt.h:123
#define GETEVT__NOMORE
Definition: f_evt.h:134
CHARS * f_evt_get_buffer_ptr(s_evt_channel *ps_chan)
Definition: f_evt.c:1928
virtual ~TGo4MbsSource()
ULong_t fuEventCounter
ULong_t fuEventInterval
INTS4 l_dlen
Definition: s_ve10_1.h:37
virtual Int_t NextEvent()
#define GETEVT__TRANS
Definition: f_evt.h:122
INTS4 l_dlen
Definition: s_ves10_1.h:37
void BuildMbsEvent(TGo4MbsEvent *target)
void SetErrMess(const char *txt)
Int_t GetMode() const
number of allowed reconnect retries
void SetTimeout(Int_t time)
INTS2 i_dummy
Definition: s_ve10_1.h:40
void SetSubtype(Short_t subtype)
Definition: TGo4MbsEvent.h:142
Int_t GetCreateStatus() const
void SetDummy(Short_t dummy)
Definition: TGo4MbsEvent.h:145
void SetDlen(Int_t dlen)
Definition: TGo4MbsEvent.h:134
static void SetPollingMode(Bool_t on=kTRUE)
s_bufhe * fxBuffer
static const UInt_t fguLONGBYCHAR
void SetType(Short_t type)
Definition: TGo4MbsEvent.h:139
#define GETEVT__REVSERV
Definition: f_evt.h:124
INTS2 i_trigger
Definition: s_ve10_1.h:41
static const UInt_t fguSHORTBYCHAR
virtual Int_t Close()
s_ve10_1 * fxEvent
static const UInt_t fguEVHEBYCHAR
static const Int_t fgiTIMEOUTDEFAULT
void SetType(Short_t type)
Int_t GetEventStatus() const
Bool_t fbFirstEvent
void SetEventStatus(Int_t status)
#define GO4TRACE(X)
Definition: TGo4Log.h:26
void HandleAnlysisEvents()
INTS4 l_dlen
Definition: s_evhe.h:34
virtual Int_t Open()
INTS2 i_type
Definition: s_ves10_1.h:38
ULong_t fuStartEvent
void SetPrintEvent(Int_t num=1, Int_t sid=-1, Int_t longw=1, Int_t hexw=1, Int_t dataw=0)
INTS2 i_subtype
Definition: s_ve10_1.h:39
virtual Bool_t BuildEvent(TGo4EventElement *dest)
void(* cb_polling)()
Definition: f_evt.h:90
ULong_t fuStopEvent
virtual s_bufhe * GetBufferHeader()
static TGo4Analysis * Instance()
INTS4 f_evt_get_event(s_evt_channel *ps_chan, INTS4 **ppl_buffer, INTS4 **ppl_goobuf)
Definition: f_evt.c:909
TGo4MbsSubEvent * BuildMbsSubEvent(TGo4MbsEvent *target, Int_t fullID, Short_t *source, Int_t datalength)
void SetSubtype(Short_t subtype)
#define GETEVT__FILE
Definition: f_evt.h:120
static void Error(const char *text,...)
Definition: TGo4Log.cxx:313
TGo4MbsSourcePrintPar fxPrEventPar
static void Info(const char *text,...)
Definition: TGo4Log.cxx:287
INTS2 i_subtype
Definition: s_ves10_1.h:39
#define GETEVT__STREAM
Definition: f_evt.h:121
static const UInt_t fguLONGBYSHORT
INTS4 l_count
Definition: s_ve10_1.h:42
void SetTrigger(Short_t trigger)
Definition: TGo4MbsEvent.h:148
static void Debug(const char *text,...)
Definition: TGo4Log.cxx:274
Int_t fiPort
if true, use short timeout to keep gSystem->ProcessEvents() running