Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

TGo4MbsSource.cxx

Go to the documentation of this file.
00001 //-------------------------------------------------------------
00002 //        Go4 Release Package v3.04-01 (build 30401)
00003 //                      28-November-2008
00004 //---------------------------------------------------------------
00005 //   The GSI Online Offline Object Oriented (Go4) Project
00006 //   Experiment Data Processing at EE department, GSI
00007 //---------------------------------------------------------------
00008 //
00009 //Copyright (C) 2000- Gesellschaft f. Schwerionenforschung, GSI
00010 //                    Planckstr. 1, 64291 Darmstadt, Germany
00011 //Contact:            http://go4.gsi.de
00012 //----------------------------------------------------------------
00013 //This software can be used under the license agreements as stated
00014 //in Go4License.txt file which is part of the distribution.
00015 //----------------------------------------------------------------
00016 #include "TGo4MbsSource.h"
00017 
00018 #include "Riostream.h"
00019 #include <stdlib.h>
00020 #include "TObjArray.h"
00021 
00022 #include "TGo4MbsEvent.h"
00023 #include "TGo4MbsSubEvent.h"
00024 
00025 #include "TGo4Log.h"
00026 #include "TGo4EventErrorException.h"
00027 #include "TGo4EventTimeoutException.h"
00028 #include "TGo4EventEndException.h"
00029 
00030 const UInt_t TGo4MbsSource::fguLONGBYCHAR  = sizeof(Int_t) / sizeof(Char_t);
00031 const UInt_t TGo4MbsSource::fguSHORTBYCHAR = sizeof(Short_t) / sizeof(Char_t);
00032 const UInt_t TGo4MbsSource::fguLONGBYSHORT = sizeof(Int_t) / sizeof(Short_t);
00033 const UInt_t TGo4MbsSource::fguEVHEBYCHAR  = sizeof(s_evhe) /  sizeof(Char_t);
00034 
00035 TGo4MbsSource::TGo4MbsSource(const char* name, Int_t mode)
00036 : TGo4EventSource(name), fiMode(mode),
00037    fxEvent(0), fxBuffer(0), fxInfoHeader(0),
00038    fbIsOpen(kFALSE), fbDataCopyMode(kFALSE), fuEventCounter(0),fuStartEvent(0) ,fuStopEvent(0),
00039    fuEventInterval(0), fiTimeout(-1)
00040 {
00041         fxInputChannel=f_evt_control();
00042    TRACE((15,"TGo4MbsSource::TGo4MbsSource(Text_t*, Int_t)",__LINE__, __FILE__));
00043 // Open() call will be done by subclasses ctors, so we can overwrite Open() method
00044 //cout <<"TGo4MbsSource with data copy mode="<<fbDataCopyMode << endl;
00045 }
00046 
00047 
00048 TGo4MbsSource::TGo4MbsSource()
00049 : TGo4EventSource("default mbs source"),fiMode(0),
00050   fxEvent(0), fxBuffer(0), fxInfoHeader(0),
00051   fbIsOpen(kFALSE),fbDataCopyMode(kFALSE),fuEventCounter(0),fuStartEvent(0) ,fuStopEvent(0),
00052   fuEventInterval(0), fiTimeout(-1)
00053 {
00054         fxInputChannel=f_evt_control();
00055    TRACE((15,"TGo4MbsSource::TGo4MbsSource()",__LINE__, __FILE__));
00056 }
00057 
00058 TGo4MbsSource::~TGo4MbsSource()
00059 {
00060   TRACE((15,"TGo4MbsSource::~TGo4MbsSource()",__LINE__, __FILE__));
00061   Close();
00062   if(fxInputChannel)free(fxInputChannel);
00063 }
00064 
00065 void TGo4MbsSource::SetPrintEvent(Int_t num, Int_t sid, Int_t longw,
00066                                   Int_t hexw, Int_t dataw)
00067 {
00068    fxPrEventPar.fiNum=num;
00069    fxPrEventPar.fiSid=sid;
00070    fxPrEventPar.fiLong=longw;
00071    fxPrEventPar.fiHex=hexw;
00072    fxPrEventPar.fiData=dataw;
00073 }
00074 
00075 
00076 void TGo4MbsSource::BuildMbsEvent(TGo4MbsEvent* target)
00077 {
00078    TRACE((12,"TGo4MbsSource::BuildMbsEvent(TGo4MbsEvent*)",__LINE__, __FILE__));
00079    TGo4MbsSubEvent* subtarget=0;
00080    if(fxEvent!=0 && GetEventStatus()==GETEVT__SUCCESS) {
00081       // check for printevent mode here:
00082       if(fxPrEventPar.fiNum>0) {
00083          f_evt_type(fxBuffer,
00084                      (s_evhe *) fxEvent,
00085                      fxPrEventPar.fiSid,
00086                      fxPrEventPar.fiLong,
00087                      fxPrEventPar.fiHex,
00088                      fxPrEventPar.fiData);
00089          cout << endl; // flush cout buffer
00090          fxPrEventPar.fiNum--;
00091       }
00092    // we have a valid event, proceed
00093       Char_t* endofevent = (Char_t*) (fxEvent) +
00094             (fxEvent->l_dlen) * fguSHORTBYCHAR + fguEVHEBYCHAR ;
00095       //cout << "end of event "<< endofevent <<endl;
00096       target->SetValid(kTRUE); // reset target if previously was set to false
00097       target->SetDlen(fxEvent->l_dlen);
00098       target->SetType(fxEvent->i_type);
00099       target->SetSubtype(fxEvent->i_subtype);
00100 
00101 
00102    //**************************************************************************
00103    //**************************************************************************
00104    // Event Type 10:
00105       if(fxEvent->i_type==10) {
00106          s_ves10_1* subevent; // pointer to subevent
00107          Char_t* subevtpointer; // dito, in bytes
00108          target->SetTrigger(fxEvent->i_trigger);
00109          target->SetCount(fxEvent->l_count);
00110          target->SetDummy(fxEvent->i_dummy);
00111          Int_t totalsubdatalength=0; // check counter for total datalength of subevents
00112          if(fxEvent->l_dlen > 4) {
00113                // we have subevent data after the event header, proceed:
00114             subevent = (s_ves10_1*) (fxEvent + 1);
00115             // first subevent header starts after event header
00116             // loop over subevents:
00117             Int_t datalength = 0; // direct dlen from subevent header (in Short_t!)
00118    //            Int_t fieldlength=0; // actual size of the target Int_t data field
00119             while((datalength = subevent->l_dlen) >0 ) {
00120                totalsubdatalength+=datalength-2+sizeof(s_ves10_1)/sizeof(Short_t);
00121                if(datalength>fxEvent->l_dlen) {
00122                   TGo4Log::Debug(" !!! MbsSource --  SUBEVENTS LENGTH mismatch!!! skipping event #%d",fxEvent->l_count);
00123                   TGo4Log::Debug("\t sub dlen:%d, event dlen:%d ",datalength-2, fxEvent->l_dlen-4);
00124                   target->SetValid(kFALSE);
00125                   break;
00126                }
00127                Int_t * subeventid= (Int_t *) (subevent) + 2; // full id starts 2 ints after subevent head anyway
00128                //Int_t* subeventid= (Int_t*) &(subevent->i_procid); // full id is lw from control, subcrate, procid fields - some compilers complain here!
00129                Short_t* data = (Short_t*) (subevent+1); // data starts after subevent header
00130                subtarget = BuildMbsSubEvent(target, *subeventid, data, datalength); // find subevent that matches id and fill it
00131                subtarget->SetType(subevent->i_type); // need to set ids manually afterwards
00132                subtarget->SetSubtype(subevent->i_subtype);
00133                subevtpointer = (Char_t*) (subevent) +
00134                       datalength * fguSHORTBYCHAR + fguEVHEBYCHAR;
00135                subevent = (s_ves10_1*) subevtpointer;
00136                if ((Char_t*) subevent >= endofevent) {
00137                  //cout << "found end of event, breaking.."<< endl;
00138                  break;
00139                }
00140             } // while((datalength=subevent->l_dlen) >0)
00141             if(totalsubdatalength!=fxEvent->l_dlen-4) {
00142                TGo4Log::Debug(" !!! MbsSource --  SUBEVENTS TOTAL LENGTH mismatch!!! disabling event #%d",fxEvent->l_count);
00143                TGo4Log::Debug("\t subdlen sum:%d, event dlen:%d ",totalsubdatalength, fxEvent->l_dlen-4);
00144                target->SetValid(kFALSE);
00145             }
00146          } else { // if(fxEvent->dlen>4)
00147            // sorry, no subevents after event header
00148            TGo4Log::Debug(" !!! MbsSource --  NO SUBEVENTS!!! ");
00149            SetErrMess("!!! BuildMbsEvent: --  NO SUBEVENTS!!!");
00150            throw TGo4EventTimeoutException(this); // no subevts=timeout
00151          } // end if (fxEvent->dlen>0)
00152       } else
00153    //**************************************************************************
00154    //**************************************************************************
00155    // Event Type 4:
00156       if(fxEvent->i_type==4) {
00157    //      cout <<"found event type 4" << endl;
00158          s_evhe* eventfourone= (s_evhe*) fxEvent; // points to event 4 1 start
00159          // copy pseudo event header information to our target:
00160          target->SetTrigger(4);
00161          target->SetCount(1);
00162          target->SetDummy(0);
00163          if(fxEvent->l_dlen > 0) {
00164             Int_t subeventid= 4; // arbitrarily defined here for type 4,1
00165             Short_t* data = (Short_t*) (eventfourone+1); // data starts after subevent header
00166             Int_t datalength=eventfourone->l_dlen+2; // length of later subevent header  (in Short_t!)
00167                                                          // add 2 to direct dlen from 4,1 event header to account subevent header
00168             subtarget = BuildMbsSubEvent(target, subeventid, data, datalength); // find subevent that matches id and fill it
00169             subtarget->SetType(4);
00170             subtarget->SetSubtype(1);
00171          } else { // if(fxEvent->dlen>0)
00172             // sorry, no subevents after event header
00173             TGo4Log::Debug(" !!! MbsSource --  NO Data in event 4,1!!! ");
00174             SetErrMess("!!! BuildMbsEvent: --  NO Data in event 4,1!!!");
00175             throw TGo4EventTimeoutException(this); // no data=timeout
00176          } // end if (fxEvent->dlen>0)
00177       } else {
00178          TGo4Log::Debug(" !!! Mbs Source --  ERROR: Unknown event type %d !!! ",fxEvent->i_type);
00179          throw TGo4EventErrorException(this);
00180       } //if(fxEvent->i_type==...)
00181 
00182    } else {
00183       // somethings wrong, display error message from f_evt_error()
00184       TGo4Log::Debug(" !!! Mbs Source --  ERROR: %s !!! ",GetErrMess());
00185       throw TGo4EventErrorException(this);
00186    } //if(fxEvent!=0 && GetEventStatus()==GETEVT__SUCCESS)
00187 }
00188 
00189 
00190 TGo4MbsSubEvent* TGo4MbsSource::BuildMbsSubEvent(TGo4MbsEvent * target, Int_t fullID, Short_t* source, Int_t datalength)
00191 {
00192    Int_t fieldlength =0;
00193    TGo4MbsSubEvent* subtarget=0; // the subevent in use
00194    TGo4MbsSubEvent* subtargetindex=0; // target subevent iterator
00195    if(datalength>2)
00196       fieldlength = (datalength-2) / fguLONGBYSHORT ; // field is Int_t
00197    else {
00198       TGo4Log::Debug(" !!! MbsSource --  EMPTY subevent #%d ",fxEvent->l_count);
00199       fieldlength =0; // for empty subevents (<- W.M.)
00200    }
00201 
00202    target->ResetIterator();
00203    while ( ( subtargetindex= target->NextSubEvent(kTRUE) ) !=0 ) {
00204       // get pointer to complete id longword in structures:
00205       Int_t* subtargetid= &((subtargetindex->fxHeader).fiFullid);
00206       if(*subtargetid == fullID) {
00207          // subevent ids match:
00208          if(!subtargetindex->fbIsFilled) {
00209             // this has not been filled before, we fill this one
00210             subtarget=subtargetindex;
00211             break; // leave the loop, fill later
00212          } else {
00213             // was already filled in this cycle, continue for next sub
00214          }
00215       } else {
00216             // no match, try next subevent
00217       }
00218    } // while (subtargetindex...)
00219    if(!subtarget) {
00220       // we found no matching id, create new TObjArray entry
00221       subtarget = new TGo4MbsSubEvent(fieldlength);
00222       Int_t* newsubtargetid= &((subtarget->fxHeader).fiFullid);
00223       if(!fbDataCopyMode)
00224          {
00225             subtarget->fbIsDataOwner=kFALSE;
00226             delete [] (subtarget->fiData); // remove default field
00227             subtarget->fiAllocLen=0;
00228          }
00229       *newsubtargetid=fullID;
00230       TGo4Log::Debug(" Created new output subevent for event %d\n\tpid:%d subcrate:%d ctrl:%d",
00231                fxEvent->l_count ,subtarget->GetProcid(),subtarget->GetSubcrate(), subtarget->GetControl());
00232       target->fxSubEvArray->AddLast(subtarget);
00233    } 
00235    subtarget->SetDlen(datalength);
00236    void* data = (void*) source;
00237    if(fbDataCopyMode) {
00238       subtarget->fbIsDataOwner = kTRUE;
00239       subtarget->ReAllocate(fieldlength); // reallocate field if necessary
00241       if(datalength>2) 
00242          memcpy((void*) (subtarget->fiData),
00243                   data, (datalength-2)*sizeof(Short_t));
00244    } else {
00245       // set reference to external data field in subevent
00246       subtarget->fbIsDataOwner=kFALSE;
00247       subtarget->fiAllocLen=fieldlength;
00248       if(datalength>2)
00249          subtarget->fiData= (Int_t*) data;
00250       else
00251          subtarget->fiData= 0; // reset for empty subevent
00252    }// if(fbDataCopyMode)
00253    subtarget->fbIsFilled=kTRUE; // remember we filled this one, never overwrite!
00254    return subtarget;
00255 }
00256 
00257 Int_t TGo4MbsSource::NextEvent()
00258 {
00259    TRACE((12,"TGo4MbsSource::NextEvent()",__LINE__, __FILE__));
00260    // skip and sample mode introduced without changed gsievt functions for first tests
00261    ULong_t eventstep;
00262    if(fuEventInterval)
00263       eventstep = fuEventInterval;
00264    else
00265       eventstep=1;
00266       
00267    // test if we had reached the last event:
00268    if(fuStopEvent!=0 && fuEventCounter>=fuStopEvent)
00269       SetEventStatus(GETEVT__NOMORE);
00270    else {
00271       // check possible overflow of our counter:  
00272       if(fuEventCounter+eventstep<fuEventCounter)
00273         {
00274             TGo4Log::Warn("TGo4MbsSource::NextEvent(): Overflow of eventcounter at %d, reset to 0",fuEventCounter),
00275             fuEventCounter=0;
00276         }
00277       // go to the start event if necessary
00278       if(fuEventCounter<fuStartEvent) 
00279           while(fuEventCounter++<fuStartEvent){}
00280       ULong_t counter(0);    
00281       for(counter=fuEventCounter; counter<fuEventCounter+eventstep; ++counter) {
00282          // retrieve the event, skip all events until end of the step
00283          Int_t status=f_evt_get_event(fxInputChannel,
00284                              (Int_t **) (void*) &fxEvent,
00285                              (Int_t **) (void*) &fxBuffer);
00286          SetEventStatus(status);
00287          if(status!=0) break;
00288       }
00289       fuEventCounter = counter; // index of next event
00290    }
00291    if(GetEventStatus()!=0) {
00292       Text_t buffer[TGo4EventSource::fguTXTLEN];
00293       f_evt_error(GetEventStatus(),buffer,1); // provide text message for later output
00294       SetErrMess(buffer);
00295    }
00296 
00297    switch(GetEventStatus()) {
00298       case 0:
00299          return 0;
00300          break;
00301       case GETEVT__TIMEOUT:
00302          throw TGo4EventTimeoutException(this);
00303          break;
00304       case GETEVT__NOMORE:
00305          throw TGo4EventEndException(this);
00306          break;
00307       default:
00308          throw TGo4EventErrorException(this);
00309          break;
00310    }
00311    
00312    cout << "MbsSource::NextEvent --  NEVER COME HERE" << endl;
00313    return GetEventStatus();
00314 }
00315 
00316 Int_t TGo4MbsSource::Open()
00317 {
00318    TRACE((12,"TGo4MbsSource::Open()",__LINE__, __FILE__));
00319 
00320    if(fbIsOpen) return -1;
00321 //cout << "Open of TGo4MbsSource"<< endl;
00322 // open connection/file
00323    void* headptr= &fxInfoHeader; // suppress type-punned pointer warning
00324    f_evt_timeout(fxInputChannel, fiTimeout); // have to set timeout before open now JAM
00325    Int_t status = f_evt_get_open(
00326                      fiMode,
00327                      const_cast<Text_t*>( GetName() ),
00328                      fxInputChannel,
00329                      (Char_t**) headptr,
00330                      0,
00331                      0);
00332    SetCreateStatus(status);
00333    if(GetCreateStatus() !=GETEVT__SUCCESS) {
00334      //     TGo4Log::Debug(" Mbs Source --  !!! failed to open input from type %d:  %s!!! ",
00335      //        fiMode, GetName());
00336       Text_t buffer[TGo4EventSource::fguTXTLEN];
00337       f_evt_error(GetCreateStatus(),buffer,1); // provide text message for later output
00338 //
00339 //   snprintf(buffer,TGo4EventSource::fguTXTLEN-1," Mbs Source --  !!! failed to open input from type %d:  %s!!! ",
00340 //        fiMode, GetName());
00341       SetErrMess(buffer);
00342       fbIsOpen = kFALSE;
00343       throw TGo4EventErrorException(this);
00344    } else {
00345       TGo4Log::Debug(" Mbs Source --  opened input from type %d:  %s . Timeout=%d s",
00346                fiMode, GetName(), fiTimeout);
00347 
00348       fbIsOpen=kTRUE;
00349    }
00350    return status;
00351 }
00352 
00353 Int_t TGo4MbsSource::Close()
00354 {
00355    TRACE((12,"TGo4MbsSource::Close()",__LINE__, __FILE__));
00356    if(!fbIsOpen) return -1;
00357 //cout << "Close of TGo4MbsSource"<< endl;
00358    Int_t rev = GetCreateStatus();
00359 // close connection/file
00360    if(rev == GETEVT__SUCCESS) {
00361       f_evt_get_close(fxInputChannel);
00362       fbIsOpen=kFALSE;
00363    }
00364 
00365    return rev;
00366 }
00367 
00368 s_bufhe * TGo4MbsSource::GetBufferHeader()
00369 {
00370    return (s_bufhe*) f_evt_get_buffer_ptr(fxInputChannel);
00371 }
00372 
00373 //----------------------------END OF GO4 SOURCE FILE ---------------------

Generated on Fri Nov 28 12:59:08 2008 for Go4-v3.04-1 by  doxygen 1.4.2