CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/EventFilter/GctRawToDigi/src/GctFormatTranslateV35.cc

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