CMS 3D CMS Logo

/data/git/CMSSW_5_3_11_patch5/src/DataFormats/L1GlobalTrigger/src/L1GtfeExtWord.cc

Go to the documentation of this file.
00001 
00017 // this class header
00018 #include "DataFormats/L1GlobalTrigger/interface/L1GtfeExtWord.h"
00019 
00020 // system include files
00021 #include <iomanip>
00022 #include <stdint.h>
00023 
00024 // user include files
00025 #include "FWCore/Utilities/interface/EDMException.h"
00026 
00027 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00028 #include "FWCore/MessageLogger/interface/MessageDrop.h"
00029 
00030 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetupFwd.h"
00031 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetup.h"
00032 
00033 
00034 // constructors
00035 
00036 // empty constructor, all members set to zero;
00037 L1GtfeExtWord::L1GtfeExtWord() :
00038     L1GtfeWord(), m_bstSource(0) {
00039 
00040     // empty
00041 
00042 }
00043 
00044 // all members set to zero, m_bst has bstSizeBytes zero elements
00045 L1GtfeExtWord::L1GtfeExtWord(int bstSizeBytes) :
00046     L1GtfeWord(), m_bstSource(0) {
00047 
00048     m_bst.resize(bstSizeBytes);
00049 
00050 }
00051 
00052 
00053 // constructor from unpacked values, m_bst size taken from bstValue
00054 L1GtfeExtWord::L1GtfeExtWord(
00055         cms_uint16_t boardIdValue, cms_uint16_t recordLength1Value,
00056         cms_uint16_t recordLengthValue, cms_uint16_t bxNrValue,
00057         cms_uint32_t setupVersionValue, cms_uint16_t activeBoardsValue,
00058         cms_uint16_t altNrBxBoardValue, cms_uint32_t totalTriggerNrValue, // end of L1GtfeWord
00059         std::vector<cms_uint16_t> bstValue, cms_uint16_t bstSourceValue) :
00060     L1GtfeWord(
00061             boardIdValue, recordLength1Value, recordLengthValue, bxNrValue, setupVersionValue,
00062             activeBoardsValue, altNrBxBoardValue, totalTriggerNrValue), m_bst(bstValue),
00063             m_bstSource(bstSourceValue)
00064 
00065 {
00066 
00067     // empty
00068 }
00069 
00070 // destructor
00071 L1GtfeExtWord::~L1GtfeExtWord() {
00072 
00073     // empty now
00074 
00075 }
00076 
00077 // equal operator
00078 bool L1GtfeExtWord::operator==(const L1GtfeExtWord& result) const
00079 {
00080 
00081     // base class
00082 
00083     const L1GtfeWord gtfeResult = result;
00084     const L1GtfeWord gtfeThis = *this;
00085 
00086     if (gtfeThis != gtfeResult) {
00087         return false;
00088     }
00089 
00090 
00091     //
00092 
00093     for (unsigned int iB = 0; iB < m_bst.size(); ++iB) {
00094         if(m_bst[iB] != result.m_bst[iB]) {
00095             return false;
00096         }
00097     }
00098 
00099     if ( m_bstSource != result.m_bstSource) {
00100         return false;
00101     }
00102 
00103     // all members identical
00104     return true;
00105 
00106 }
00107 
00108 // unequal operator
00109 bool L1GtfeExtWord::operator!=(const L1GtfeExtWord& result) const
00110 {
00111 
00112     return !( result == *this);
00113 
00114 }
00115 
00116 // methods
00117 
00118 const cms_uint64_t L1GtfeExtWord::gpsTime() const
00119 {
00120 
00121     cms_uint64_t gpst = 0ULL;
00122 
00123     // return 0 if BST message too small
00124     int bstSize = m_bst.size();
00125     if (GpsTimeLastBlock >= bstSize) {
00126         return gpst;
00127     }
00128 
00129     for (int iB = GpsTimeFirstBlock; iB <= GpsTimeLastBlock; ++iB) {
00130 
00131         // keep capitalization for similarity with other functions
00132         const int scaledIB = iB - GpsTimeFirstBlock;
00133         const int BstShift = BstBitSize*scaledIB;
00134 
00135         gpst = gpst |
00136                ( (static_cast<cms_uint64_t> (m_bst[iB])) << BstShift );
00137 
00138     }
00139 
00140     return gpst;
00141 }
00142 
00143 void L1GtfeExtWord::setGpsTime(const cms_uint64_t gpsTimeValue) {
00144 
00145     // return if BST message too small
00146     int bstSize = m_bst.size();
00147     if (GpsTimeLastBlock >= bstSize) {
00148 
00149         edm::LogError("L1GtfeExtWord") << "Error: BST message length "
00150             << bstSize << " smaller than the required GpsTimeLastBlock "
00151             << GpsTimeLastBlock << "\n Cannot set GpsTime" << std::endl;
00152 
00153         return;
00154     }
00155 
00156     for (int iB = GpsTimeFirstBlock; iB <= GpsTimeLastBlock; ++iB) {
00157 
00158         // keep capitalization for similarity with other functions
00159         const int scaledIB = iB - GpsTimeFirstBlock;
00160         const int BstShift = BstBitSize*scaledIB;
00161         const cms_uint64_t BstMask = 0x0000000000000000ULL | (BstBlockMask << BstShift);
00162 
00163         m_bst[iB] = static_cast<cms_uint16_t> ((gpsTimeValue & BstMask) >> BstShift);
00164 
00165         //LogTrace("L1GtfeExtWord")
00166         //<< "BstShift: value [dec] = " << BstShift << "\n"
00167         //<< "BstBlockMask: value [hex] = "  << std::hex << BstBlockMask << "\n"
00168         //<< "BstMask: value [hex] = "<< BstMask << std::dec
00169         //<< std::endl;
00170 
00171         //LogTrace("L1GtfeExtWord")
00172         //<< "BST block " << iB << ": value [hex] = " << std::hex << m_bst[iB] << std::dec
00173         //<< std::endl;
00174 
00175     }
00176 
00177 }
00178 
00179 const cms_uint16_t L1GtfeExtWord::bstMasterStatus() const
00180 {
00181 
00182     cms_uint16_t bms = 0;
00183 
00184     // return 0 if BST message too small
00185     int bstSize = m_bst.size();
00186     if (BstMasterStatusLastBlock >= bstSize) {
00187         return bms;
00188     }
00189 
00190     for (int iB = BstMasterStatusFirstBlock; iB <= BstMasterStatusLastBlock; ++iB) {
00191 
00192         // keep capitalization for similarity with other functions
00193         const int scaledIB = iB - BstMasterStatusFirstBlock;
00194         const int BstShift = BstBitSize*scaledIB;
00195 
00196         bms = bms | ( m_bst[iB] << BstShift );
00197 
00198     }
00199 
00200     return bms;
00201 }
00202 
00203 
00204 const cms_uint32_t L1GtfeExtWord::turnCountNumber() const
00205 {
00206 
00207     cms_uint32_t tcn = 0;
00208 
00209     // return 0 if BST message too small
00210     int bstSize = m_bst.size();
00211     if (TurnCountNumberLastBlock >= bstSize) {
00212         return tcn;
00213     }
00214 
00215     for (int iB = TurnCountNumberFirstBlock; iB <= TurnCountNumberLastBlock; ++iB) {
00216 
00217         // keep capitalization for similarity with other functions
00218         const int scaledIB = iB - TurnCountNumberFirstBlock;
00219         const int BstShift = BstBitSize*scaledIB;
00220 
00221         tcn = tcn |
00222               ( (static_cast<cms_uint32_t> (m_bst[iB])) << BstShift );
00223 
00224     }
00225 
00226     return tcn;
00227 }
00228 
00229 const cms_uint32_t L1GtfeExtWord::lhcFillNumber() const
00230 {
00231 
00232     cms_uint32_t lhcfn = 0;
00233 
00234     // return 0 if BST message too small
00235     int bstSize = m_bst.size();
00236     if (LhcFillNumberLastBlock >= bstSize) {
00237         return lhcfn;
00238     }
00239 
00240     for (int iB = LhcFillNumberFirstBlock; iB <= LhcFillNumberLastBlock; ++iB) {
00241 
00242         // keep capitalization for similarity with other functions
00243         const int scaledIB = iB - LhcFillNumberFirstBlock;
00244         const int BstShift = BstBitSize*scaledIB;
00245 
00246         lhcfn = lhcfn |
00247                 ( (static_cast<cms_uint32_t> (m_bst[iB])) << BstShift );
00248 
00249     }
00250 
00251     return lhcfn;
00252 }
00253 
00254 const cms_uint16_t L1GtfeExtWord::beamMode() const
00255 {
00256 
00257     cms_uint16_t bm = 0;
00258 
00259     // return 0 if BST message too small
00260     int bstSize = m_bst.size();
00261     if (BeamModeLastBlock >= bstSize) {
00262         return bm;
00263     }
00264 
00265     for (int iB = BeamModeFirstBlock; iB <= BeamModeLastBlock; ++iB) {
00266 
00267         // keep capitalization for similarity with other functions
00268         const int scaledIB = iB - BeamModeFirstBlock;
00269         const int BstShift = BstBitSize*scaledIB;
00270 
00271         bm = bm | ( m_bst[iB] << BstShift );
00272 
00273     }
00274 
00275     return bm;
00276 }
00277 
00278 const cms_uint16_t L1GtfeExtWord::particleTypeBeam1() const
00279 {
00280 
00281     cms_uint16_t ptb = 0;
00282 
00283     // return 0 if BST message too small
00284     int bstSize = m_bst.size();
00285     if (ParticleTypeBeam1LastBlock >= bstSize) {
00286         return ptb;
00287     }
00288 
00289     for (int iB = ParticleTypeBeam1FirstBlock; iB <= ParticleTypeBeam1LastBlock; ++iB) {
00290 
00291         // keep capitalization for similarity with other functions
00292         const int scaledIB = iB - ParticleTypeBeam1FirstBlock;
00293         const int BstShift = BstBitSize*scaledIB;
00294 
00295         ptb = ptb | ( m_bst[iB] << BstShift );
00296 
00297     }
00298 
00299     return ptb;
00300 }
00301 
00302 const cms_uint16_t L1GtfeExtWord::particleTypeBeam2() const
00303 {
00304 
00305     cms_uint16_t ptb = 0;
00306 
00307     // return 0 if BST message too small
00308     int bstSize = m_bst.size();
00309     if (ParticleTypeBeam2LastBlock >= bstSize) {
00310         return ptb;
00311     }
00312 
00313     for (int iB = ParticleTypeBeam2FirstBlock; iB <= ParticleTypeBeam2LastBlock; ++iB) {
00314 
00315         // keep capitalization for similarity with other functions
00316         const int scaledIB = iB - ParticleTypeBeam2FirstBlock;
00317         const int BstShift = BstBitSize*scaledIB;
00318 
00319         ptb = ptb | ( m_bst[iB] << BstShift );
00320 
00321     }
00322 
00323     return ptb;
00324 
00325 }
00326 
00327 const cms_uint16_t L1GtfeExtWord::beamMomentum() const
00328 {
00329 
00330     cms_uint16_t bm = 0;
00331 
00332     // return 0 if BST message too small
00333     int bstSize = m_bst.size();
00334     if (BeamMomentumLastBlock >= bstSize) {
00335         return bm;
00336     }
00337 
00338     for (int iB = BeamMomentumFirstBlock; iB <= BeamMomentumLastBlock; ++iB) {
00339 
00340         // keep capitalization for similarity with other functions
00341         const int scaledIB = iB - BeamMomentumFirstBlock;
00342         const int BstShift = BstBitSize*scaledIB;
00343 
00344         bm = bm | ( m_bst[iB] << BstShift );
00345 
00346     }
00347 
00348     return bm;
00349 }
00350 
00351 const cms_uint32_t L1GtfeExtWord::totalIntensityBeam1() const
00352 {
00353 
00354     cms_uint32_t tib = 0;
00355 
00356     // return 0 if BST message too small
00357     int bstSize = m_bst.size();
00358     if (TotalIntensityBeam1LastBlock >= bstSize) {
00359         return tib;
00360     }
00361 
00362     for (int iB = TotalIntensityBeam1FirstBlock; iB <= TotalIntensityBeam1LastBlock; ++iB) {
00363 
00364         // keep capitalization for similarity with other functions
00365         const int scaledIB = iB - TotalIntensityBeam1FirstBlock;
00366         const int BstShift = BstBitSize*scaledIB;
00367 
00368         tib = tib |
00369               ( (static_cast<cms_uint32_t> (m_bst[iB])) << BstShift );
00370 
00371     }
00372 
00373     return tib;
00374 }
00375 
00376 const cms_uint32_t L1GtfeExtWord::totalIntensityBeam2() const
00377 {
00378 
00379     cms_uint32_t tib = 0;
00380 
00381     // return 0 if BST message too small
00382     int bstSize = m_bst.size();
00383     if (TotalIntensityBeam2LastBlock >= bstSize) {
00384         return tib;
00385     }
00386 
00387     for (int iB = TotalIntensityBeam2FirstBlock; iB <= TotalIntensityBeam2LastBlock; ++iB) {
00388 
00389         // keep capitalization for similarity with other functions
00390         const int scaledIB = iB - TotalIntensityBeam2FirstBlock;
00391         const int BstShift = BstBitSize*scaledIB;
00392 
00393         tib = tib |
00394               ( (static_cast<cms_uint32_t> (m_bst[iB])) << BstShift );
00395 
00396     }
00397 
00398     return tib;
00399 }
00400 
00401 
00402 // get/set BST for block iB
00403 const uint16_t L1GtfeExtWord::bst(int iB) const
00404 {
00405 
00406     int NumberBstBlocks = m_bst.size();
00407 
00408     if (iB < 0 || iB >= NumberBstBlocks) {
00409         throw cms::Exception("BstIndexError")
00410         << "\nError: index for BST array out of range. Allowed range: [0, "
00411         << NumberBstBlocks << ") " << std::endl;
00412 
00413     } else {
00414         return m_bst[iB];
00415     }
00416 
00417 }
00418 
00419 void L1GtfeExtWord::setBst(const uint16_t bstVal, const int iB)
00420 {
00421 
00422     int NumberBstBlocks = m_bst.size();
00423 
00424     if (iB < 0 || iB >= NumberBstBlocks) {
00425         throw cms::Exception("BstIndexError")
00426         << "\nError: index for BST array out of range. Allowed range: [0, "
00427         << NumberBstBlocks << ") " << std::endl;
00428 
00429     } else {
00430         m_bst[iB] = bstVal;
00431     }
00432 
00433 }
00434 
00435 // set the BST block for index iB from a 64-bits word
00436 void L1GtfeExtWord::setBst(const cms_uint64_t& word64, const int iB)
00437 {
00438 
00439     // keep capitalization for similarity with other functions //FIXME check it again
00440     const int scaledIB = iB%(sizeof(word64)*8/BstBitSize);
00441     const int BstShift = BstBitSize*scaledIB;
00442     const cms_uint64_t BstMask = 0x0000000000000000ULL | (BstBlockMask << BstShift);
00443 
00444     m_bst[iB] = static_cast<cms_uint16_t> ((word64 & BstMask) >> BstShift);
00445 
00446 }
00447 
00448 // set the BST block in a 64-bits word, having the index iWord
00449 // in the GTFE raw record
00450 void L1GtfeExtWord::setBstWord64(cms_uint64_t& word64, int iB, int iWord)
00451 {
00452 
00453     // keep capitalization for similarity with other functions
00454     const int scaledIB = iB%(sizeof(word64)*8/BstBitSize);
00455     const int BstShift = BstBitSize*scaledIB;
00456     const int BstWord = iB/(sizeof(word64)*8/BstBitSize) + BstFirstWord;
00457 
00458     if (iWord == BstWord) {
00459         word64 = word64 |
00460                  (static_cast<cms_uint64_t> (m_bst[iB]) << BstShift);
00461     }
00462 
00463 
00464 }
00465 
00466 
00467 // set the hex message indicating the source of BST message from a 64-bits word
00468 void L1GtfeExtWord::setBstSource(const cms_uint64_t& word64) {
00469 
00470     m_bstSource = (word64 & BstSourceMask) >> BstSourceShift;
00471 
00472 }
00473 
00474 // set hex message indicating the source of BST message in a 64-bits word,
00475 // having the index iWord in the GTFE raw record
00476 void L1GtfeExtWord::setBstSourceWord64(cms_uint64_t& word64, const int iWord) {
00477 
00478     // BST always in the last word of GTFE extended - size must be correct!
00479     int gtfeSize = this->getSize();
00480 
00481     int BstSourceWord = gtfeSize/8 - 1; // counting starts at 0
00482 
00483     if (iWord == BstSourceWord) {
00484         word64 = word64 | (static_cast<cms_uint64_t> (m_bstSource)
00485                            << BstSourceShift);
00486     }
00487 
00488 }
00489 
00490 
00491 // get the size of the GTFE block in GT EVM record (in multiple of 8 bits)
00492 const unsigned int L1GtfeExtWord::getSize() const {
00493 
00494     L1GtfeWord gtfeWord;
00495     unsigned int gtfeSize = gtfeWord.getSize();
00496 
00497     unsigned int gtfeExtSize;
00498 
00499     // 2 bytes to write if real BST message or simulated BST message
00500     unsigned int bytesBstWriter = 2;
00501 
00502     // size of BST block, using rounded 64-bit words (8 bytes per 64-bit word)
00503 
00504     unsigned int bstSize = m_bst.size();
00505 
00506     if ( (bstSize +bytesBstWriter )%8 == 0) {
00507         gtfeExtSize = gtfeSize + bstSize + bytesBstWriter;
00508     }
00509     else {
00510         gtfeExtSize = gtfeSize + bstSize + bytesBstWriter + (8 - (bstSize + bytesBstWriter)%8 );
00511     }
00512 
00513     return gtfeExtSize;
00514 }
00515 
00516 
00517 
00518 // resize the BST vector to get the right size of the block
00519 void L1GtfeExtWord::resize(int bstSizeBytes) {
00520 
00521     m_bst.resize(bstSizeBytes);
00522 
00523 }
00524 
00525 // reset the content of a L1GtfeExtWord
00526 void L1GtfeExtWord::reset()
00527 {
00528 
00529     L1GtfeWord::reset();
00530     m_bst.clear();
00531 
00532 }
00533 
00534 // pretty print the content of a L1GtfeWord
00535 void L1GtfeExtWord::print(std::ostream& myCout) const {
00536 
00537     myCout << "\n L1GtfeExtWord::print \n" << std::endl;
00538 
00539     unsigned int sizeW64 = 64;
00540     unsigned int dataBlocksPerLine = sizeW64 / 8; // 8x8 bits per line
00541 
00542     L1GtfeWord::print(myCout);
00543 
00544     unsigned int numberBstBlocks = m_bst.size();
00545 
00546     myCout << "\n  BST ";
00547 
00548     if (numberBstBlocks == 0) {
00549 
00550         myCout << "\n  BST source [hex]: " << std::hex << std::setw(4)
00551                 << std::setfill('0') << m_bstSource << std::setfill(' ')
00552                 << std::dec << std::endl;
00553 
00554         return;
00555     }
00556 
00557     for (unsigned int iB = 0; iB < numberBstBlocks; iB += dataBlocksPerLine) {
00558 
00559         myCout << "\n" << std::hex << " hex: ";
00560 
00561         for (unsigned int jB = iB; jB < dataBlocksPerLine + iB; ++jB) {
00562 
00563             if (jB >= numberBstBlocks) {
00564                 break;
00565             }
00566 
00567             myCout << std::setw(2) << std::setfill('0') << m_bst[jB] << "   "
00568                     << std::setfill(' ');
00569         }
00570 
00571         myCout << "\n" << std::dec << " dec: ";
00572 
00573         for (unsigned int jB = iB; jB < dataBlocksPerLine + iB; ++jB) {
00574 
00575             if (jB >= numberBstBlocks) {
00576                 break;
00577             }
00578 
00579             myCout << std::setw(3) << std::setfill('0') << m_bst[jB] << "  "
00580                     << std::setfill(' ');
00581         }
00582 
00583         myCout << std::endl;
00584 
00585     }
00586 
00587     myCout << "\n  BST source [hex]: " << std::hex << std::setw(4)
00588             << std::setfill('0') << m_bstSource << std::setfill(' ')
00589             << std::dec << std::endl;
00590 
00591 }
00592 
00593 void L1GtfeExtWord::unpack(const unsigned char* gtfePtr)
00594 {
00595     LogDebug("L1GtfeExtWord")
00596     << "\nUnpacking GTFE block.\n"
00597     << std::endl;
00598 
00599     L1GtfeWord::unpack(gtfePtr);
00600 
00601     // TODO make BlockSize protected & use friends instead of creating L1GtfeWord?
00602     L1GtfeWord gtfeWord;
00603     const unsigned char* gtfeExtPtr = gtfePtr + gtfeWord.getSize();
00604 
00605     const cms_uint64_t* payload =
00606         reinterpret_cast<cms_uint64_t*>(const_cast<unsigned char*>(gtfeExtPtr));
00607 
00608     int BlockSizeExt = this->getSize()/8;
00609     int NumberBstBlocks = m_bst.size();
00610 
00611     if (edm::isDebugEnabled() ) {
00612 
00613         for (int iWord = BstFirstWord; iWord < BlockSizeExt; ++iWord) {
00614 
00615             int jWord = iWord - BstFirstWord;
00616             LogTrace("L1GtfeExtWord")
00617             << std::setw(4) << iWord << "  "
00618             << std::hex << std::setfill('0')
00619             << std::setw(16) << payload[jWord]
00620             << std::dec << std::setfill(' ')
00621             << std::endl;
00622 
00623         }
00624     }
00625 
00626     int blocksPerWord = sizeof(cms_uint64_t)*8/BstBitSize;
00627 
00628     for (int iB = 0; iB < NumberBstBlocks; ++iB) {
00629 
00630         // keep capitalization for similarity with other functions
00631         int BstWord = iB/blocksPerWord;
00632 
00633         setBst(payload[BstWord], iB);
00634 
00635     }
00636 
00637 }
00638 
00639 
00640 
00641 
00642 // static class members
00643 
00644 // block description in the raw GT record
00645 
00646 // index of first word for BST blocks
00647 const int L1GtfeExtWord::BstFirstWord = 2;
00648 
00649 // size in bits for a BST block
00650 const int L1GtfeExtWord::BstBitSize = 8;
00651 
00652 // BST block mask, correlated with the number of bits of a block
00653 // 8 bit = 0xFF
00654 const cms_uint64_t L1GtfeExtWord::BstBlockMask = 0xFFULL;
00655 
00656 // BST blocks: conversion to defined quantities (LHC-BOB-ES-0001)
00657 
00658 const int L1GtfeExtWord::GpsTimeFirstBlock = 0;
00659 const int L1GtfeExtWord::GpsTimeLastBlock = 7;
00660 
00661 const int L1GtfeExtWord::BstMasterStatusFirstBlock = 17;
00662 const int L1GtfeExtWord::BstMasterStatusLastBlock =  17;
00663 
00664 const int L1GtfeExtWord::TurnCountNumberFirstBlock = 18;
00665 const int L1GtfeExtWord::TurnCountNumberLastBlock = 21;
00666 
00667 const int L1GtfeExtWord::LhcFillNumberFirstBlock = 22;
00668 const int L1GtfeExtWord::LhcFillNumberLastBlock = 25;
00669 
00670 const int L1GtfeExtWord::BeamModeFirstBlock = 26;
00671 const int L1GtfeExtWord::BeamModeLastBlock = 27;
00672 
00673 const int L1GtfeExtWord::ParticleTypeBeam1FirstBlock = 28;
00674 const int L1GtfeExtWord::ParticleTypeBeam1LastBlock = 28;
00675 
00676 const int L1GtfeExtWord::ParticleTypeBeam2FirstBlock = 29;
00677 const int L1GtfeExtWord::ParticleTypeBeam2LastBlock = 29;
00678 
00679 const int L1GtfeExtWord::BeamMomentumFirstBlock = 30;
00680 const int L1GtfeExtWord::BeamMomentumLastBlock = 31;
00681 
00682 const int L1GtfeExtWord::TotalIntensityBeam1FirstBlock = 32;
00683 const int L1GtfeExtWord::TotalIntensityBeam1LastBlock = 35;
00684 
00685 const int L1GtfeExtWord::TotalIntensityBeam2FirstBlock = 36;
00686 const int L1GtfeExtWord::TotalIntensityBeam2LastBlock = 39;
00687 
00688 // BST
00689 const cms_uint64_t L1GtfeExtWord::BstSourceMask = 0xFFFF000000000000ULL;
00690 const int L1GtfeExtWord::BstSourceShift = 48;
00691 
00692 
00693