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