CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/EventFilter/GctRawToDigi/src/GctFormatTranslateV38.cc

Go to the documentation of this file.
00001 #include "EventFilter/GctRawToDigi/src/GctFormatTranslateV38.h"
00002 
00003 // C++ headers
00004 #include <iostream>
00005 #include <cassert>
00006 #include <algorithm>
00007 #include <cmath>
00008 
00009 // Framework headers
00010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00011 
00012 // Namespace resolution
00013 using std::cout;
00014 using std::endl;
00015 using std::pair;
00016 using std::make_pair;
00017 
00018 // INITIALISE STATIC VARIABLES
00019 GctFormatTranslateV38::BlockLengthMap GctFormatTranslateV38::m_blockLength = GctFormatTranslateV38::BlockLengthMap();
00020 GctFormatTranslateV38::BlockNameMap GctFormatTranslateV38::m_blockName = GctFormatTranslateV38::BlockNameMap();
00021 GctFormatTranslateV38::BlockIdToUnpackFnMap GctFormatTranslateV38::m_blockUnpackFn = GctFormatTranslateV38::BlockIdToUnpackFnMap();
00022 GctFormatTranslateV38::BlkToRctCrateMap GctFormatTranslateV38::m_rctEmCrate = GctFormatTranslateV38::BlkToRctCrateMap();
00023 GctFormatTranslateV38::BlkToRctCrateMap GctFormatTranslateV38::m_rctJetCrate = GctFormatTranslateV38::BlkToRctCrateMap();
00024 GctFormatTranslateV38::BlockIdToEmCandIsoBoundMap GctFormatTranslateV38::m_internEmIsoBounds = GctFormatTranslateV38::BlockIdToEmCandIsoBoundMap();
00025 
00026 
00027 // PUBLIC METHODS
00028 
00029 GctFormatTranslateV38::GctFormatTranslateV38(bool hltMode, bool unpackSharedRegions, 
00030                                              unsigned numberOfGctSamplesToUnpack, 
00031                                              unsigned numberOfRctSamplesToUnpack):
00032   GctFormatTranslateBase(hltMode, unpackSharedRegions),
00033   m_numberOfGctSamplesToUnpack(numberOfGctSamplesToUnpack),
00034   m_numberOfRctSamplesToUnpack(numberOfRctSamplesToUnpack)
00035 {
00036   static bool initClass = true;
00037 
00038   if(initClass)
00039   {
00040     initClass = false;
00041 
00042     /*** Setup BlockID to BlockLength Map ***/
00043     // Miscellaneous Blocks
00044     m_blockLength.insert(make_pair(0x000,0));      // NULL
00045     // ConcJet FPGA
00046     m_blockLength.insert(make_pair(0x580,12));     // ConcJet: Input TrigPathA (Jet Cands)
00047     m_blockLength.insert(make_pair(0x581,2));      // ConcJet: Input TrigPathB (HF Rings)
00048     m_blockLength.insert(make_pair(0x582,4));      // ConcJet: Input TrigPathC (MissHt)
00049     m_blockLength.insert(make_pair(0x583,8));      // ConcJet: Jet Cands and Counts Output to GT
00050     m_blockLength.insert(make_pair(0x587,4));      // ConcJet: BX & Orbit Info
00051     // ConcElec FPGA
00052     m_blockLength.insert(make_pair(0x680,16));     // ConcElec: Input TrigPathA (EM Cands)
00053     m_blockLength.insert(make_pair(0x681,6));      // ConcElec: Input TrigPathB (Et Sums)
00054     m_blockLength.insert(make_pair(0x682,2));      // ConcElec: Input TrigPathC (Ht Sums)
00055     m_blockLength.insert(make_pair(0x683,6));      // ConcElec: EM Cands and Energy Sums Output to GT
00056     m_blockLength.insert(make_pair(0x686,2));      // ConcElec: Test (GT Serdes Loopback)
00057     m_blockLength.insert(make_pair(0x687,4));      // ConcElec: BX & Orbit Info
00058     // Electron Leaf FPGAs
00059     m_blockLength.insert(make_pair(0x800,20));     // Leaf0ElecPosEtaU1: Sort Input
00060     m_blockLength.insert(make_pair(0x803,4));      // Leaf0ElecPosEtaU1: Sort Output
00061     m_blockLength.insert(make_pair(0x804,15));     // Leaf0ElecPosEtaU1: Raw Input
00062     m_blockLength.insert(make_pair(0x880,16));     // Leaf0ElecPosEtaU2: Sort Input
00063     m_blockLength.insert(make_pair(0x883,4));      // Leaf0ElecPosEtaU2: Sort Output
00064     m_blockLength.insert(make_pair(0x884,12));     // Leaf0ElecPosEtaU2: Raw Input
00065     m_blockLength.insert(make_pair(0xc00,20));     // Leaf0ElecNegEtaU1: Sort Input
00066     m_blockLength.insert(make_pair(0xc03,4));      // Leaf0ElecNegEtaU1: Sort Output
00067     m_blockLength.insert(make_pair(0xc04,15));     // Leaf0ElecNegEtaU1: Raw Input
00068     m_blockLength.insert(make_pair(0xc80,16));     // Leaf0ElecNegEtaU2: Sort Input
00069     m_blockLength.insert(make_pair(0xc83,4));      // Leaf0ElecNegEtaU2: Sort Output
00070     m_blockLength.insert(make_pair(0xc84,12));     // Leaf0ElecNegEtaU2: Raw Input
00071     // Wheel Pos-eta Jet FPGA
00072     m_blockLength.insert(make_pair(0x300,27));     // WheelPosEtaJet: Input TrigPathA (Jet Sort)
00073     m_blockLength.insert(make_pair(0x301,3));      // WheelPosEtaJet: Input TrigPathB (MissHt)
00074     m_blockLength.insert(make_pair(0x303,6));      // WheelPosEtaJet: Output TrigPathA (Jet Sort)
00075     m_blockLength.insert(make_pair(0x305,2));      // WheelPosEtaJet: Output TrigPathB (MissHt)
00076     m_blockLength.insert(make_pair(0x306,32));     // WheelPosEtaJet: Test (deprecated)  (Doesn't exist in V27.1 format, but does in V24 & V25, so keep for CRUZET2 data compatibility reasons)
00077     m_blockLength.insert(make_pair(0x307,4));      // WheelPosEtaJet: Info (deprecated)  (Doesn't exist in V27.1 format, but does in V24 & V25, so keep for CRUZET2 data compatibility reasons)
00078     // Wheel Pos-eta Energy FPGA
00079     m_blockLength.insert(make_pair(0x380,21));     // WheelPosEtaEnergy: Input TrigPathA (Et)
00080     m_blockLength.insert(make_pair(0x381,6));      // WheelPosEtaEnergy: Input TrigPathB (Ht)
00081     m_blockLength.insert(make_pair(0x383,7));      // WheelPosEtaEnergy: Output TrigPathA (Et)
00082     m_blockLength.insert(make_pair(0x385,2));      // WheelPosEtaEnergy: Output TrigPathB (Ht)
00083     m_blockLength.insert(make_pair(0x386,32));     // WheelPosEtaEnergy: Test
00084     m_blockLength.insert(make_pair(0x387,6));      // WheelPosEtaEnergy: BX & Orbit Info   (Potential data incompatibility between V24/V25 where block length=4, and V27.1 where block length=6)
00085     // Wheel Neg-eta Jet FPGA
00086     m_blockLength.insert(make_pair(0x700,27));     // WheelNegEtaJet: Input TrigPathA (Jet Sort)
00087     m_blockLength.insert(make_pair(0x701,3));      // WheelNegEtaJet: Input TrigPathB (MissHt)
00088     m_blockLength.insert(make_pair(0x703,6));      // WheelNegEtaJet: Output TrigPathA (Jet Sort)
00089     m_blockLength.insert(make_pair(0x705,2));      // WheelNegEtaJet: Output TrigPathB (MissHt)
00090     m_blockLength.insert(make_pair(0x706,32));     // WheelNegEtaJet: Test (deprecated)  (Doesn't exist in V27.1 format, but does in V24 & V25, so keep for CRUZET2 data compatibility reasons)
00091     m_blockLength.insert(make_pair(0x707,4));      // WheelNegEtaJet: Info (deprecated)  (Doesn't exist in V27.1 format, but does in V24 & V25, so keep for CRUZET2 data compatibility reasons)
00092     // Wheel Neg-eta Energy FPGA
00093     m_blockLength.insert(make_pair(0x780,21));     // WheelNegEtaEnergy: Input TrigPathA (Et)
00094     m_blockLength.insert(make_pair(0x781,6));      // WheelNegEtaEnergy: Input TrigPathB (Ht)
00095     m_blockLength.insert(make_pair(0x783,7));      // WheelNegEtaEnergy: Output TrigPathA (Et)
00096     m_blockLength.insert(make_pair(0x785,2));      // WheelNegEtaEnergy: Output TrigPathB (Ht)
00097     m_blockLength.insert(make_pair(0x786,32));     // WheelNegEtaEnergy: Test
00098     m_blockLength.insert(make_pair(0x787,6));      // WheelNegEtaEnergy: BX & Orbit Info   (Potential data incompatibility between V24/V25 where block length=4, and V27.1 where block length=6)
00099     // Jet Leaf FPGAs - Positive Eta 
00100     m_blockLength.insert(make_pair(0x900,13));     // Leaf1JetPosEtaU1: JF2 Input
00101     m_blockLength.insert(make_pair(0x901,3));      // Leaf1JetPosEtaU1: JF2 Shared Received
00102     m_blockLength.insert(make_pair(0x902,3));      // Leaf1JetPosEtaU1: JF2 Shared Sent
00103     m_blockLength.insert(make_pair(0x903,10));     // Leaf1JetPosEtaU1: JF2 Output
00104     m_blockLength.insert(make_pair(0x904,8));      // Leaf1JetPosEtaU1: JF2 Raw Input
00105     m_blockLength.insert(make_pair(0x908,13));     // Leaf1JetPosEtaU1: JF3 Input
00106     m_blockLength.insert(make_pair(0x909,3));      // Leaf1JetPosEtaU1: JF3 Shared Received
00107     m_blockLength.insert(make_pair(0x90a,3));      // Leaf1JetPosEtaU1: JF3 Shared Sent
00108     m_blockLength.insert(make_pair(0x90b,10));     // Leaf1JetPosEtaU1: JF3 Output
00109     m_blockLength.insert(make_pair(0x90c,8));      // Leaf1JetPosEtaU1: JF3 Raw Input
00110     m_blockLength.insert(make_pair(0x980,6));      // Leaf1JetPosEtaU2: Eta0 Input
00111     m_blockLength.insert(make_pair(0x984,6));      // Leaf1JetPosEtaU2: Eta0 Raw Input
00112     m_blockLength.insert(make_pair(0x988,13));     // Leaf1JetPosEtaU2: JF1 Input
00113     m_blockLength.insert(make_pair(0x989,3));      // Leaf1JetPosEtaU2: JF1 Shared Received
00114     m_blockLength.insert(make_pair(0x98a,3));      // Leaf1JetPosEtaU2: JF1 Shared Sent
00115     m_blockLength.insert(make_pair(0x98b,10));     // Leaf1JetPosEtaU2: JF1 Output
00116     m_blockLength.insert(make_pair(0x98c,8));      // Leaf1JetPosEtaU2: JF1 Raw Input
00117     m_blockLength.insert(make_pair(0xa00,13));     // Leaf2JetPosEtaU1: JF2 Input
00118     m_blockLength.insert(make_pair(0xa01,3));      // Leaf2JetPosEtaU1: JF2 Shared Received
00119     m_blockLength.insert(make_pair(0xa02,3));      // Leaf2JetPosEtaU1: JF2 Shared Sent
00120     m_blockLength.insert(make_pair(0xa03,10));     // Leaf2JetPosEtaU1: JF2 Output
00121     m_blockLength.insert(make_pair(0xa04,8));      // Leaf2JetPosEtaU1: JF2 Raw Input
00122     m_blockLength.insert(make_pair(0xa08,13));     // Leaf2JetPosEtaU1: JF3 Input
00123     m_blockLength.insert(make_pair(0xa09,3));      // Leaf2JetPosEtaU1: JF3 Shared Received
00124     m_blockLength.insert(make_pair(0xa0a,3));      // Leaf2JetPosEtaU1: JF3 Shared Sent
00125     m_blockLength.insert(make_pair(0xa0b,10));     // Leaf2JetPosEtaU1: JF3 Output
00126     m_blockLength.insert(make_pair(0xa0c,8));      // Leaf2JetPosEtaU1: JF3 Raw Input
00127     m_blockLength.insert(make_pair(0xa80,6));      // Leaf2JetPosEtaU2: Eta0 Input
00128     m_blockLength.insert(make_pair(0xa84,6));      // Leaf2JetPosEtaU2: Eta0 Raw Input
00129     m_blockLength.insert(make_pair(0xa88,13));     // Leaf2JetPosEtaU2: JF1 Input
00130     m_blockLength.insert(make_pair(0xa89,3));      // Leaf2JetPosEtaU2: JF1 Shared Received
00131     m_blockLength.insert(make_pair(0xa8a,3));      // Leaf2JetPosEtaU2: JF1 Shared Sent
00132     m_blockLength.insert(make_pair(0xa8b,10));     // Leaf2JetPosEtaU2: JF1 Output
00133     m_blockLength.insert(make_pair(0xa8c,8));      // Leaf2JetPosEtaU2: JF1 Raw Input
00134     m_blockLength.insert(make_pair(0xb00,13));     // Leaf3JetPosEtaU1: JF2 Input
00135     m_blockLength.insert(make_pair(0xb01,3));      // Leaf3JetPosEtaU1: JF2 Shared Received
00136     m_blockLength.insert(make_pair(0xb02,3));      // Leaf3JetPosEtaU1: JF2 Shared Sent
00137     m_blockLength.insert(make_pair(0xb03,10));     // Leaf3JetPosEtaU1: JF2 Output
00138     m_blockLength.insert(make_pair(0xb04,8));      // Leaf3JetPosEtaU1: JF2 Raw Input
00139     m_blockLength.insert(make_pair(0xb08,13));     // Leaf3JetPosEtaU1: JF3 Input
00140     m_blockLength.insert(make_pair(0xb09,3));      // Leaf3JetPosEtaU1: JF3 Shared Received
00141     m_blockLength.insert(make_pair(0xb0a,3));      // Leaf3JetPosEtaU1: JF3 Shared Sent
00142     m_blockLength.insert(make_pair(0xb0b,10));     // Leaf3JetPosEtaU1: JF3 Output
00143     m_blockLength.insert(make_pair(0xb0c,8));      // Leaf3JetPosEtaU1: JF3 Raw Input
00144     m_blockLength.insert(make_pair(0xb80,6));      // Leaf3JetPosEtaU2: Eta0 Input
00145     m_blockLength.insert(make_pair(0xb84,6));      // Leaf3JetPosEtaU2: Eta0 Raw Input
00146     m_blockLength.insert(make_pair(0xb88,13));     // Leaf3JetPosEtaU2: JF1 Input
00147     m_blockLength.insert(make_pair(0xb89,3));      // Leaf3JetPosEtaU2: JF1 Shared Received
00148     m_blockLength.insert(make_pair(0xb8a,3));      // Leaf3JetPosEtaU2: JF1 Shared Sent
00149     m_blockLength.insert(make_pair(0xb8b,10));     // Leaf3JetPosEtaU2: JF1 Output
00150     m_blockLength.insert(make_pair(0xb8c,8));      // Leaf3JetPosEtaU2: JF1 Raw Input
00151     // Jet Leaf FPGAs - Negative Eta 
00152     m_blockLength.insert(make_pair(0xd00,13));     // Leaf1JetNegEtaU1: JF2 Input
00153     m_blockLength.insert(make_pair(0xd01,3));      // Leaf1JetNegEtaU1: JF2 Shared Received
00154     m_blockLength.insert(make_pair(0xd02,3));      // Leaf1JetNegEtaU1: JF2 Shared Sent
00155     m_blockLength.insert(make_pair(0xd03,10));     // Leaf1JetNegEtaU1: JF2 Output
00156     m_blockLength.insert(make_pair(0xd04,8));      // Leaf1JetNegEtaU1: JF2 Raw Input
00157     m_blockLength.insert(make_pair(0xd08,13));     // Leaf1JetNegEtaU1: JF3 Input
00158     m_blockLength.insert(make_pair(0xd09,3));      // Leaf1JetNegEtaU1: JF3 Shared Received
00159     m_blockLength.insert(make_pair(0xd0a,3));      // Leaf1JetNegEtaU1: JF3 Shared Sent
00160     m_blockLength.insert(make_pair(0xd0b,10));     // Leaf1JetNegEtaU1: JF3 Output
00161     m_blockLength.insert(make_pair(0xd0c,8));      // Leaf1JetNegEtaU1: JF3 Raw Input
00162     m_blockLength.insert(make_pair(0xd80,6));      // Leaf1JetNegEtaU2: Eta0 Input
00163     m_blockLength.insert(make_pair(0xd84,6));      // Leaf1JetNegEtaU2: Eta0 Raw Input
00164     m_blockLength.insert(make_pair(0xd88,13));     // Leaf1JetNegEtaU2: JF1 Input
00165     m_blockLength.insert(make_pair(0xd89,3));      // Leaf1JetNegEtaU2: JF1 Shared Received
00166     m_blockLength.insert(make_pair(0xd8a,3));      // Leaf1JetNegEtaU2: JF1 Shared Sent
00167     m_blockLength.insert(make_pair(0xd8b,10));     // Leaf1JetNegEtaU2: JF1 Output
00168     m_blockLength.insert(make_pair(0xd8c,8));      // Leaf1JetNegEtaU2: JF1 Raw Input
00169     m_blockLength.insert(make_pair(0xe00,13));     // Leaf2JetNegEtaU1: JF2 Input
00170     m_blockLength.insert(make_pair(0xe01,3));      // Leaf2JetNegEtaU1: JF2 Shared Received
00171     m_blockLength.insert(make_pair(0xe02,3));      // Leaf2JetNegEtaU1: JF2 Shared Sent
00172     m_blockLength.insert(make_pair(0xe03,10));     // Leaf2JetNegEtaU1: JF2 Output
00173     m_blockLength.insert(make_pair(0xe04,8));      // Leaf2JetNegEtaU1: JF2 Raw Input
00174     m_blockLength.insert(make_pair(0xe08,13));     // Leaf2JetNegEtaU1: JF3 Input
00175     m_blockLength.insert(make_pair(0xe09,3));      // Leaf2JetNegEtaU1: JF3 Shared Received
00176     m_blockLength.insert(make_pair(0xe0a,3));      // Leaf2JetNegEtaU1: JF3 Shared Sent
00177     m_blockLength.insert(make_pair(0xe0b,10));     // Leaf2JetNegEtaU1: JF3 Output
00178     m_blockLength.insert(make_pair(0xe0c,8));      // Leaf2JetNegEtaU1: JF3 Raw Input
00179     m_blockLength.insert(make_pair(0xe80,6));      // Leaf2JetNegEtaU2: Eta0 Input
00180     m_blockLength.insert(make_pair(0xe84,6));      // Leaf2JetNegEtaU2: Eta0 Raw Input
00181     m_blockLength.insert(make_pair(0xe88,13));     // Leaf2JetNegEtaU2: JF1 Input
00182     m_blockLength.insert(make_pair(0xe89,3));      // Leaf2JetNegEtaU2: JF1 Shared Received
00183     m_blockLength.insert(make_pair(0xe8a,3));      // Leaf2JetNegEtaU2: JF1 Shared Sent
00184     m_blockLength.insert(make_pair(0xe8b,10));     // Leaf2JetNegEtaU2: JF1 Output
00185     m_blockLength.insert(make_pair(0xe8c,8));      // Leaf2JetNegEtaU2: JF1 Raw Input
00186     m_blockLength.insert(make_pair(0xf00,13));     // Leaf3JetNegEtaU1: JF2 Input
00187     m_blockLength.insert(make_pair(0xf01,3));      // Leaf3JetNegEtaU1: JF2 Shared Received
00188     m_blockLength.insert(make_pair(0xf02,3));      // Leaf3JetNegEtaU1: JF2 Shared Sent
00189     m_blockLength.insert(make_pair(0xf03,10));     // Leaf3JetNegEtaU1: JF2 Output
00190     m_blockLength.insert(make_pair(0xf04,8));      // Leaf3JetNegEtaU1: JF2 Raw Input
00191     m_blockLength.insert(make_pair(0xf08,13));     // Leaf3JetNegEtaU1: JF3 Input
00192     m_blockLength.insert(make_pair(0xf09,3));      // Leaf3JetNegEtaU1: JF3 Shared Received
00193     m_blockLength.insert(make_pair(0xf0a,3));      // Leaf3JetNegEtaU1: JF3 Shared Sent
00194     m_blockLength.insert(make_pair(0xf0b,10));     // Leaf3JetNegEtaU1: JF3 Output
00195     m_blockLength.insert(make_pair(0xf0c,8));      // Leaf3JetNegEtaU1: JF3 Raw Input
00196     m_blockLength.insert(make_pair(0xf80,6));      // Leaf3JetNegEtaU2: Eta0 Input
00197     m_blockLength.insert(make_pair(0xf84,6));      // Leaf3JetNegEtaU2: Eta0 Raw Input
00198     m_blockLength.insert(make_pair(0xf88,13));     // Leaf3JetNegEtaU2: JF1 Input    
00199     m_blockLength.insert(make_pair(0xf89,3));      // Leaf3JetNegEtaU2: JF1 Shared Received
00200     m_blockLength.insert(make_pair(0xf8a,3));      // Leaf3JetNegEtaU2: JF1 Shared Sent
00201     m_blockLength.insert(make_pair(0xf8b,10));     // Leaf3JetNegEtaU2: JF1 Output
00202     m_blockLength.insert(make_pair(0xf8c,8));      // Leaf3JetNegEtaU2: JF1 Raw Input
00203 
00204 
00205     /*** Setup BlockID to BlockName Map ***/
00206     // Miscellaneous Blocks
00207     m_blockName.insert(make_pair(0x000,"NULL"));
00208     // ConcJet FPGA
00209     m_blockName.insert(make_pair(0x580,"ConcJet: Input TrigPathA (Jet Cands)"));
00210     m_blockName.insert(make_pair(0x581,"ConcJet: Input TrigPathB (HF Rings)"));
00211     m_blockName.insert(make_pair(0x582,"ConcJet: Input TrigPathC (MissHt)"));
00212     m_blockName.insert(make_pair(0x583,"ConcJet: Jet Cands and Counts Output to GT"));
00213     m_blockName.insert(make_pair(0x587,"ConcJet: BX & Orbit Info"));
00214     // ConcElec FPGA
00215     m_blockName.insert(make_pair(0x680,"ConcElec: Input TrigPathA (EM Cands)"));
00216     m_blockName.insert(make_pair(0x681,"ConcElec: Input TrigPathB (Et Sums)"));
00217     m_blockName.insert(make_pair(0x682,"ConcElec: Input TrigPathC (Ht Sums)"));
00218     m_blockName.insert(make_pair(0x683,"ConcElec: EM Cands and Energy Sums Output to GT"));
00219     m_blockName.insert(make_pair(0x686,"ConcElec: Test (GT Serdes Loopback)"));
00220     m_blockName.insert(make_pair(0x687,"ConcElec: BX & Orbit Info"));
00221     // Electron Leaf FPGAs
00222     m_blockName.insert(make_pair(0x800,"Leaf0ElecPosEtaU1: Sort Input"));
00223     m_blockName.insert(make_pair(0x803,"Leaf0ElecPosEtaU1: Sort Output"));
00224     m_blockName.insert(make_pair(0x804,"Leaf0ElecPosEtaU1: Raw Input"));
00225     m_blockName.insert(make_pair(0x880,"Leaf0ElecPosEtaU2: Sort Input"));
00226     m_blockName.insert(make_pair(0x883,"Leaf0ElecPosEtaU2: Sort Output"));
00227     m_blockName.insert(make_pair(0x884,"Leaf0ElecPosEtaU2: Raw Input"));
00228     m_blockName.insert(make_pair(0xc00,"Leaf0ElecNegEtaU1: Sort Input"));
00229     m_blockName.insert(make_pair(0xc03,"Leaf0ElecNegEtaU1: Sort Output"));
00230     m_blockName.insert(make_pair(0xc04,"Leaf0ElecNegEtaU1: Raw Input"));
00231     m_blockName.insert(make_pair(0xc80,"Leaf0ElecNegEtaU2: Sort Input"));
00232     m_blockName.insert(make_pair(0xc83,"Leaf0ElecNegEtaU2: Sort Output"));
00233     m_blockName.insert(make_pair(0xc84,"Leaf0ElecNegEtaU2: Raw Input"));
00234     // Wheel Pos-eta Jet FPGA
00235     m_blockName.insert(make_pair(0x300,"WheelPosEtaJet: Input TrigPathA (Jet Sort)"));
00236     m_blockName.insert(make_pair(0x301,"WheelPosEtaJet: Input TrigPathB (MissHt)"));  
00237     m_blockName.insert(make_pair(0x303,"WheelPosEtaJet: Output TrigPathA (Jet Sort)"));
00238     m_blockName.insert(make_pair(0x305,"WheelPosEtaJet: Output TrigPathB (MissHt)"));
00239     m_blockName.insert(make_pair(0x306,"WheelPosEtaJet: Test (deprecated)"));  // (Doesn't exist in V27.1 format, but does in V24 & V25, so keep for CRUZET2 data compatibility reasons)
00240     m_blockName.insert(make_pair(0x307,"WheelPosEtaJet: Info (deprecated)"));  // (Doesn't exist in V27.1 format, but does in V24 & V25, so keep for CRUZET2 data compatibility reasons)
00241     // Wheel Pos-eta Energy FPGA
00242     m_blockName.insert(make_pair(0x380,"WheelPosEtaEnergy: Input TrigPathA (Et)"));
00243     m_blockName.insert(make_pair(0x381,"WheelPosEtaEnergy: Input TrigPathB (Ht)"));
00244     m_blockName.insert(make_pair(0x383,"WheelPosEtaEnergy: Output TrigPathA (Et)"));
00245     m_blockName.insert(make_pair(0x385,"WheelPosEtaEnergy: Output TrigPathB (Ht)"));
00246     m_blockName.insert(make_pair(0x386,"WheelPosEtaEnergy: Test"));
00247     m_blockName.insert(make_pair(0x387,"WheelPosEtaEnergy: BX & Orbit Info"));
00248     // Wheel Neg-eta Jet FPGA
00249     m_blockName.insert(make_pair(0x700,"WheelNegEtaJet: Input TrigPathA (Jet Sort)"));
00250     m_blockName.insert(make_pair(0x701,"WheelNegEtaJet: Input TrigPathB (MissHt)"));
00251     m_blockName.insert(make_pair(0x703,"WheelNegEtaJet: Output TrigPathA (Jet Sort)"));
00252     m_blockName.insert(make_pair(0x705,"WheelNegEtaJet: Output TrigPathB (MissHt)"));
00253     m_blockName.insert(make_pair(0x706,"WheelNegEtaJet: Test (deprecated)"));  // (Doesn't exist in V27.1 format, but does in V24 & V25, so keep for CRUZET2 data compatibility reasons)
00254     m_blockName.insert(make_pair(0x707,"WheelNegEtaJet: Info (deprecated)"));  // (Doesn't exist in V27.1 format, but does in V24 & V25, so keep for CRUZET2 data compatibility reasons)
00255     // Wheel Neg-eta Energy FPGA
00256     m_blockName.insert(make_pair(0x780,"WheelNegEtaEnergy: Input TrigPathA (Et)"));
00257     m_blockName.insert(make_pair(0x781,"WheelNegEtaEnergy: Input TrigPathB (Ht)"));
00258     m_blockName.insert(make_pair(0x783,"WheelNegEtaEnergy: Output TrigPathA (Et)"));
00259     m_blockName.insert(make_pair(0x785,"WheelNegEtaEnergy: Output TrigPathB (Ht)"));
00260     m_blockName.insert(make_pair(0x786,"WheelNegEtaEnergy: Test"));
00261     m_blockName.insert(make_pair(0x787,"WheelNegEtaEnergy: BX & Orbit Info"));
00262     // Jet Leaf FPGAs - Positive Eta
00263     m_blockName.insert(make_pair(0x900,"Leaf1JetPosEtaU1: JF2 Input"));
00264     m_blockName.insert(make_pair(0x901,"Leaf1JetPosEtaU1: JF2 Shared Received"));
00265     m_blockName.insert(make_pair(0x902,"Leaf1JetPosEtaU1: JF2 Shared Sent"));
00266     m_blockName.insert(make_pair(0x903,"Leaf1JetPosEtaU1: JF2 Output"));
00267     m_blockName.insert(make_pair(0x904,"Leaf1JetPosEtaU1: JF2 Raw Input"));
00268     m_blockName.insert(make_pair(0x908,"Leaf1JetPosEtaU1: JF3 Input"));
00269     m_blockName.insert(make_pair(0x909,"Leaf1JetPosEtaU1: JF3 Shared Received"));
00270     m_blockName.insert(make_pair(0x90a,"Leaf1JetPosEtaU1: JF3 Shared Sent"));
00271     m_blockName.insert(make_pair(0x90b,"Leaf1JetPosEtaU1: JF3 Output"));
00272     m_blockName.insert(make_pair(0x90c,"Leaf1JetPosEtaU1: JF3 Raw Input"));
00273     m_blockName.insert(make_pair(0x980,"Leaf1JetPosEtaU2: Eta0 Input"));  // Next Leaf Start
00274     m_blockName.insert(make_pair(0x984,"Leaf1JetPosEtaU2: Eta0 Raw Input"));
00275     m_blockName.insert(make_pair(0x988,"Leaf1JetPosEtaU2: JF1 Input"));
00276     m_blockName.insert(make_pair(0x989,"Leaf1JetPosEtaU2: JF1 Shared Received"));
00277     m_blockName.insert(make_pair(0x98a,"Leaf1JetPosEtaU2: JF1 Shared Sent"));
00278     m_blockName.insert(make_pair(0x98b,"Leaf1JetPosEtaU2: JF1 Output"));
00279     m_blockName.insert(make_pair(0x98c,"Leaf1JetPosEtaU2: JF1 Raw Input"));
00280     m_blockName.insert(make_pair(0xa00,"Leaf2JetPosEtaU1: JF2 Input"));  // Next Leaf Start
00281     m_blockName.insert(make_pair(0xa01,"Leaf2JetPosEtaU1: JF2 Shared Received"));
00282     m_blockName.insert(make_pair(0xa02,"Leaf2JetPosEtaU1: JF2 Shared Sent"));
00283     m_blockName.insert(make_pair(0xa03,"Leaf2JetPosEtaU1: JF2 Output"));
00284     m_blockName.insert(make_pair(0xa04,"Leaf2JetPosEtaU1: JF2 Raw Input"));
00285     m_blockName.insert(make_pair(0xa08,"Leaf2JetPosEtaU1: JF3 Input"));
00286     m_blockName.insert(make_pair(0xa09,"Leaf2JetPosEtaU1: JF3 Shared Received"));
00287     m_blockName.insert(make_pair(0xa0a,"Leaf2JetPosEtaU1: JF3 Shared Sent"));
00288     m_blockName.insert(make_pair(0xa0b,"Leaf2JetPosEtaU1: JF3 Output"));
00289     m_blockName.insert(make_pair(0xa0c,"Leaf2JetPosEtaU1: JF3 Raw Input"));
00290     m_blockName.insert(make_pair(0xa80,"Leaf2JetPosEtaU2: Eta0 Input"));  // Next Leaf Start
00291     m_blockName.insert(make_pair(0xa84,"Leaf2JetPosEtaU2: Eta0 Raw Input"));
00292     m_blockName.insert(make_pair(0xa88,"Leaf2JetPosEtaU2: JF1 Input"));
00293     m_blockName.insert(make_pair(0xa89,"Leaf2JetPosEtaU2: JF1 Shared Received"));
00294     m_blockName.insert(make_pair(0xa8a,"Leaf2JetPosEtaU2: JF1 Shared Sent"));
00295     m_blockName.insert(make_pair(0xa8b,"Leaf2JetPosEtaU2: JF1 Output"));
00296     m_blockName.insert(make_pair(0xa8c,"Leaf2JetPosEtaU2: JF1 Raw Input"));
00297     m_blockName.insert(make_pair(0xb00,"Leaf3JetPosEtaU1: JF2 Input"));  // Next Leaf Start
00298     m_blockName.insert(make_pair(0xb01,"Leaf3JetPosEtaU1: JF2 Shared Received"));
00299     m_blockName.insert(make_pair(0xb02,"Leaf3JetPosEtaU1: JF2 Shared Sent"));
00300     m_blockName.insert(make_pair(0xb03,"Leaf3JetPosEtaU1: JF2 Output"));
00301     m_blockName.insert(make_pair(0xb04,"Leaf3JetPosEtaU1: JF2 Raw Input"));
00302     m_blockName.insert(make_pair(0xb08,"Leaf3JetPosEtaU1: JF3 Input"));
00303     m_blockName.insert(make_pair(0xb09,"Leaf3JetPosEtaU1: JF3 Shared Received"));
00304     m_blockName.insert(make_pair(0xb0a,"Leaf3JetPosEtaU1: JF3 Shared Sent"));
00305     m_blockName.insert(make_pair(0xb0b,"Leaf3JetPosEtaU1: JF3 Output"));
00306     m_blockName.insert(make_pair(0xb0c,"Leaf3JetPosEtaU1: JF3 Raw Input"));
00307     m_blockName.insert(make_pair(0xb80,"Leaf3JetPosEtaU2: Eta0 Input"));  // Next Leaf Start
00308     m_blockName.insert(make_pair(0xb84,"Leaf3JetPosEtaU2: Eta0 Raw Input"));
00309     m_blockName.insert(make_pair(0xb88,"Leaf3JetPosEtaU2: JF1 Input"));
00310     m_blockName.insert(make_pair(0xb89,"Leaf3JetPosEtaU2: JF1 Shared Received"));
00311     m_blockName.insert(make_pair(0xb8a,"Leaf3JetPosEtaU2: JF1 Shared Sent"));
00312     m_blockName.insert(make_pair(0xb8b,"Leaf3JetPosEtaU2: JF1 Output"));
00313     m_blockName.insert(make_pair(0xb8c,"Leaf3JetPosEtaU2: JF1 Raw Input"));
00314     // Jet Leaf FPGAs - Negative Eta
00315     m_blockName.insert(make_pair(0xd00,"Leaf1JetNegEtaU1: JF2 Input"));       // START OF NEG ETA JET LEAVES
00316     m_blockName.insert(make_pair(0xd01,"Leaf1JetNegEtaU1: JF2 Shared Received"));
00317     m_blockName.insert(make_pair(0xd02,"Leaf1JetNegEtaU1: JF2 Shared Sent"));
00318     m_blockName.insert(make_pair(0xd03,"Leaf1JetNegEtaU1: JF2 Output"));
00319     m_blockName.insert(make_pair(0xd04,"Leaf1JetNegEtaU1: JF2 Raw Input"));
00320     m_blockName.insert(make_pair(0xd08,"Leaf1JetNegEtaU1: JF3 Input"));
00321     m_blockName.insert(make_pair(0xd09,"Leaf1JetNegEtaU1: JF3 Shared Received"));
00322     m_blockName.insert(make_pair(0xd0a,"Leaf1JetNegEtaU1: JF3 Shared Sent"));
00323     m_blockName.insert(make_pair(0xd0b,"Leaf1JetNegEtaU1: JF3 Output"));
00324     m_blockName.insert(make_pair(0xd0c,"Leaf1JetNegEtaU1: JF3 Raw Input"));
00325     m_blockName.insert(make_pair(0xd80,"Leaf1JetNegEtaU2: Eta0 Input"));  // Next Leaf Start
00326     m_blockName.insert(make_pair(0xd84,"Leaf1JetNegEtaU2: Eta0 Raw Input"));
00327     m_blockName.insert(make_pair(0xd88,"Leaf1JetNegEtaU2: JF1 Input"));
00328     m_blockName.insert(make_pair(0xd89,"Leaf1JetNegEtaU2: JF1 Shared Received"));
00329     m_blockName.insert(make_pair(0xd8a,"Leaf1JetNegEtaU2: JF1 Shared Sent"));
00330     m_blockName.insert(make_pair(0xd8b,"Leaf1JetNegEtaU2: JF1 Output"));
00331     m_blockName.insert(make_pair(0xd8c,"Leaf1JetNegEtaU2: JF1 Raw Input"));
00332     m_blockName.insert(make_pair(0xe00,"Leaf2JetNegEtaU1: JF2 Input"));  // Next Leaf Start
00333     m_blockName.insert(make_pair(0xe01,"Leaf2JetNegEtaU1: JF2 Shared Received"));
00334     m_blockName.insert(make_pair(0xe02,"Leaf2JetNegEtaU1: JF2 Shared Sent"));
00335     m_blockName.insert(make_pair(0xe03,"Leaf2JetNegEtaU1: JF2 Output"));
00336     m_blockName.insert(make_pair(0xe04,"Leaf2JetNegEtaU1: JF2 Raw Input"));
00337     m_blockName.insert(make_pair(0xe08,"Leaf2JetNegEtaU1: JF3 Input"));
00338     m_blockName.insert(make_pair(0xe09,"Leaf2JetNegEtaU1: JF3 Shared Received"));
00339     m_blockName.insert(make_pair(0xe0a,"Leaf2JetNegEtaU1: JF3 Shared Sent"));
00340     m_blockName.insert(make_pair(0xe0b,"Leaf2JetNegEtaU1: JF3 Output"));
00341     m_blockName.insert(make_pair(0xe0c,"Leaf2JetNegEtaU1: JF3 Raw Input"));
00342     m_blockName.insert(make_pair(0xe80,"Leaf2JetNegEtaU2: Eta0 Input"));  // Next Leaf Start
00343     m_blockName.insert(make_pair(0xe84,"Leaf2JetNegEtaU2: Eta0 Raw Input"));
00344     m_blockName.insert(make_pair(0xe88,"Leaf2JetNegEtaU2: JF1 Input"));
00345     m_blockName.insert(make_pair(0xe89,"Leaf2JetNegEtaU2: JF1 Shared Received"));
00346     m_blockName.insert(make_pair(0xe8a,"Leaf2JetNegEtaU2: JF1 Shared Sent"));
00347     m_blockName.insert(make_pair(0xe8b,"Leaf2JetNegEtaU2: JF1 Output"));
00348     m_blockName.insert(make_pair(0xe8c,"Leaf2JetNegEtaU2: JF1 Raw Input"));
00349     m_blockName.insert(make_pair(0xf00,"Leaf3JetNegEtaU1: JF2 Input"));  // Next Leaf Start
00350     m_blockName.insert(make_pair(0xf01,"Leaf3JetNegEtaU1: JF2 Shared Received"));
00351     m_blockName.insert(make_pair(0xf02,"Leaf3JetNegEtaU1: JF2 Shared Sent"));
00352     m_blockName.insert(make_pair(0xf03,"Leaf3JetNegEtaU1: JF2 Output"));
00353     m_blockName.insert(make_pair(0xf04,"Leaf3JetNegEtaU1: JF2 Raw Input"));
00354     m_blockName.insert(make_pair(0xf08,"Leaf3JetNegEtaU1: JF3 Input"));
00355     m_blockName.insert(make_pair(0xf09,"Leaf3JetNegEtaU1: JF3 Shared Received"));
00356     m_blockName.insert(make_pair(0xf0a,"Leaf3JetNegEtaU1: JF3 Shared Sent"));
00357     m_blockName.insert(make_pair(0xf0b,"Leaf3JetNegEtaU1: JF3 Output"));
00358     m_blockName.insert(make_pair(0xf0c,"Leaf3JetNegEtaU1: JF3 Raw Input"));
00359     m_blockName.insert(make_pair(0xf80,"Leaf3JetNegEtaU2: Eta0 Input"));  // Next Leaf Start
00360     m_blockName.insert(make_pair(0xf84,"Leaf3JetNegEtaU2: Eta0 Raw Input"));
00361     m_blockName.insert(make_pair(0xf88,"Leaf3JetNegEtaU2: JF1 Input"));
00362     m_blockName.insert(make_pair(0xf89,"Leaf3JetNegEtaU2: JF1 Shared Received"));
00363     m_blockName.insert(make_pair(0xf8a,"Leaf3JetNegEtaU2: JF1 Shared Sent"));
00364     m_blockName.insert(make_pair(0xf8b,"Leaf3JetNegEtaU2: JF1 Output"));
00365     m_blockName.insert(make_pair(0xf8c,"Leaf3JetNegEtaU2: JF1 Raw Input"));
00366 
00367 
00368     /*** Setup BlockID to Unpack-Function Map ***/
00369     // Miscellaneous Blocks
00370     m_blockUnpackFn[0x000] = &GctFormatTranslateV38::blockDoNothing;                    // NULL
00371     // ConcJet FPGA                                                             
00372     m_blockUnpackFn[0x580] = &GctFormatTranslateV38::blockToGctTrigObjects;             // ConcJet: Input TrigPathA (Jet Cands)
00373     m_blockUnpackFn[0x581] = &GctFormatTranslateV38::blockToGctInternRingSums;          // ConcJet: Input TrigPathB (HF Rings)
00374     m_blockUnpackFn[0x582] = &GctFormatTranslateV38::blockToGctInternHtMissPostWheel;   // ConcJet: Input TrigPathC (MissHt)
00375     m_blockUnpackFn[0x583] = &GctFormatTranslateV38::blockToGctJetCandsAndCounts;       // ConcJet: Jet Cands and Counts Output to GT
00376     m_blockUnpackFn[0x587] = &GctFormatTranslateV38::blockDoNothing;                    // ConcJet: BX & Orbit Info
00377     // ConcElec FPGA                                                            
00378     m_blockUnpackFn[0x680] = &GctFormatTranslateV38::blockToGctInternEmCand;            // ConcElec: Input TrigPathA (EM Cands)
00379     m_blockUnpackFn[0x681] = &GctFormatTranslateV38::blockToGctInternEtSums;            // ConcElec: Input TrigPathB (Et Sums)
00380     m_blockUnpackFn[0x682] = &GctFormatTranslateV38::blockToGctInternEtSums;            // ConcElec: Input TrigPathC (Ht Sums)
00381     m_blockUnpackFn[0x683] = &GctFormatTranslateV38::blockToGctEmCandsAndEnergySums;    // ConcElec: EM Cands and Energy Sums Output to GT
00382     m_blockUnpackFn[0x686] = &GctFormatTranslateV38::blockDoNothing;                    // ConcElec: Test (GT Serdes Loopback)
00383     m_blockUnpackFn[0x687] = &GctFormatTranslateV38::blockDoNothing;                    // ConcElec: BX & Orbit Info
00384     // Electron Leaf FPGAs                                                      
00385     m_blockUnpackFn[0x800] = &GctFormatTranslateV38::blockToGctInternEmCand;            // Leaf0ElecPosEtaU1: Sort Input
00386     m_blockUnpackFn[0x803] = &GctFormatTranslateV38::blockToGctInternEmCand;            // Leaf0ElecPosEtaU1: Sort Output
00387     m_blockUnpackFn[0x804] = &GctFormatTranslateV38::blockToFibresAndToRctEmCand;       // Leaf0ElecPosEtaU1: Raw Input
00388     m_blockUnpackFn[0x880] = &GctFormatTranslateV38::blockToGctInternEmCand;            // Leaf0ElecPosEtaU2: Sort Input
00389     m_blockUnpackFn[0x883] = &GctFormatTranslateV38::blockToGctInternEmCand;            // Leaf0ElecPosEtaU2: Sort Output
00390     m_blockUnpackFn[0x884] = &GctFormatTranslateV38::blockToFibresAndToRctEmCand;       // Leaf0ElecPosEtaU2: Raw Input
00391     m_blockUnpackFn[0xc00] = &GctFormatTranslateV38::blockToGctInternEmCand;            // Leaf0ElecNegEtaU1: Sort Input
00392     m_blockUnpackFn[0xc03] = &GctFormatTranslateV38::blockToGctInternEmCand;            // Leaf0ElecNegEtaU1: Sort Output
00393     m_blockUnpackFn[0xc04] = &GctFormatTranslateV38::blockToFibresAndToRctEmCand;       // Leaf0ElecNegEtaU1: Raw Input
00394     m_blockUnpackFn[0xc80] = &GctFormatTranslateV38::blockToGctInternEmCand;            // Leaf0ElecNegEtaU2: Sort Input
00395     m_blockUnpackFn[0xc83] = &GctFormatTranslateV38::blockToGctInternEmCand;            // Leaf0ElecNegEtaU2: Sort Output
00396     m_blockUnpackFn[0xc84] = &GctFormatTranslateV38::blockToFibresAndToRctEmCand;       // Leaf0ElecNegEtaU2: Raw Input
00397     // Wheel Pos-eta Jet FPGA                                                   
00398     m_blockUnpackFn[0x300] = &GctFormatTranslateV38::blockToGctJetClusterMinimal;       // WheelPosEtaJet: Input TrigPathA (Jet Sort)
00399     m_blockUnpackFn[0x301] = &GctFormatTranslateV38::blockToGctInternHtMissPreWheel;    // WheelPosEtaJet: Input TrigPathB (MissHt)
00400     m_blockUnpackFn[0x303] = &GctFormatTranslateV38::blockToGctTrigObjects;             // WheelPosEtaJet: Output TrigPathA (Jet Sort)
00401     m_blockUnpackFn[0x305] = &GctFormatTranslateV38::blockToGctInternHtMissPostWheel;   // WheelPosEtaJet: Output TrigPathB (MissHt)
00402     m_blockUnpackFn[0x306] = &GctFormatTranslateV38::blockDoNothing;                    // WheelPosEtaJet: Test (deprecated)  (Doesn't exist in V27.1 format, but does in V24 & V25, so keep for CRUZET2 data compatibility reasons)
00403     m_blockUnpackFn[0x307] = &GctFormatTranslateV38::blockDoNothing;                    // WheelPosEtaJet: Info (deprecated)  (Doesn't exist in V27.1 format, but does in V24 & V25, so keep for CRUZET2 data compatibility reasons)
00404     // Wheel Pos-eta Energy FPGA                                                
00405     m_blockUnpackFn[0x380] = &GctFormatTranslateV38::blockToGctWheelInputInternEtAndRingSums;     // WheelPosEtaEnergy: Input TrigPathA (Et)
00406     m_blockUnpackFn[0x381] = &GctFormatTranslateV38::blockToGctInternEtSums;            // WheelPosEtaEnergy: Input TrigPathB (Ht)
00407     m_blockUnpackFn[0x383] = &GctFormatTranslateV38::blockToGctWheelOutputInternEtAndRingSums;     // WheelPosEtaEnergy: Output TrigPathA (Et)
00408     m_blockUnpackFn[0x385] = &GctFormatTranslateV38::blockToGctInternEtSums;            // WheelPosEtaEnergy: Output TrigPathB (Ht)
00409     m_blockUnpackFn[0x386] = &GctFormatTranslateV38::blockDoNothing;                    // WheelPosEtaEnergy: Test
00410     m_blockUnpackFn[0x387] = &GctFormatTranslateV38::blockDoNothing;                    // WheelPosEtaEnergy: BX & Orbit Info   (Potential data incompatibility between V24/V25 where block length=4, and V27.1 where block length=6)
00411     // Wheel Neg-eta Jet FPGA                                                   
00412     m_blockUnpackFn[0x700] = &GctFormatTranslateV38::blockToGctJetClusterMinimal;       // WheelNegEtaJet: Input TrigPathA (Jet Sort)
00413     m_blockUnpackFn[0x701] = &GctFormatTranslateV38::blockToGctInternHtMissPreWheel;    // WheelNegEtaJet: Input TrigPathB (MissHt)
00414     m_blockUnpackFn[0x703] = &GctFormatTranslateV38::blockToGctTrigObjects;             // WheelNegEtaJet: Output TrigPathA (Jet Sort)
00415     m_blockUnpackFn[0x705] = &GctFormatTranslateV38::blockToGctInternHtMissPostWheel;   // WheelNegEtaJet: Output TrigPathB (MissHt)    
00416     m_blockUnpackFn[0x706] = &GctFormatTranslateV38::blockDoNothing;                    // WheelNegEtaJet: Test (deprecated)  (Doesn't exist in V27.1 format, but does in V24 & V25, so keep for CRUZET2 data compatibility reasons)
00417     m_blockUnpackFn[0x707] = &GctFormatTranslateV38::blockDoNothing;                    // WheelNegEtaJet: Info (deprecated)  (Doesn't exist in V27.1 format, but does in V24 & V25, so keep for CRUZET2 data compatibility reasons)
00418     // Wheel Neg-eta Energy FPGA                                                
00419     m_blockUnpackFn[0x780] = &GctFormatTranslateV38::blockToGctWheelInputInternEtAndRingSums;     // WheelNegEtaEnergy: Input TrigPathA (Et)
00420     m_blockUnpackFn[0x781] = &GctFormatTranslateV38::blockToGctInternEtSums;            // WheelNegEtaEnergy: Input TrigPathB (Ht)
00421     m_blockUnpackFn[0x783] = &GctFormatTranslateV38::blockToGctWheelOutputInternEtAndRingSums;     // WheelNegEtaEnergy: Output TrigPathA (Et)
00422     m_blockUnpackFn[0x785] = &GctFormatTranslateV38::blockToGctInternEtSums;            // WheelNegEtaEnergy: Output TrigPathB (Ht)
00423     m_blockUnpackFn[0x786] = &GctFormatTranslateV38::blockDoNothing;                    // WheelNegEtaEnergy: Test
00424     m_blockUnpackFn[0x787] = &GctFormatTranslateV38::blockDoNothing;                    // WheelNegEtaEnergy: BX & Orbit Info   (Potential data incompatibility between V24/V25 where block length=4, and V27.1 where block length=6)
00425     // Jet Leaf FPGAs - Positive Eta
00426     m_blockUnpackFn[0x900] = &GctFormatTranslateV38::blockToRctCaloRegions;             // Leaf1JetPosEtaU1: JF2 Input
00427     m_blockUnpackFn[0x901] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf1JetPosEtaU1: JF2 Shared Received
00428     m_blockUnpackFn[0x902] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf1JetPosEtaU1: JF2 Shared Sent
00429     m_blockUnpackFn[0x903] = &GctFormatTranslateV38::blockToGctInternEtSumsAndJetCluster;// Leaf1JetPosEtaU1: JF2 Output
00430     m_blockUnpackFn[0x904] = &GctFormatTranslateV38::blockToFibres;                     // Leaf1JetPosEtaU1: JF2 Raw Input
00431     m_blockUnpackFn[0x908] = &GctFormatTranslateV38::blockToRctCaloRegions;             // Leaf1JetPosEtaU1: JF3 Input
00432     m_blockUnpackFn[0x909] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf1JetPosEtaU1: JF3 Shared Received
00433     m_blockUnpackFn[0x90a] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf1JetPosEtaU1: JF3 Shared Sent
00434     m_blockUnpackFn[0x90b] = &GctFormatTranslateV38::blockToGctInternEtSumsAndJetCluster;// Leaf1JetPosEtaU1: JF3 Output
00435     m_blockUnpackFn[0x90c] = &GctFormatTranslateV38::blockToFibres;                     // Leaf1JetPosEtaU1: JF3 Raw Input
00436     m_blockUnpackFn[0x980] = &GctFormatTranslateV38::blockDoNothing;                    // Leaf1JetPosEtaU2: Eta0 Input
00437     m_blockUnpackFn[0x984] = &GctFormatTranslateV38::blockToFibres;                     // Leaf1JetPosEtaU2: Eta0 Raw Input
00438     m_blockUnpackFn[0x988] = &GctFormatTranslateV38::blockToRctCaloRegions;             // Leaf1JetPosEtaU2: JF1 Input
00439     m_blockUnpackFn[0x989] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf1JetPosEtaU2: JF1 Shared Received
00440     m_blockUnpackFn[0x98a] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf1JetPosEtaU2: JF1 Shared Sent
00441     m_blockUnpackFn[0x98b] = &GctFormatTranslateV38::blockToGctInternEtSumsAndJetCluster;// Leaf1JetPosEtaU2: JF1 Output
00442     m_blockUnpackFn[0x98c] = &GctFormatTranslateV38::blockToFibres;                     // Leaf1JetPosEtaU2: JF1 Raw Input
00443     m_blockUnpackFn[0xa00] = &GctFormatTranslateV38::blockToRctCaloRegions;             // Leaf2JetPosEtaU1: JF2 Input
00444     m_blockUnpackFn[0xa01] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf2JetPosEtaU1: JF2 Shared Received
00445     m_blockUnpackFn[0xa02] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf2JetPosEtaU1: JF2 Shared Sent
00446     m_blockUnpackFn[0xa03] = &GctFormatTranslateV38::blockToGctInternEtSumsAndJetCluster;// Leaf2JetPosEtaU1: JF2 Output
00447     m_blockUnpackFn[0xa04] = &GctFormatTranslateV38::blockToFibres;                     // Leaf2JetPosEtaU1: JF2 Raw Input
00448     m_blockUnpackFn[0xa08] = &GctFormatTranslateV38::blockToRctCaloRegions;             // Leaf2JetPosEtaU1: JF3 Input
00449     m_blockUnpackFn[0xa09] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf2JetPosEtaU1: JF3 Shared Received
00450     m_blockUnpackFn[0xa0a] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf2JetPosEtaU1: JF3 Shared Sent
00451     m_blockUnpackFn[0xa0b] = &GctFormatTranslateV38::blockToGctInternEtSumsAndJetCluster;// Leaf2JetPosEtaU1: JF3 Output
00452     m_blockUnpackFn[0xa0c] = &GctFormatTranslateV38::blockToFibres;                     // Leaf2JetPosEtaU1: JF3 Raw Input
00453     m_blockUnpackFn[0xa80] = &GctFormatTranslateV38::blockDoNothing;                    // Leaf2JetPosEtaU2: Eta0 Input
00454     m_blockUnpackFn[0xa84] = &GctFormatTranslateV38::blockToFibres;                     // Leaf2JetPosEtaU2: Eta0 Raw Input
00455     m_blockUnpackFn[0xa88] = &GctFormatTranslateV38::blockToRctCaloRegions;             // Leaf2JetPosEtaU2: JF1 Input
00456     m_blockUnpackFn[0xa89] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf2JetPosEtaU2: JF1 Shared Received
00457     m_blockUnpackFn[0xa8a] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf2JetPosEtaU2: JF1 Shared Sent
00458     m_blockUnpackFn[0xa8b] = &GctFormatTranslateV38::blockToGctInternEtSumsAndJetCluster;// Leaf2JetPosEtaU2: JF1 Output
00459     m_blockUnpackFn[0xa8c] = &GctFormatTranslateV38::blockToFibres;                     // Leaf2JetPosEtaU2: JF1 Raw Input
00460     m_blockUnpackFn[0xb00] = &GctFormatTranslateV38::blockToRctCaloRegions;             // Leaf3JetPosEtaU1: JF2 Input
00461     m_blockUnpackFn[0xb01] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf3JetPosEtaU1: JF2 Shared Received
00462     m_blockUnpackFn[0xb02] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf3JetPosEtaU1: JF2 Shared Sent
00463     m_blockUnpackFn[0xb03] = &GctFormatTranslateV38::blockToGctInternEtSumsAndJetCluster;// Leaf3JetPosEtaU1: JF2 Output
00464     m_blockUnpackFn[0xb04] = &GctFormatTranslateV38::blockToFibres;                     // Leaf3JetPosEtaU1: JF2 Raw Input
00465     m_blockUnpackFn[0xb08] = &GctFormatTranslateV38::blockToRctCaloRegions;             // Leaf3JetPosEtaU1: JF3 Input
00466     m_blockUnpackFn[0xb09] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf3JetPosEtaU1: JF3 Shared Received
00467     m_blockUnpackFn[0xb0a] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf3JetPosEtaU1: JF3 Shared Sent
00468     m_blockUnpackFn[0xb0b] = &GctFormatTranslateV38::blockToGctInternEtSumsAndJetCluster;// Leaf3JetPosEtaU1: JF3 Output
00469     m_blockUnpackFn[0xb0c] = &GctFormatTranslateV38::blockToFibres;                     // Leaf3JetPosEtaU1: JF3 Raw Input
00470     m_blockUnpackFn[0xb80] = &GctFormatTranslateV38::blockDoNothing;                    // Leaf3JetPosEtaU2: Eta0 Input
00471     m_blockUnpackFn[0xb84] = &GctFormatTranslateV38::blockToFibres;                     // Leaf3JetPosEtaU2: Eta0 Raw Input
00472     m_blockUnpackFn[0xb88] = &GctFormatTranslateV38::blockToRctCaloRegions;             // Leaf3JetPosEtaU2: JF1 Input
00473     m_blockUnpackFn[0xb89] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf3JetPosEtaU2: JF1 Shared Received
00474     m_blockUnpackFn[0xb8a] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf3JetPosEtaU2: JF1 Shared Sent
00475     m_blockUnpackFn[0xb8b] = &GctFormatTranslateV38::blockToGctInternEtSumsAndJetCluster;// Leaf3JetPosEtaU2: JF1 Output
00476     m_blockUnpackFn[0xb8c] = &GctFormatTranslateV38::blockToFibres;                     // Leaf3JetPosEtaU2: JF1 Raw Input
00477     // Jet Leaf FPGAs - Negative Eta
00478     m_blockUnpackFn[0xd00] = &GctFormatTranslateV38::blockToRctCaloRegions;             // Leaf1JetNegEtaU1: JF2 Input
00479     m_blockUnpackFn[0xd01] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf1JetNegEtaU1: JF2 Shared Received
00480     m_blockUnpackFn[0xd02] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf1JetNegEtaU1: JF2 Shared Sent
00481     m_blockUnpackFn[0xd03] = &GctFormatTranslateV38::blockToGctInternEtSumsAndJetCluster;// Leaf1JetNegEtaU1: JF2 Output
00482     m_blockUnpackFn[0xd04] = &GctFormatTranslateV38::blockToFibres;                     // Leaf1JetNegEtaU1: JF2 Raw Input
00483     m_blockUnpackFn[0xd08] = &GctFormatTranslateV38::blockToRctCaloRegions;             // Leaf1JetNegEtaU1: JF3 Input
00484     m_blockUnpackFn[0xd09] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf1JetNegEtaU1: JF3 Shared Received
00485     m_blockUnpackFn[0xd0a] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf1JetNegEtaU1: JF3 Shared Sent
00486     m_blockUnpackFn[0xd0b] = &GctFormatTranslateV38::blockToGctInternEtSumsAndJetCluster;// Leaf1JetNegEtaU1: JF3 Output
00487     m_blockUnpackFn[0xd0c] = &GctFormatTranslateV38::blockToFibres;                     // Leaf1JetNegEtaU1: JF3 Raw Input
00488     m_blockUnpackFn[0xd80] = &GctFormatTranslateV38::blockDoNothing;                    // Leaf1JetNegEtaU2: Eta0 Input
00489     m_blockUnpackFn[0xd84] = &GctFormatTranslateV38::blockToFibres;                     // Leaf1JetNegEtaU2: Eta0 Raw Input
00490     m_blockUnpackFn[0xd88] = &GctFormatTranslateV38::blockToRctCaloRegions;             // Leaf1JetNegEtaU2: JF1 Input
00491     m_blockUnpackFn[0xd89] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf1JetNegEtaU2: JF1 Shared Received
00492     m_blockUnpackFn[0xd8a] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf1JetNegEtaU2: JF1 Shared Sent
00493     m_blockUnpackFn[0xd8b] = &GctFormatTranslateV38::blockToGctInternEtSumsAndJetCluster;// Leaf1JetNegEtaU2: JF1 Output
00494     m_blockUnpackFn[0xd8c] = &GctFormatTranslateV38::blockToFibres;                     // Leaf1JetNegEtaU2: JF1 Raw Input
00495     m_blockUnpackFn[0xe00] = &GctFormatTranslateV38::blockToRctCaloRegions;             // Leaf2JetNegEtaU1: JF2 Input
00496     m_blockUnpackFn[0xe01] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf2JetNegEtaU1: JF2 Shared Received
00497     m_blockUnpackFn[0xe02] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf2JetNegEtaU1: JF2 Shared Sent
00498     m_blockUnpackFn[0xe03] = &GctFormatTranslateV38::blockToGctInternEtSumsAndJetCluster;// Leaf2JetNegEtaU1: JF2 Output
00499     m_blockUnpackFn[0xe04] = &GctFormatTranslateV38::blockToFibres;                     // Leaf2JetNegEtaU1: JF2 Raw Input
00500     m_blockUnpackFn[0xe08] = &GctFormatTranslateV38::blockToRctCaloRegions;             // Leaf2JetNegEtaU1: JF3 Input
00501     m_blockUnpackFn[0xe09] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf2JetNegEtaU1: JF3 Shared Received
00502     m_blockUnpackFn[0xe0a] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf2JetNegEtaU1: JF3 Shared Sent
00503     m_blockUnpackFn[0xe0b] = &GctFormatTranslateV38::blockToGctInternEtSumsAndJetCluster;// Leaf2JetNegEtaU1: JF3 Output
00504     m_blockUnpackFn[0xe0c] = &GctFormatTranslateV38::blockToFibres;                     // Leaf2JetNegEtaU1: JF3 Raw Input
00505     m_blockUnpackFn[0xe80] = &GctFormatTranslateV38::blockDoNothing;                    // Leaf2JetNegEtaU2: Eta0 Input
00506     m_blockUnpackFn[0xe84] = &GctFormatTranslateV38::blockToFibres;                     // Leaf2JetNegEtaU2: Eta0 Raw Input
00507     m_blockUnpackFn[0xe88] = &GctFormatTranslateV38::blockToRctCaloRegions;             // Leaf2JetNegEtaU2: JF1 Input
00508     m_blockUnpackFn[0xe89] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf2JetNegEtaU2: JF1 Shared Received
00509     m_blockUnpackFn[0xe8a] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf2JetNegEtaU2: JF1 Shared Sent
00510     m_blockUnpackFn[0xe8b] = &GctFormatTranslateV38::blockToGctInternEtSumsAndJetCluster;// Leaf2JetNegEtaU2: JF1 Output
00511     m_blockUnpackFn[0xe8c] = &GctFormatTranslateV38::blockToFibres;                     // Leaf2JetNegEtaU2: JF1 Raw Input
00512     m_blockUnpackFn[0xf00] = &GctFormatTranslateV38::blockToRctCaloRegions;             // Leaf3JetNegEtaU1: JF2 Input
00513     m_blockUnpackFn[0xf01] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf3JetNegEtaU1: JF2 Shared Received
00514     m_blockUnpackFn[0xf02] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf3JetNegEtaU1: JF2 Shared Sent
00515     m_blockUnpackFn[0xf03] = &GctFormatTranslateV38::blockToGctInternEtSumsAndJetCluster;// Leaf3JetNegEtaU1: JF2 Output
00516     m_blockUnpackFn[0xf04] = &GctFormatTranslateV38::blockToFibres;                     // Leaf3JetNegEtaU1: JF2 Raw Input
00517     m_blockUnpackFn[0xf08] = &GctFormatTranslateV38::blockToRctCaloRegions;             // Leaf3JetNegEtaU1: JF3 Input
00518     m_blockUnpackFn[0xf09] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf3JetNegEtaU1: JF3 Shared Received
00519     m_blockUnpackFn[0xf0a] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf3JetNegEtaU1: JF3 Shared Sent
00520     m_blockUnpackFn[0xf0b] = &GctFormatTranslateV38::blockToGctInternEtSumsAndJetCluster;// Leaf3JetNegEtaU1: JF3 Output
00521     m_blockUnpackFn[0xf0c] = &GctFormatTranslateV38::blockToFibres;                     // Leaf3JetNegEtaU1: JF3 Raw Input
00522     m_blockUnpackFn[0xf80] = &GctFormatTranslateV38::blockDoNothing;                    // Leaf3JetNegEtaU2: Eta0 Input
00523     m_blockUnpackFn[0xf84] = &GctFormatTranslateV38::blockToFibres;                     // Leaf3JetNegEtaU2: Eta0 Raw Input
00524     m_blockUnpackFn[0xf88] = &GctFormatTranslateV38::blockToRctCaloRegions;             // Leaf3JetNegEtaU2: JF1 Input
00525     m_blockUnpackFn[0xf89] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf3JetNegEtaU2: JF1 Shared Received
00526     m_blockUnpackFn[0xf8a] = &GctFormatTranslateV38::blockToGctJetPreCluster;           // Leaf3JetNegEtaU2: JF1 Shared Sent
00527     m_blockUnpackFn[0xf8b] = &GctFormatTranslateV38::blockToGctInternEtSumsAndJetCluster;// Leaf3JetNegEtaU2: JF1 Output
00528     m_blockUnpackFn[0xf8c] = &GctFormatTranslateV38::blockToFibres;                     // Leaf3JetNegEtaU2: JF1 Raw Input
00529 
00530 
00531     /*** Setup RCT Em Crate Map ***/
00532     m_rctEmCrate[0x804] = 13;
00533     m_rctEmCrate[0x884] = 9;
00534     m_rctEmCrate[0xc04] = 4;
00535     m_rctEmCrate[0xc84] = 0;
00536 
00537 
00538     /*** Setup RCT jet crate map. ***/
00539     m_rctJetCrate[0x900] = 9;  // PosEta Leaf 1 JF2
00540     m_rctJetCrate[0x908] = 10; // PosEta Leaf 1 JF3
00541     m_rctJetCrate[0x988] = 17; // PosEta Leaf 1 JF1 
00542     m_rctJetCrate[0xa00] = 12; // PosEta Leaf 2 JF2
00543     m_rctJetCrate[0xa08] = 13; // PosEta Leaf 2 JF3
00544     m_rctJetCrate[0xa88] = 11; // PosEta Leaf 2 JF1 
00545     m_rctJetCrate[0xb00] = 15; // PosEta Leaf 3 JF2
00546     m_rctJetCrate[0xb08] = 16; // PosEta Leaf 3 JF3
00547     m_rctJetCrate[0xb88] = 14; // PosEta Leaf 3 JF1 
00548     m_rctJetCrate[0xd00] = 0;  // NegEta Leaf 1 JF2
00549     m_rctJetCrate[0xd08] = 1;  // NegEta Leaf 1 JF3
00550     m_rctJetCrate[0xd88] = 8;  // NegEta Leaf 1 JF1 
00551     m_rctJetCrate[0xe00] = 3;  // NegEta Leaf 2 JF2
00552     m_rctJetCrate[0xe08] = 4;  // NegEta Leaf 2 JF3
00553     m_rctJetCrate[0xe88] = 2;  // NegEta Leaf 2 JF1 
00554     m_rctJetCrate[0xf00] = 6;  // NegEta Leaf 3 JF2
00555     m_rctJetCrate[0xf08] = 7;  // NegEta Leaf 3 JF3
00556     m_rctJetCrate[0xf88] = 5;  // NegEta Leaf 3 JF1 
00557 
00558 
00559     /*** Setup Block ID map for pipeline payload positions of isolated Internal EM Cands. ***/
00560     m_internEmIsoBounds[0x680] = IsoBoundaryPair(8,15);
00561     m_internEmIsoBounds[0x800] = IsoBoundaryPair(0, 9);
00562     m_internEmIsoBounds[0x803] = IsoBoundaryPair(0, 1);
00563     m_internEmIsoBounds[0x880] = IsoBoundaryPair(0, 7);
00564     m_internEmIsoBounds[0x883] = IsoBoundaryPair(0, 1);
00565     m_internEmIsoBounds[0xc00] = IsoBoundaryPair(0, 9);
00566     m_internEmIsoBounds[0xc03] = IsoBoundaryPair(0, 1);
00567     m_internEmIsoBounds[0xc80] = IsoBoundaryPair(0, 7);
00568     m_internEmIsoBounds[0xc83] = IsoBoundaryPair(0, 1);
00569   }
00570 }
00571 
00572 GctFormatTranslateV38::~GctFormatTranslateV38()
00573 {
00574 }
00575 
00576 GctBlockHeader GctFormatTranslateV38::generateBlockHeader(const unsigned char * data) const
00577 {
00578   // Turn the four 8-bit header words into the full 32-bit header.
00579   uint32_t hdr = data[0] + (data[1]<<8) + (data[2]<<16) + (data[3]<<24);
00580 
00581 //  Bit mapping of V35 header:
00582 //  --------------------------
00583 //  11:0   => block_id  Unique pipeline identifier.
00584 //   - 3:0    =>> pipe_id There can be up to 16 different pipelines per FPGA.
00585 //   - 6:4    =>> reserved  Do not use yet. Set to zero.
00586 //   - 11:7   =>> fpga geograpical add  The VME geographical address of the FPGA.
00587 //  15:12  => event_id  Determined locally.  Not reset by Resync.
00588 //  19:16  => number_of_time_samples  If time samples 15 or more then value = 15.
00589 //  31:20  => event_bcid  The bunch crossing the data was recorded.
00590 
00591   unsigned blockId = hdr & 0xfff;
00592   unsigned blockLength = 0;  // Set to zero until we know it's a valid block
00593   unsigned nSamples = (hdr>>16) & 0xf;
00594   unsigned bxId = (hdr>>20) & 0xfff;
00595   unsigned eventId = (hdr>>12) & 0xf;
00596   bool valid = (blockLengthMap().find(blockId) != blockLengthMap().end());
00597 
00598   if(valid) { blockLength = blockLengthMap().find(blockId)->second; }
00599   
00600   return GctBlockHeader(blockId, blockLength, nSamples, bxId, eventId, valid);  
00601 }
00602 
00603 // conversion
00604 bool GctFormatTranslateV38::convertBlock(const unsigned char * data, const GctBlockHeader& hdr)
00605 {
00606   // if the block has no time samples, don't bother with it.
00607   if ( hdr.nSamples() < 1 ) { return true; }
00608 
00609   if(!checkBlock(hdr)) { return false; }  // Check the block to see if it's possible to unpack.
00610 
00611   // The header validity check above will protect against
00612   // the map::find() method returning the end of the map,
00613   // assuming the block header definitions are up-to-date.
00614   (this->*m_blockUnpackFn.find(hdr.blockId())->second)(data, hdr);  // Calls the correct unpack function, based on block ID.
00615   
00616   return true;
00617 }
00618 
00619 
00620 // PROTECTED METHODS
00621 
00622 uint32_t GctFormatTranslateV38::generateRawHeader(const uint32_t blockId,
00623                                                   const uint32_t nSamples,
00624                                                   const uint32_t bxId,
00625                                                   const uint32_t eventId) const
00626 {
00627   //  Bit mapping of V35 header:
00628   //  --------------------------
00629   //  11:0   => block_id  Unique pipeline identifier.
00630   //   - 3:0    =>> pipe_id There can be up to 16 different pipelines per FPGA.
00631   //   - 6:4    =>> reserved  Do not use yet. Set to zero.
00632   //   - 11:7   =>> fpga geograpical add  The VME geographical address of the FPGA.
00633   //  15:12  => event_id  Determined locally.  Not reset by Resync.
00634   //  19:16  => number_of_time_samples  If time samples 15 or more then value = 15.
00635   //  31:20  => event_bxId  The bunch crossing the data was recorded.
00636 
00637   return ((bxId & 0xfff) << 20) | ((nSamples & 0xf) << 16) | ((eventId & 0xf) << 12) | (blockId & 0xfff);
00638 }
00639 
00640 
00641 // PRIVATE METHODS
00642 
00643 // Throughout the code, bx refers to the hardware definition of time-samples
00644 // ie. if 5 time samples are unpacked, they are bx=0, 1, 2, 3, 4 in order
00645 // what is written to digi would be -2, -1, 0, +1, +2
00646 
00647 // Output EM Candidates unpacking
00648 void GctFormatTranslateV38::blockToGctEmCandsAndEnergySums(const unsigned char * d, const GctBlockHeader& hdr)
00649 {
00650   const unsigned int id = hdr.blockId();
00651   const unsigned int nSamples = hdr.nSamples();
00652 
00653   // Re-interpret pointer.  p16 will be pointing at the 16 bit word that
00654   // contains the rank0 non-isolated electron of the zeroth time-sample.
00655   const uint16_t * p16 = reinterpret_cast<const uint16_t *>(d);
00656 
00657   // UNPACK EM CANDS
00658 
00659   const unsigned int emCandCategoryOffset = nSamples * 4;  // Offset to jump from the non-iso electrons to the isolated ones.
00660   const unsigned int timeSampleOffset = nSamples * 2;  // Offset to jump to next candidate pair in the same time-sample.
00661 
00662   unsigned int samplesToUnpack = std::min(nSamples,m_numberOfGctSamplesToUnpack); // Unpack as many as asked for if they are in the raw data
00663   unsigned int centralSample = (unsigned)std::ceil((double)nSamples/2.)-1;  // think this works when nSamples is even, need to check!!!
00664   unsigned int firstSample = centralSample-(unsigned)std::ceil((double)samplesToUnpack/2.)+1;
00665   unsigned int lastSample = centralSample+(unsigned)(samplesToUnpack/2);
00666 
00667   LogDebug("GCT") << "Unpacking output EM.  Central sample=" << centralSample << " first=" << firstSample << " last=" << lastSample;
00668 
00669   for (unsigned int iso=0; iso<2; ++iso)  // loop over non-iso/iso candidate pairs
00670   {
00671     bool isoFlag = (iso==1);
00672 
00673     // Get the correct collection to put them in.
00674     L1GctEmCandCollection* em;
00675     if (isoFlag) { em = colls()->gctIsoEm(); }
00676     else { em = colls()->gctNonIsoEm(); }
00677     
00678     for (unsigned int bx=firstSample; bx<=lastSample; ++bx) // loop over samples to be unpacked
00679     {
00680       // cand0Offset will give the offset on p16 to get the rank 0 candidate
00681       // of the correct category and timesample.
00682       const unsigned int cand0Offset = iso*emCandCategoryOffset + bx*2;
00683 
00684       em->push_back(L1GctEmCand(p16[cand0Offset], isoFlag, id, 0, (int)bx-(int)centralSample));  // rank0 electron
00685       em->push_back(L1GctEmCand(p16[cand0Offset + timeSampleOffset], isoFlag, id, 1, (int)bx-(int)centralSample));  // rank1 electron
00686       em->push_back(L1GctEmCand(p16[cand0Offset + 1], isoFlag, id, 2, (int)bx-(int)centralSample));  // rank2 electron
00687       em->push_back(L1GctEmCand(p16[cand0Offset + timeSampleOffset + 1], isoFlag, id, 3, (int)bx-(int)centralSample));  // rank3 electron
00688 
00689       LogDebug("GCT") << "Unpacked a bunch of EG.  iso=" << iso << " bx=" << bx << std::endl;
00690     }
00691   }
00692 
00693   p16 += emCandCategoryOffset * 2;  // Move the pointer over the data we've already unpacked.
00694 
00695   // UNPACK ENERGY SUMS
00696 
00697   for (unsigned int bx=firstSample; bx<=lastSample; ++bx) // loop over all time samples
00698     {
00699       const unsigned int offset = bx*2;
00700       colls()->gctEtTot()->push_back(L1GctEtTotal(p16[offset],(int)bx-(int)centralSample));  // Et total
00701       colls()->gctEtHad()->push_back(L1GctEtHad(p16[offset+1],(int)bx-(int)centralSample));  // Et hadronic 
00702     }
00703 
00704   p16 += nSamples * 2;
00705 
00706   // 32-bit pointer for getting Missing Et.
00707   const uint32_t * p32 = reinterpret_cast<const uint32_t *>(p16);
00708 
00709   for (unsigned int bx=firstSample; bx<=lastSample; ++bx) {
00710     colls()->gctEtMiss()->push_back(L1GctEtMiss(p32[bx],(int)bx-(int)centralSample)); // Et Miss 
00711     LogDebug("GCT") << "Unpacked energy sums bx=" << bx << std::endl;   
00712   }
00713 
00714 
00715 }
00716 
00717 void GctFormatTranslateV38::blockToGctJetCandsAndCounts(const unsigned char * d, const GctBlockHeader& hdr)
00718 {
00719   const unsigned int id = hdr.blockId();  // Capture block ID.
00720   const unsigned int nSamples = hdr.nSamples();  // Number of time-samples.
00721 
00722   // Re-interpret block payload pointer to 16 bits so it sees one candidate at a time.
00723   // p16 points to the start of the block payload, at the rank0 tau jet candidate.
00724   const uint16_t * p16 = reinterpret_cast<const uint16_t *>(d);
00725 
00726   // UNPACK JET CANDS
00727 
00728   const unsigned int jetCandCategoryOffset = nSamples * 4;  // Offset to jump from one jet category to the next.
00729   const unsigned int timeSampleOffset = nSamples * 2;  // Offset to jump to next candidate pair in the same time-sample.
00730 
00731   unsigned int samplesToUnpack = std::min(nSamples,m_numberOfGctSamplesToUnpack); // Unpack as many as asked for if they are in the raw data
00732   unsigned int centralSample = (unsigned)std::ceil((double)nSamples/2.)-1;  // think this works when nSamples is even, need to check!!!
00733   unsigned int firstSample = centralSample-(unsigned)std::ceil((double)samplesToUnpack/2.)+1;
00734   unsigned int lastSample = centralSample+(unsigned)(samplesToUnpack/2);
00735 
00736   LogDebug("GCT") << "Unpacking output Jets. Samples to unpack=" << samplesToUnpack << " central=" << centralSample << " first=" << firstSample << " last=" << lastSample;
00737 
00738   // Loop over the different catagories of jets
00739   for(unsigned int iCat = 0 ; iCat < NUM_JET_CATEGORIES ; ++iCat)
00740   {
00741     L1GctJetCandCollection * const jets = gctJets(iCat);
00742     assert(jets->empty()); // The supplied vector should be empty.
00743 
00744     bool tauflag = (iCat == TAU_JETS);
00745     bool forwardFlag = (iCat == FORWARD_JETS);
00746 
00747     // Loop over the different timesamples (bunch crossings).
00748     for(unsigned int bx = firstSample ; bx <=lastSample; ++bx)
00749     {
00750       // cand0Offset will give the offset on p16 to get the rank 0 Jet Cand of the correct category and timesample.
00751       const unsigned int cand0Offset = iCat*jetCandCategoryOffset + bx*2;
00752 
00753       // Rank 0 Jet.
00754       jets->push_back(L1GctJetCand(p16[cand0Offset], tauflag, forwardFlag, id, 0, (int)bx-(int)centralSample));
00755       // Rank 1 Jet.
00756       jets->push_back(L1GctJetCand(p16[cand0Offset + timeSampleOffset], tauflag, forwardFlag, id, 1, (int)bx-(int)centralSample));
00757       // Rank 2 Jet.
00758       jets->push_back(L1GctJetCand(p16[cand0Offset + 1],  tauflag, forwardFlag, id, 2, (int)bx-(int)centralSample));
00759       // Rank 3 Jet.
00760       jets->push_back(L1GctJetCand(p16[cand0Offset + timeSampleOffset + 1], tauflag, forwardFlag, id, 3, (int)bx-(int)centralSample));
00761     }
00762   }
00763 
00764   p16 += NUM_JET_CATEGORIES * jetCandCategoryOffset; // Move the pointer over the data we've already unpacked.
00765 
00766   // NOW UNPACK: HFBitCounts, HFRingEtSums and Missing Ht
00767 
00768   // Re-interpret block payload pointer to 32 bits so it sees six jet counts at a time.
00769   const uint32_t * p32 = reinterpret_cast<const uint32_t *>(p16);
00770 
00771   for (unsigned int bx=firstSample; bx<=lastSample; ++bx) // loop over all time samples
00772     {
00773       // Channel 0 carries both HF counts and sums
00774       colls()->gctHfBitCounts()->push_back(L1GctHFBitCounts::fromConcHFBitCounts(id,6,(int)bx-(int)centralSample,p32[bx])); 
00775       colls()->gctHfRingEtSums()->push_back(L1GctHFRingEtSums::fromConcRingSums(id,6,(int)bx-(int)centralSample,p32[bx]));
00776       
00777       // Channel 1 carries Missing HT.
00778       colls()->gctHtMiss()->push_back(L1GctHtMiss(p32[bx+nSamples], (int)bx-(int)centralSample));
00779     }
00780 }
00781 
00782 // Internal EM Candidates unpacking
00783 void GctFormatTranslateV38::blockToGctInternEmCand(const unsigned char * d, const GctBlockHeader& hdr)
00784 {
00785   // Don't want to do this in HLT optimisation mode!
00786   if(hltMode()) { LogDebug("GCT") << "HLT mode - skipping unpack of internal EM Cands"; return; }
00787 
00788   unsigned int id = hdr.blockId();
00789   unsigned int nSamples = hdr.nSamples();
00790   unsigned int numCandPairs = hdr.blockLength();
00791 
00792   // Debug assertion to prevent problems if definitions not up to date.
00793   assert(internEmIsoBounds().find(id) != internEmIsoBounds().end());  
00794 
00795   unsigned int lowerIsoPairBound = internEmIsoBounds()[id].first;
00796   unsigned int upperIsoPairBound = internEmIsoBounds()[id].second;
00797 
00798   // Re-interpret pointer to 16 bits so it sees one candidate at a time.
00799   const uint16_t * p = reinterpret_cast<const uint16_t *>(d);
00800 
00801   // Loop over timesamples (i.e. bunch crossings)
00802   for(unsigned int bx=0; bx < nSamples; ++bx)
00803   {
00804     // Loop over candidate pairs (i.e. each iteration unpacks a pair of candidates)
00805     for(unsigned int candPair = 0 ; candPair < numCandPairs ; ++candPair)
00806     {
00807       // Is the candidate electron pair an isolated pair or not?
00808       bool iso = ((candPair>=lowerIsoPairBound) && (candPair<=upperIsoPairBound));
00809       
00810       // Loop over the two electron candidates in each pair
00811       for(unsigned int i = 0 ; i < 2 ; ++i)
00812       { 
00813         unsigned offset = 2*(bx + candPair*nSamples) + i;
00814         uint16_t candRaw = p[offset]; 
00815         colls()->gctInternEm()->push_back( L1GctInternEmCand(candRaw, iso, id, candPair*2 + i, bx) );
00816       }
00817     }
00818   }
00819 }
00820 
00821 
00822 // Input EM Candidates unpacking
00823 // this is the last time I deal the RCT bit assignment travesty!!!
00824 void GctFormatTranslateV38::blockToRctEmCand(const unsigned char * d, const GctBlockHeader& hdr)
00825 {
00826   // Don't want to do this in HLT optimisation mode!
00827   if(hltMode()) { LogDebug("GCT") << "HLT mode - skipping unpack of RCT EM Cands"; return; }
00828 
00829   unsigned int id = hdr.blockId();
00830   unsigned int nSamples = hdr.nSamples();
00831   unsigned int length = hdr.blockLength();
00832 
00833   // re-interpret pointer
00834   const uint16_t * p = reinterpret_cast<const uint16_t *>(d);
00835 
00836   // arrays of source card data
00837   uint16_t sfp[2][4]; // [ cycle ] [ SFP ]
00838   uint16_t eIsoRank[4];
00839   uint16_t eIsoCard[4];
00840   uint16_t eIsoRgn[4];
00841   uint16_t eNonIsoRank[4];
00842   uint16_t eNonIsoCard[4];
00843   uint16_t eNonIsoRgn[4];
00844   uint16_t MIPbits[7][2];
00845   uint16_t QBits[7][2];
00846 
00847   unsigned int bx = 0;
00848 
00849   // loop over crates
00850   for (unsigned int crate=rctEmCrateMap()[id]; crate<rctEmCrateMap()[id]+length/3; ++crate) {
00851 
00852     // read SC SFP words
00853     for (unsigned short iSfp=0 ; iSfp<4 ; ++iSfp) {
00854       for (unsigned short cyc=0 ; cyc<2 ; ++cyc) {
00855         if (iSfp==0) { sfp[cyc][iSfp] = 0; } // muon bits
00856         else {                               // EM candidate
00857           sfp[cyc][iSfp] = *p;
00858           ++p;
00859         }
00860       }
00861       p = p + 2*(nSamples-1);
00862     }
00863 
00864     // fill SC arrays
00865     srcCardRouting().SFPtoEMU(eIsoRank, eIsoCard, eIsoRgn, eNonIsoRank, eNonIsoCard, eNonIsoRgn, MIPbits, QBits, sfp);
00866     
00867     // create EM cands
00868     for (unsigned short int i=0; i<4; ++i) {
00869       colls()->rctEm()->push_back( L1CaloEmCand( eIsoRank[i], eIsoRgn[i], eIsoCard[i], crate, true, i, bx) );
00870     }
00871     for (unsigned short int i=0; i<4; ++i) {
00872       colls()->rctEm()->push_back( L1CaloEmCand( eNonIsoRank[i], eNonIsoRgn[i], eNonIsoCard[i], crate, false, i, bx) );
00873     }
00874   }
00875 }
00876 
00877 // Input RCT region unpacking
00878 void GctFormatTranslateV38::blockToRctCaloRegions(const unsigned char * d, const GctBlockHeader& hdr)
00879 {
00880   // Don't want to do this in HLT optimisation mode!
00881   if(hltMode()) { LogDebug("GCT") << "HLT mode - skipping unpack of RCT Regions"; return; }
00882 
00883   unsigned int id = hdr.blockId();
00884   unsigned int nSamples = hdr.nSamples();
00885   unsigned int length = hdr.blockLength();
00886 
00887   // Debug assertion to prevent problems if definitions not up to date.
00888   assert(rctJetCrateMap().find(id) != rctJetCrateMap().end());  
00889   
00890   // get crate (need this to get ieta and iphi)
00891   unsigned int crate=rctJetCrateMap()[id];
00892 
00893   // re-interpret pointer
00894   const uint16_t * p = reinterpret_cast<const uint16_t *>(d);
00895   
00896   // eta and phi
00897   unsigned int ieta; 
00898   unsigned int iphi; 
00899   
00900   for (unsigned int i=0; i<length; ++i)
00901   { 
00902     for (uint16_t bx=0; bx<nSamples; ++bx)
00903     {
00904       // First figure out eta and phi
00905       if (crate<9) { // negative eta
00906           ieta = 12-i; 
00907           iphi = 2*((11-crate)%9);
00908       }
00909       else { // positive eta
00910         ieta = 9+i;
00911         iphi = 2*((20-crate)%9);
00912       }
00913       
00914       // Skip the first four regions (i.e. where i<2) which are duplicates (shared data).
00915       if (i>1) { 
00916         // First region is phi=0
00917         colls()->rctCalo()->push_back( L1CaloRegion::makeRegionFromUnpacker(*p, ieta, iphi, id, i, bx) );
00918         ++p;
00919         // Second region is phi=1
00920         if (iphi>0) { iphi-=1; }
00921         else { iphi = 17; }
00922         colls()->rctCalo()->push_back( L1CaloRegion::makeRegionFromUnpacker(*p, ieta, iphi, id, i, bx) );
00923         ++p;
00924       }
00925       // Unpack the shared data if asked for debugging
00926       else if (unpackSharedRegions()){
00927         // First region is phi=0
00928         colls()->rctCalo()->push_back( L1CaloRegion::makeRegionFromUnpacker(*p, ieta, iphi, id, i, bx) );
00929         ++p;
00930         // Second region is phi=1
00931         if (iphi>0) { iphi-=1; }
00932         else { iphi = 17; }
00933         colls()->rctCalo()->push_back( L1CaloRegion::makeRegionFromUnpacker(*p, ieta, iphi, id, i, bx) );
00934         ++p;
00935         
00936       } else { // Skip the shared data  
00937         ++p;
00938         ++p;
00939       }
00940     }
00941   } 
00942 }  
00943 
00944 
00945 // Fibre unpacking
00946 void GctFormatTranslateV38::blockToFibres(const unsigned char * d, const GctBlockHeader& hdr)
00947 {
00948   // Don't want to do this in HLT optimisation mode!
00949   if(hltMode()) { LogDebug("GCT") << "HLT mode - skipping unpack of GCT Fibres"; return; }
00950   
00951   unsigned int id = hdr.blockId();
00952   unsigned int nSamples = hdr.nSamples();
00953   unsigned int length = hdr.blockLength();
00954 
00955   // re-interpret pointer
00956   const uint32_t * p = reinterpret_cast<const uint32_t *>(d);
00957 
00958   for (unsigned int i=0; i<length; ++i) {
00959     for (unsigned int bx=0; bx<nSamples; ++bx) {
00960       colls()->gctFibres()->push_back( L1GctFibreWord(*p, id, i, bx) );
00961       ++p;
00962     }
00963   } 
00964 }
00965 
00966 void GctFormatTranslateV38::blockToFibresAndToRctEmCand(const unsigned char * d, const GctBlockHeader& hdr)
00967 {
00968   this->blockToRctEmCand(d, hdr);
00969   this->blockToFibres(d, hdr);
00970 }
00971 
00972 void GctFormatTranslateV38::blockToGctInternEtSums(const unsigned char * d, const GctBlockHeader& hdr)
00973 {
00974   // Don't want to do this in HLT optimisation mode!                                                                                                                           
00975   
00976   if(hltMode()) { LogDebug("GCT") << "HLT mode - skipping unpack of internal Et Sums"; return; }
00977 
00978   unsigned int id = hdr.blockId();
00979   unsigned int nSamples = hdr.nSamples();
00980   unsigned int length = hdr.blockLength();
00981 
00982   // Re-interpret pointer to 32 bits 
00983   const uint32_t * p = reinterpret_cast<const uint32_t *>(d);
00984 
00985   for (unsigned int i=0; i<length; ++i) {
00986     // Loop over timesamples (i.e. bunch crossings)                                                                                                                            
00987     for (unsigned int bx=0; bx<nSamples; ++bx) {
00988       colls()->gctInternEtSums()->push_back(L1GctInternEtSum::fromTotalEtOrHt(id,i,bx,*p));
00989       ++p;
00990     }
00991   }
00992 }
00993 
00994 void GctFormatTranslateV38::blockToGctInternEtSumsAndJetCluster(const unsigned char * d, const GctBlockHeader& hdr)
00995 {
00996   // Don't want to do this in HLT optimisation mode!
00997   if(hltMode()) { LogDebug("GCT") << "HLT mode - skipping unpack of internal Jet Cands"; return; }
00998 
00999   unsigned int id = hdr.blockId();
01000   unsigned int nSamples = hdr.nSamples();
01001   unsigned int length = hdr.blockLength();
01002 
01003   // Re-interpret pointer to 32 bits 
01004   const uint32_t * p = reinterpret_cast<const uint32_t *>(d);
01005 
01006   for (unsigned int i=0; i<length; ++i) {
01007     // Loop over timesamples (i.e. bunch crossings)
01008     for (unsigned int bx=0; bx<nSamples; ++bx) {
01009       if (i<2) colls()->gctInternEtSums()->push_back(L1GctInternEtSum::fromJetMissEt(id,i,bx,*p));
01010       if (i==3){
01011         colls()->gctInternEtSums()->push_back(L1GctInternEtSum::fromJetTotEt(id,i,bx,*p));
01012         colls()->gctInternEtSums()->push_back(L1GctInternEtSum::fromJetTotHt(id,i,bx,*p));
01013       } 
01014       if (i>4) colls()->gctInternJets()->push_back(L1GctInternJetData::fromJetCluster(L1CaloRegionDetId(0,0),id,i,bx,*p));
01015       ++p;
01016     }  
01017   }
01018 }
01019 
01020 void GctFormatTranslateV38::blockToGctTrigObjects(const unsigned char * d, const GctBlockHeader& hdr)
01021 {
01022   // Don't want to do this in HLT optimisation mode!
01023   if(hltMode()) { LogDebug("GCT") << "HLT mode - skipping unpack of internal Jet Cands"; return; }
01024 
01025   unsigned int id = hdr.blockId();
01026   unsigned int nSamples = hdr.nSamples();
01027   unsigned int length = hdr.blockLength();
01028 
01029   // Re-interpret pointer to 16 bits so it sees one candidate at a time.
01030   const uint16_t * p = reinterpret_cast<const uint16_t *>(d);
01031 
01032   for (unsigned int i=0; i<length; ++i) {
01033     // Loop over timesamples (i.e. bunch crossings)
01034     for (unsigned int bx=0; bx<nSamples; ++bx) {
01035       colls()->gctInternJets()->push_back( L1GctInternJetData::fromGctTrigObject(L1CaloRegionDetId(0,0),id,i,bx,*p));
01036       ++p;
01037       colls()->gctInternJets()->push_back( L1GctInternJetData::fromGctTrigObject(L1CaloRegionDetId(0,0),id,i,bx,*p));
01038       ++p;
01039     }
01040   } 
01041 }
01042 
01043 void GctFormatTranslateV38::blockToGctJetClusterMinimal(const unsigned char * d, const GctBlockHeader& hdr)
01044 {
01045   // Don't want to do this in HLT optimisation mode!
01046   if(hltMode()) { LogDebug("GCT") << "HLT mode - skipping unpack of internal Jet Cands"; return; }
01047 
01048   unsigned int id = hdr.blockId();
01049   unsigned int nSamples = hdr.nSamples();
01050   unsigned int length = hdr.blockLength();
01051 
01052   // Re-interpret pointer to 16 bits so it sees one candidate at a time.
01053   const uint16_t * p = reinterpret_cast<const uint16_t *>(d);
01054 
01055   for (unsigned int i=0; i<length; ++i) {
01056     // Loop over timesamples (i.e. bunch crossings)
01057     for (unsigned int bx=0; bx<nSamples; ++bx) {
01058       colls()->gctInternJets()->push_back( L1GctInternJetData::fromJetClusterMinimal(L1CaloRegionDetId(0,0),id,i,bx,*p));
01059       ++p;
01060       colls()->gctInternJets()->push_back( L1GctInternJetData::fromJetClusterMinimal(L1CaloRegionDetId(0,0),id,i,bx,*p));
01061       ++p;
01062     }
01063   } 
01064 }
01065 
01066 void GctFormatTranslateV38::blockToGctJetPreCluster(const unsigned char * d, const GctBlockHeader& hdr)
01067 {
01068   // Don't want to do this in HLT optimisation mode!
01069   if(hltMode()) { LogDebug("GCT") << "HLT mode - skipping unpack of internal Jet Cands"; return; }
01070 
01071   unsigned int id = hdr.blockId();
01072   unsigned int nSamples = hdr.nSamples();
01073   unsigned int length = hdr.blockLength();
01074 
01075   // Re-interpret pointer to 16 bits so it sees one candidate at a time.
01076   const uint16_t * p = reinterpret_cast<const uint16_t *>(d);
01077 
01078   for (unsigned int i=0; i<length; ++i) {
01079     // Loop over timesamples (i.e. bunch crossings)
01080     for (unsigned int bx=0; bx<nSamples; ++bx) {
01081       colls()->gctInternJets()->push_back( L1GctInternJetData::fromJetPreCluster(L1CaloRegionDetId(0,0),id,i,bx,*p));
01082       ++p;
01083       colls()->gctInternJets()->push_back( L1GctInternJetData::fromJetPreCluster(L1CaloRegionDetId(0,0),id,i,bx,*p));
01084       ++p;
01085     }
01086   } 
01087 }
01088 
01089 void GctFormatTranslateV38::blockToGctInternRingSums(const unsigned char * d, const GctBlockHeader& hdr)
01090 {
01091   // Don't want to do this in HLT optimisation mode!
01092   if(hltMode()) { LogDebug("GCT") << "HLT mode - skipping unpack of internal HF ring data"; return; }
01093 
01094   unsigned int id = hdr.blockId();
01095   unsigned int nSamples = hdr.nSamples();
01096   unsigned int length = hdr.blockLength();
01097 
01098   // Re-interpret pointer to 32 bits 
01099   const uint32_t * p = reinterpret_cast<const uint32_t *>(d);
01100 
01101   for (unsigned int i=0; i<length/2; ++i) {
01102     // Loop over timesamples (i.e. bunch crossings)
01103     for (unsigned int bx=0; bx<nSamples; ++bx) {
01104       colls()->gctInternHFData()->push_back(L1GctInternHFData::fromConcRingSums(id,i,bx,*p));
01105       ++p;
01106     }
01107     for (unsigned int bx=0; bx<nSamples; ++bx) {
01108       colls()->gctInternHFData()->push_back(L1GctInternHFData::fromConcBitCounts(id,i,bx,*p));
01109       ++p;
01110     }  
01111   }
01112 }
01113 
01114 void GctFormatTranslateV38::blockToGctWheelInputInternEtAndRingSums(const unsigned char * d, const GctBlockHeader& hdr)
01115 {
01116   // Don't want to do this in HLT optimisation mode!
01117   if(hltMode()) { LogDebug("GCT") << "HLT mode - skipping unpack of wheel input internal Et sums and HF ring data"; return; }
01118 
01119   unsigned int id = hdr.blockId();
01120   unsigned int nSamples = hdr.nSamples();
01121   unsigned int length = hdr.blockLength();
01122 
01123   // Re-interpret pointer to 32 bits 
01124   const uint32_t * p = reinterpret_cast<const uint32_t *>(d);
01125 
01126   for (unsigned int i=0; i<length; ++i) {
01127     // Loop over timesamples (i.e. bunch crossings)
01128     for (unsigned int bx=0; bx<nSamples; ++bx) {
01129       if (i<3){
01130         colls()->gctInternEtSums()->push_back(L1GctInternEtSum::fromTotalEtOrHt(id,i,bx,*p));
01131       } else if (i>2 && i<9) {
01132         colls()->gctInternEtSums()->push_back(L1GctInternEtSum::fromMissEtxOrEty(id,i,bx,*p));
01133       } else if (i>8 && i<15) {
01134         colls()->gctInternHFData()->push_back(L1GctInternHFData::fromWheelRingSums(id,i,bx,*p));
01135       } else if (i>14){
01136         colls()->gctInternHFData()->push_back(L1GctInternHFData::fromWheelBitCounts(id,i,bx,*p));
01137       }
01138       ++p;
01139     }
01140   }
01141 }
01142 
01143 void GctFormatTranslateV38::blockToGctWheelOutputInternEtAndRingSums(const unsigned char * d, const GctBlockHeader& hdr)
01144 {
01145   // Don't want to do this in HLT optimisation mode!
01146   if(hltMode()) { LogDebug("GCT") << "HLT mode - skipping unpack of wheel output internal Et sums and HF ring data"; return; }
01147 
01148   unsigned int id = hdr.blockId();
01149   unsigned int nSamples = hdr.nSamples();
01150   unsigned int length = hdr.blockLength();
01151 
01152   // Re-interpret pointer to 32 bits 
01153   const uint32_t * p = reinterpret_cast<const uint32_t *>(d);
01154 
01155   for (unsigned int i=0; i<length; ++i) {
01156     // Loop over timesamples (i.e. bunch crossings)
01157     for (unsigned int bx=0; bx<nSamples; ++bx) {
01158       if (i<1){
01159         colls()->gctInternEtSums()->push_back(L1GctInternEtSum::fromTotalEtOrHt(id,i,bx,*p));
01160       } else if (i>0 && i<3) {
01161         colls()->gctInternEtSums()->push_back(L1GctInternEtSum::fromMissEtxOrEty(id,i,bx,*p));
01162       } else if (i>2 && i<5) {
01163         colls()->gctInternHFData()->push_back(L1GctInternHFData::fromWheelRingSums(id,i,bx,*p));
01164       } else if (i>4){
01165         colls()->gctInternHFData()->push_back(L1GctInternHFData::fromWheelBitCounts(id,i,bx,*p));
01166       }
01167       ++p;
01168     }
01169   }
01170 }
01171 
01172 void GctFormatTranslateV38::blockToGctInternHtMissPreWheel(const unsigned char* d, const GctBlockHeader& hdr)
01173 {
01174   // Don't want to do this in HLT optimisation mode!
01175   if(hltMode()) { LogDebug("GCT") << "HLT mode - skipping unpack of pre-wheel internal Missing Ht data"; return; }
01176 
01177   unsigned int id = hdr.blockId();
01178   unsigned int nSamples = hdr.nSamples();
01179   unsigned int length = hdr.blockLength();
01180 
01181   // Re-interpret pointer to 32 bits 
01182   const uint32_t * p = reinterpret_cast<const uint32_t *>(d);
01183   
01184   for (unsigned int iLength=0; iLength < length; ++iLength)
01185   {
01186     // Loop over timesamples (i.e. bunch crossings)
01187     for (unsigned int bx=0; bx<nSamples; ++bx) 
01188     {
01189       colls()->gctInternHtMiss()->push_back(L1GctInternHtMiss::unpackerMissHtxHty(id, iLength, bx, *p));
01190       ++p;
01191     }
01192   }
01193 }
01194 
01195 void GctFormatTranslateV38::blockToGctInternHtMissPostWheel(const unsigned char* d, const GctBlockHeader& hdr)
01196 {
01197   // Don't want to do this in HLT optimisation mode!
01198   if(hltMode()) { LogDebug("GCT") << "HLT mode - skipping unpack of post-wheel internal Missing Ht data"; return; }
01199 
01200   unsigned int id = hdr.blockId();
01201   unsigned int nSamples = hdr.nSamples();
01202   unsigned int length = hdr.blockLength();
01203 
01204   // Re-interpret pointer to 32 bits 
01205   const uint32_t * p = reinterpret_cast<const uint32_t *>(d);
01206 
01207   for (unsigned int iLength=0; iLength < length; ++iLength)
01208   {
01209     // Loop over timesamples (i.e. bunch crossings)
01210     for (unsigned int bx=0; bx<nSamples; ++bx)
01211     {
01212       if(iLength % 2) { colls()->gctInternHtMiss()->push_back(L1GctInternHtMiss::unpackerMissHty(id, iLength, bx, *p)); }  // Hty on odd numbers
01213       else { colls()->gctInternHtMiss()->push_back(L1GctInternHtMiss::unpackerMissHtx(id, iLength, bx, *p)); } // Htx on even numbers
01214       ++p;
01215     }
01216   }
01217 }