Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

TMidasEvent.cxx

Go to the documentation of this file.
00001 //  TMidasEvent.cxx.
00009 #include <iostream>
00010 #include <iomanip>
00011 
00012 #include "TMidasEvent.h"
00013 
00014 using std::cout;
00015 using std::cerr;
00016 using std::endl;
00017 using std::hex;
00018 using std::dec;
00019 using std::setw;
00020 using std::setfill;
00021 using std::showbase;
00022 using std::bad_alloc;
00023 using std::ios_base;
00024 
00025 TMidasEvent::TMidasEvent()
00026   : fBankListMax(64), fStringBankListMax(fBankListMax * 4),
00027     fData(0), fAllocated(false)
00028 {
00031   fEventHeader.fEventId      = 0;
00032   fEventHeader.fTriggerMask  = 0;
00033   fEventHeader.fSerialNumber = 0;
00034   fEventHeader.fTimeStamp    = 0;
00035   fEventHeader.fDataSize     = 0;
00036 }
00037 
00038 TMidasEvent::TMidasEvent(const TMidasEvent &rhs)
00039   : fBankListMax(64), fStringBankListMax(fBankListMax * 4)
00040 {
00045   fData         = rhs.fData;
00046   fEventHeader.fEventId      = rhs.fEventHeader.fEventId;
00047   fEventHeader.fTriggerMask  = rhs.fEventHeader.fTriggerMask;
00048   fEventHeader.fSerialNumber = rhs.fEventHeader.fSerialNumber;
00049   fEventHeader.fTimeStamp    = rhs.fEventHeader.fTimeStamp;
00050   fEventHeader.fDataSize     = rhs.fEventHeader.fDataSize;
00051   if (fData)
00052     try {
00053       fData = new Char_t[4096 * (1 + fEventHeader.fDataSize / 4096)];
00054       strcpy(fData, rhs.fData);
00055       fAllocated = true;
00056     } catch(bad_alloc) {
00057       cerr << "operator=: ERROR - unable to copy data" << endl;
00058       fData = 0;
00059     }
00060 }
00061 
00062 TMidasEvent::~TMidasEvent()
00063 {
00066   Clear();
00067 }
00068 
00069 TMidasEvent & TMidasEvent::operator=(const TMidasEvent &rhs)
00070 {
00075   if (&rhs != this) {
00076     Clear();
00077   fData         = rhs.fData;
00078   fEventHeader.fEventId      = rhs.fEventHeader.fEventId;
00079   fEventHeader.fTriggerMask  = rhs.fEventHeader.fTriggerMask;
00080   fEventHeader.fSerialNumber = rhs.fEventHeader.fSerialNumber;
00081   fEventHeader.fTimeStamp    = rhs.fEventHeader.fTimeStamp;
00082   fEventHeader.fDataSize     = rhs.fEventHeader.fDataSize;
00083   if (fData)
00084     try {
00085       fData = new Char_t[4096 * (1 + fEventHeader.fDataSize / 4096)];
00086       strcpy(fData, rhs.fData);
00087       fAllocated = true;
00088     } catch(bad_alloc) {
00089       cerr << "operator=: ERROR - unable to copy data" << endl;
00090       fData = 0;
00091     }
00092   }
00093   return *this;
00094 }
00095 
00096 void TMidasEvent::Clear(const Char_t *option)
00097 {
00103   if (fData && fAllocated) delete [] fData;
00104   fData         = 0;
00105   fEventHeader.fEventId      = 0;
00106   fEventHeader.fTriggerMask  = 0;
00107   fEventHeader.fSerialNumber = 0;
00108   fEventHeader.fTimeStamp    = 0;
00109   fEventHeader.fDataSize     = 0;
00110 }
00111 
00112 void TMidasEvent::Set(Char_t *eventData)
00113 {
00119   EventHeader_t *h = reinterpret_cast<EventHeader_t *>(eventData);
00120   fEventHeader.fEventId      = h->fEventId;
00121   fEventHeader.fTriggerMask  = h->fTriggerMask;
00122   fEventHeader.fSerialNumber = h->fSerialNumber;
00123   fEventHeader.fTimeStamp    = h->fTimeStamp;
00124   fEventHeader.fDataSize     = h->fDataSize;
00125   fData = static_cast<Char_t *>(eventData + sizeof(fEventHeader));
00126 }
00127                  
00128 Int_t
00129 TMidasEvent::LocateBank(const Char_t *name, void *pdata) const
00130 {
00136   Int_t TID_SIZE[] = {0, 1, 1, 1, 2, 2, 4, 4, 4, 4, 8, 1, 0, 0, 0, 0, 0};
00137   Bank_t *pbk;
00138   Bank32_t *pbk32;
00139   DWORD dname;
00140   void *event = reinterpret_cast<void *>(fData);
00141 
00142   if (((((BankHeader_t *) event)->fFlags & (1<<4)) > 0)) {
00143     pbk32 = (Bank32_t *) (((BankHeader_t *) event) + 1);
00144     strncpy((Char_t *) &dname, name, 4);
00145     do {
00146       if (*((DWORD *) pbk32->fName) == dname) {
00147         *((void **) pdata) = pbk32 + 1;
00148         if (TID_SIZE[pbk32->fType & 0xFF] == 0)
00149           return pbk32->fDataSize;
00150         return pbk32->fDataSize / TID_SIZE[pbk32->fType & 0xFF];
00151       }
00152       pbk32 = (Bank32_t *) ((Char_t *)(pbk32 + 1)+(((pbk32->fDataSize)+7) & ~7));
00153     } while ((DWORD) pbk32 - (DWORD) event <
00154              ((BankHeader_t *) event)->fDataSize + sizeof(BankHeader_t));
00155   } else {
00156     pbk = (Bank_t *) (((BankHeader_t *) event) + 1);
00157     strncpy((Char_t *) &dname, name, 4);
00158     do {
00159       if (*((DWORD *) pbk->fName) == dname) {
00160         *((void **) pdata) = pbk + 1;
00161         if (TID_SIZE[pbk->fType & 0xFF] == 0)
00162           return pbk->fDataSize;
00163         return pbk->fDataSize / TID_SIZE[pbk->fType & 0xFF];
00164       }
00165       pbk = (Bank_t *) ((Char_t *) (pbk + 1) + (((pbk->fDataSize)+7) & ~7));
00166     } while ((DWORD) pbk - (DWORD) event <
00167              ((BankHeader_t *) event)->fDataSize + sizeof(BankHeader_t));
00168   }
00169   //
00170   // bank not found
00171   //
00172   *((void **) pdata) = NULL;
00173   return 0;
00174 }
00175 
00176 Int_t TMidasEvent::FindBank(const Char_t *name, ULong_t *bklen,
00177                             ULong_t *bktype, void **pdata) const
00178 {
00186   Int_t TID_SIZE[] = {0, 1, 1, 1, 2, 2, 4, 4, 4, 4, 8, 1, 0, 0, 0, 0, 0};
00187   Bank_t *pbk;
00188   Bank32_t *pbk32;
00189   DWORD dname;
00190   BankHeader_t *pbkh = reinterpret_cast<BankHeader_t *>(fData);
00191 
00192   if (((((BankHeader_t *) pbkh)->fFlags & (1<<4)) > 0)) {
00193     pbk32 = (Bank32_t *) (pbkh + 1);
00194     strncpy((Char_t *) &dname, name, 4);
00195     do {
00196       if (*((DWORD *) pbk32->fName) == dname) {
00197         *((void **) pdata) = pbk32 + 1;
00198         if (TID_SIZE[pbk32->fType & 0xFF] == 0)
00199           *bklen = pbk32->fDataSize;
00200         else
00201           *bklen = pbk32->fDataSize / TID_SIZE[pbk32->fType & 0xFF];
00202 
00203         *bktype = pbk32->fType;
00204         return 1;
00205       }
00206       pbk32 = (Bank32_t *) ((Char_t *) (pbk32 + 1) +
00207                           (((pbk32->fDataSize)+7) & ~7));
00208     } while ((DWORD) pbk32 -
00209              (DWORD) pbkh < pbkh->fDataSize + sizeof(BankHeader_t));
00210   } else {
00211     pbk = (Bank_t *) (pbkh + 1);
00212     strncpy((Char_t *) &dname, name, 4);
00213     do {
00214       if (*((DWORD *) pbk->fName) == dname) {
00215         *((void **) pdata) = pbk + 1;
00216         if (TID_SIZE[pbk->fType & 0xFF] == 0)
00217           *bklen = pbk->fDataSize;
00218         else
00219           *bklen = pbk->fDataSize / TID_SIZE[pbk->fType & 0xFF];
00220 
00221         *bktype = pbk->fType;
00222         return 1;
00223       }
00224       pbk = (Bank_t *) ((Char_t *) (pbk + 1) + (((pbk->fDataSize)+7) & ~7));
00225     } while ((DWORD) pbk - (DWORD) pbkh < pbkh->fDataSize +
00226              sizeof(BankHeader_t));
00227   }
00228   //
00229   // bank not found
00230   //
00231   *((void **) pdata) = NULL;
00232   return 0;
00233 }
00234 
00235 Int_t TMidasEvent::SwapBytes(Bool_t force)
00236 {
00249   BankHeader_t *pbh;
00250   Bank_t *pbk;
00251   Bank32_t *pbk32;
00252   void *pdata;
00253   WORD type;
00254   Bool_t b32;
00255   
00256   pbh = (BankHeader_t *) fData;
00257   //
00258   // only swap if flags in high 16-bit
00259   //
00260   if (pbh->fFlags < 0x10000 && ! force)
00261     return 0;
00262 
00263   //
00264   // swap bank header
00265   //
00266   DWORD_SWAP(&pbh->fDataSize);
00267   DWORD_SWAP(&pbh->fFlags);
00268   //
00269   // check for 32-bit banks
00270   //
00271   b32 = ((pbh->fFlags & (1<<4)) > 0);
00272 
00273   pbk = (Bank_t *) (pbh + 1);
00274   pbk32 = (Bank32_t *) pbk;
00275   //
00276   // scan event
00277   //
00278   while ((Int_t) pbk - (Int_t) pbh < (Int_t) pbh->fDataSize +
00279          (Int_t) sizeof(BankHeader_t)) {
00280     //
00281     // swap bank header
00282     //
00283     if (b32) {
00284       DWORD_SWAP(&pbk32->fType);
00285       DWORD_SWAP(&pbk32->fDataSize);
00286       pdata = pbk32 + 1;
00287       type = (WORD) pbk32->fType;
00288     } else {
00289       WORD_SWAP(&pbk->fType);
00290       WORD_SWAP(&pbk->fDataSize);
00291       pdata = pbk + 1;
00292       type = pbk->fType;
00293     }
00294     //
00295     // pbk points to next bank
00296     //
00297     if (b32) {
00298       pbk32 = (Bank32_t *) ((Char_t *) (pbk32 + 1) +
00299                           (((pbk32->fDataSize)+7) & ~7));
00300       pbk = (Bank_t *) pbk32;
00301     } else {
00302       pbk = (Bank_t *) ((Char_t *) (pbk + 1) +  (((pbk->fDataSize)+7) & ~7));
00303       pbk32 = (Bank32_t *) pbk;
00304     }
00305 
00306     switch (type) {
00307     case 4:
00308     case 5:
00309       while ((Int_t) pdata < (Int_t) pbk) {
00310         WORD_SWAP(pdata);
00311         pdata = (void *) (((WORD *) pdata) + 1);
00312       }
00313       break;
00314     case 6:
00315     case 7:
00316     case 8:
00317     case 9:
00318       while ((Int_t) pdata < (Int_t) pbk) {
00319         DWORD_SWAP(pdata);
00320         pdata = (void *) (((DWORD *) pdata) + 1);
00321       }
00322       break;
00323     case 10:
00324       while ((Int_t) pdata < (Int_t) pbk) {
00325         QWORD_SWAP(pdata);
00326         pdata = (void *) (((Double_t *) pdata) + 1);
00327       }
00328       break;
00329     }
00330   }
00331   return true;
00332 }
00333 
00334 void TMidasEvent::Print(const Char_t *option) const
00335 {
00341   cout.setf(ios_base::showbase | ios_base::internal);
00342   cout.setf(ios_base::hex, ios_base::basefield);
00343   cout.fill('0');
00344   cout << endl << "Event start:" << endl
00345        << "  Event ID:       " << setw(6)  << fEventHeader.fEventId      << endl
00346        << "  Trigger mask:   " << setw(6)  << fEventHeader.fTriggerMask  << endl
00347        << "  Serial number:  " << setw(10) << fEventHeader.fSerialNumber << endl
00348        << "  Time-stamp:     " << setw(10) << fEventHeader.fTimeStamp
00349        << " ==> "
00350        << ctime(reinterpret_cast<time_t const *>(&fEventHeader.fTimeStamp))
00351        << "  Data size:      " << setw(10) << fEventHeader.fDataSize << endl;
00352   if ((fEventHeader.fEventId & 0xffff) == TMidasEvent::kEV_BOR) {
00353     const Char_t *midasMagic =
00354       reinterpret_cast<const Char_t *>(&fEventHeader.fTriggerMask);
00355     cout << "No banks, start of run:"      << endl << "  midas magic="
00356          << midasMagic[0] << midasMagic[1] << endl << "  run number="
00357          << dec << fEventHeader.fSerialNumber << endl;
00358   } else if ((fEventHeader.fEventId & 0xffff) == TMidasEvent::kEV_EOR) {
00359     cout << "No banks, end of run:" << endl;
00360   } else if (option[0] == 'a' || option[0] == 'b') {
00361     UShort_t banksN;
00362     const Char_t *bankList = GetBankList(banksN);
00363 
00364     cout << "Banks: " << bankList << endl;
00365     for (Int_t i = 0; i < banksN * 4; i += 4) {
00366       ULong_t bankLength = 0;
00367       ULong_t bankType = 0;
00368       void *pdata = 0;
00369       Int_t found = FindBank(&bankList[i], &bankLength, &bankType,  &pdata);
00370 
00371       cout << "Bank="         << bankList[i]     << bankList[i + 1]
00372            << bankList[i + 2] << bankList[i + 3] << " length="   << dec
00373            << bankLength      << " type="        << bankType     << endl;
00374       if (option[0] == 'a' && found) {
00375         cout << "Bank data: " << endl;
00376         switch (bankType) {
00377           //
00378           // TID_WORD
00379           //
00380         case 4:
00381           for (UInt_t j = 0; j < bankLength; j++) {
00382             cout << setw(6) << hex << showbase
00383                  << static_cast<Short_t>((static_cast<WORD *>(pdata))[j])
00384                  << " ";
00385             if (j % 11 == 10)
00386               cout << endl;
00387           }
00388           cout << endl;
00389           break;
00390           //
00391           // TID_DWORD
00392           //
00393         case 6:
00394           for (UInt_t j = 0; j < bankLength; j++) {
00395             cout << setw(10) << hex << showbase
00396                  << static_cast<Int_t>((static_cast<DWORD *>(pdata))[j]) << " ";
00397             if (j % 7 == 6)
00398               cout << endl;
00399           }
00400           cout << endl;
00401           break;
00402           //
00403           // TID_FLOAT
00404           //
00405         case 9:
00406           for (UInt_t j = 0; j < bankLength; j++) {
00407             cout << setw(6) << dec
00408                  << static_cast<Float_t>((static_cast<Float_t *>(pdata))[j])
00409                  << " ";
00410             if (j % 7 == 6)
00411               cout << endl;
00412           }
00413           cout << endl;
00414           break;
00415         default:
00416           cerr << "Print: ERROR - unknown bank type " << bankType << endl;
00417         }
00418       }
00419     }
00420     delete bankList;
00421   }
00422 }
00423 
00424 void TMidasEvent::AllocateData()
00425 {
00428   try {
00429     fData = new Char_t[4096 * (1 + fEventHeader.fDataSize / 4096)];
00430     fAllocated = true;
00431   } catch(bad_alloc) {
00432     cerr << "AllocateData: ERROR - unable to allocate memory for data" << endl;
00433     fData = 0;
00434     fAllocated = false;
00435   }
00436 }
00437 
00438 const Char_t * TMidasEvent::GetBankList(UShort_t &banksN) const
00439 {
00445   Char_t bankList[fStringBankListMax];
00446   Char_t *bklist = bankList;
00447   void *event = reinterpret_cast<void *>(fData);
00448   Bank_t *pmbk = NULL;
00449   Bank32_t *pmbk32 = NULL;
00450   Char_t *pdata;
00451   Bool_t moreBanks = 1;
00452 
00453   //
00454   // compose bank list
00455   //
00456   bklist[0] = 0;
00457   banksN = 0;
00458   
00459   if (fEventHeader.fEventId > 0) {
00460 
00461     do {
00462       //
00463       // scan all banks for bank name only
00464       //
00465       if ((((BankHeader_t *) event)->fFlags & (1 << 4)) > 0) {
00466         IterateBank32(event, &pmbk32, &pdata);
00467         if (pmbk32 == NULL)
00468           break;
00469       } else {
00470         IterateBank(event, &pmbk, &pdata);
00471         if (pmbk == NULL)
00472           break;
00473       }
00474       banksN++;
00475 
00476       if (banksN > fBankListMax) {
00477         cerr << "GetBankList: Over " << fBankListMax
00478              << " banks -> truncated" << endl;
00479         moreBanks = 0;
00480       } else {
00481         if ((((BankHeader_t *) event)->fFlags & (1 << 4)) > 0)
00482           strncat(bklist, (Char_t *) pmbk32->fName, 4);
00483         else
00484           strncat(bklist, (Char_t *) pmbk->fName, 4);
00485       }
00486     } while (moreBanks);
00487   }
00488   return strdup(bankList);
00489 }
00490 
00491 Int_t TMidasEvent::IterateBank(void *event, Bank_t **pbk, void *pdata) const
00492 {
00502   if (*pbk == NULL)
00503     *pbk = (Bank_t *) (((BankHeader_t *) event) + 1);
00504   else
00505     *pbk = (Bank_t *) ((Char_t *) (*pbk + 1) + ((((*pbk)->fDataSize)+7) & ~7));
00506 
00507   *((void **) pdata) = (*pbk) + 1;
00508 
00509   if ((DWORD) * pbk - (DWORD) event >=
00510       ((BankHeader_t *) event)->fDataSize + sizeof(BankHeader_t)) {
00511     *pbk = *((Bank_t **) pdata) = NULL;
00512     return 0;
00513   }
00514   return (*pbk)->fDataSize;
00515 }
00516 
00517 Int_t TMidasEvent::IterateBank32(void *event, Bank32_t **pbk, void *pdata) const
00518 {
00528   if (*pbk == NULL)
00529     *pbk = (Bank32_t *) (((BankHeader_t *) event) + 1);
00530   else
00531     *pbk = (Bank32_t *) ((Char_t *) (*pbk + 1) +
00532                          ((((*pbk)->fDataSize)+7) & ~7));
00533 
00534   *((void **) pdata) = (*pbk) + 1;
00535 
00536   if ((DWORD) * pbk - (DWORD) event >=
00537       ((BankHeader_t *) event)->fDataSize + sizeof(BankHeader_t)) {
00538     *pbk = *((Bank32_t **) pdata) = NULL;
00539     return 0;
00540   }
00541   return (*pbk)->fDataSize;
00542 }
00543 
00544 void TMidasEvent::SwapBytesEventHeader()
00545 {
00548   WORD_SWAP(&fEventHeader.fEventId);
00549   WORD_SWAP(&fEventHeader.fTriggerMask);
00550   DWORD_SWAP(&fEventHeader.fSerialNumber);
00551   DWORD_SWAP(&fEventHeader.fTimeStamp);
00552   DWORD_SWAP(&fEventHeader.fDataSize);
00553 }

Generated on Mon Jan 8 11:54:31 2007 for DragonRoot by  doxygen 1.3.9.1