CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_10_patch1/src/L1Trigger/GlobalCaloTrigger/src/L1GlobalCaloTrigger.cc

Go to the documentation of this file.
00001 #include "L1Trigger/GlobalCaloTrigger/interface/L1GlobalCaloTrigger.h"
00002 
00003 #include "CondFormats/L1TObjects/interface/L1GctJetFinderParams.h"
00004 #include "CondFormats/L1TObjects/interface/L1GctChannelMask.h"
00005 
00006 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctJetEtCalibrationLut.h"
00007 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctEmLeafCard.h"
00008 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctWheelJetFpga.h"
00009 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctWheelEnergyFpga.h"
00010 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctJetFinalStage.h"
00011 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctGlobalEnergyAlgos.h"
00012 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctGlobalHfSumAlgos.h"
00013 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctElectronFinalSort.h"
00014 
00015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00016 
00017 using std::vector;
00018 
00019 //DEFINE STATICS
00020 const int L1GlobalCaloTrigger::N_JET_LEAF_CARDS = 6;
00021 const int L1GlobalCaloTrigger::N_EM_LEAF_CARDS = 2;
00022 const int L1GlobalCaloTrigger::N_WHEEL_CARDS = 2;
00023 
00024 // constructor
00025 L1GlobalCaloTrigger::L1GlobalCaloTrigger(const L1GctJetLeafCard::jetFinderType jfType, unsigned jetLeafMask) :
00026   theJetLeafCards(N_JET_LEAF_CARDS),
00027   theJetFinders(N_JET_LEAF_CARDS*3),
00028   theEmLeafCards(N_EM_LEAF_CARDS),
00029   theIsoElectronSorters(N_EM_LEAF_CARDS*2),
00030   theNonIsoElectronSorters(N_EM_LEAF_CARDS*2),
00031   theWheelJetFpgas(N_WHEEL_CARDS),
00032   theWheelEnergyFpgas(N_WHEEL_CARDS),
00033   m_jetFinderParams(0),
00034   m_jetEtCalLuts(),
00035   m_inputChannelMask(0),
00036   m_bxRangeAuto(true),
00037   m_bxStart(0), m_numOfBx(1),
00038   m_allInputEmCands(), m_allInputRegions()  
00039 {
00040 
00041   // construct hardware
00042   build(jfType, jetLeafMask);
00043 }
00044 
00046 L1GlobalCaloTrigger::~L1GlobalCaloTrigger()
00047 {
00048   // Delete the components of the GCT that we made in build()
00049   // (But not the LUTs, since these don't belong to us)
00050 
00051   if (theNonIsoEmFinalStage != 0) delete theNonIsoEmFinalStage;
00052   
00053   if (theIsoEmFinalStage != 0) delete theIsoEmFinalStage;
00054   
00055   if (theEnergyFinalStage != 0) delete theEnergyFinalStage;     
00056   
00057   if (theJetFinalStage != 0) delete theJetFinalStage;                   
00058   
00059   for (unsigned i=0; i<theWheelEnergyFpgas.size(); ++i) { 
00060     if (theWheelEnergyFpgas.at(i) != 0) delete theWheelEnergyFpgas.at(i); }
00061   theWheelEnergyFpgas.clear();
00062   
00063   for (unsigned i=0; i<theWheelJetFpgas.size(); ++i) { 
00064     if (theWheelJetFpgas.at(i) != 0) delete theWheelJetFpgas.at(i); }
00065   theWheelJetFpgas.clear();             
00066 
00067   for (unsigned i=0; i<theEmLeafCards.size(); ++i) { 
00068     if (theEmLeafCards.at(i) != 0) delete theEmLeafCards.at(i); }
00069   theEmLeafCards.clear();
00070 
00071   for (unsigned i=0; i<theJetLeafCards.size(); ++i) { 
00072     if (theJetLeafCards.at(i) != 0) delete theJetLeafCards.at(i); }
00073   theJetLeafCards.clear();
00074   
00075 }
00076 
00081 void L1GlobalCaloTrigger::reset() {
00082 
00083   // Input data
00084   m_allInputEmCands.clear();
00085   m_allInputRegions.clear();
00086 
00087   if (m_bxRangeAuto) {
00088     m_bxStart = 0;
00089     m_numOfBx = 1;
00090   }
00091 
00092   // EM Leaf Card
00093   for (int i=0; i<N_EM_LEAF_CARDS; i++) {
00094     theEmLeafCards.at(i)->reset();
00095   }
00096 
00097   // Jet Leaf cards
00098   for (int i=0; i<N_JET_LEAF_CARDS; i++) {
00099     theJetLeafCards.at(i)->reset();
00100   }
00101 
00102   // Jet Finders
00103   for (int i=0; i<N_JET_LEAF_CARDS*3; i++) {
00104     theJetFinders.at(i)->reset();
00105   }
00106 
00107   // Wheel Cards
00108   for (int i=0; i<N_WHEEL_CARDS; i++) {
00109     theWheelJetFpgas.at(i)->reset();
00110   }
00111 
00112   for (int i=0; i<N_WHEEL_CARDS; i++) {
00113     theWheelEnergyFpgas.at(i)->reset();
00114   }
00115 
00116   // Electron Final Stage
00117   theIsoEmFinalStage->reset();
00118   theNonIsoEmFinalStage->reset();
00119 
00120   // Jet Final Stage
00121   theJetFinalStage->reset();
00122 
00123   // Energy Final Stage
00124   theEnergyFinalStage->reset();
00125 
00126 }
00127 
00128 void L1GlobalCaloTrigger::process() {
00129 
00130   // Shouldn't get here unless the setup has been completed
00131   if (setupOk()) {
00132 
00134     sortInputData();
00135     // Extract the earliest and latest bunch crossing
00136     // in the input if required, and forward to the processors
00137     // to determine the size of the output vectors
00138     bxSetup();
00139 
00140     vector<L1CaloEmCand>::iterator emc=m_allInputEmCands.begin();
00141     vector<L1CaloRegion>::iterator rgn=m_allInputRegions.begin();
00142     int bx = m_bxStart;
00143 
00144     // Loop over bunch crossings
00145     for (int i=0; i<m_numOfBx; i++) {
00146       // Perform partial reset (reset processing logic but preserve pipeline contents)
00147       bxReset(bx);
00148       // Fill input data into processors for this bunch crossing
00149       fillEmCands(emc, bx);
00150       fillRegions(rgn, bx);
00151       // Process this bunch crossing
00152       bxProcess(bx);
00153       bx++;
00154     }
00155   }
00156 }
00157 
00159 void L1GlobalCaloTrigger::sortInputData() {
00160   std::sort(m_allInputEmCands.begin(), m_allInputEmCands.end(), emcBxComparator);
00161   std::sort(m_allInputRegions.begin(), m_allInputRegions.end(), rgnBxComparator);
00162 }
00163 
00165 void L1GlobalCaloTrigger::bxSetup() {
00166   // Assume input data have been sorted by bunch crossing number
00167   if (m_bxRangeAuto) {
00168     // Find parameters defining the range of bunch crossings to be processed
00169     int16_t firstBxEmCand = (m_allInputEmCands.size()==0 ? 0 : m_allInputEmCands.front().bx() );
00170     int16_t firstBxRegion = (m_allInputRegions.size()==0 ? 0 : m_allInputRegions.front().bx() );
00171     int16_t  lastBxEmCand = (m_allInputEmCands.size()==0 ? 0 : m_allInputEmCands.back().bx() );
00172     int16_t  lastBxRegion = (m_allInputRegions.size()==0 ? 0 : m_allInputRegions.back().bx() );
00173     m_bxStart = std::min(firstBxEmCand, firstBxRegion);
00174     m_numOfBx = std::max( lastBxEmCand,  lastBxRegion) - m_bxStart + 1;
00175   } else {
00176     // Remove any input from before the start of the requested range
00177     for (vector<L1CaloEmCand>::iterator emc=m_allInputEmCands.begin(); emc != m_allInputEmCands.end(); emc++) {
00178       if (emc->bx() >= m_bxStart) break;
00179       m_allInputEmCands.erase(emc);
00180     }
00181 
00182     for (vector<L1CaloRegion>::iterator rgn=m_allInputRegions.begin(); rgn != m_allInputRegions.end(); rgn++) {
00183       if (rgn->bx() >= m_bxStart) break;
00184       m_allInputRegions.erase(rgn);
00185     }
00186   }
00187 
00188   // Setup pipeline lengths
00189   // EM Leaf Card
00190   for (int i=0; i<N_EM_LEAF_CARDS; i++) {
00191     theEmLeafCards.at(i)->setBxRange(m_bxStart, m_numOfBx);
00192   }
00193 
00194   // Jet Leaf cards
00195   for (int i=0; i<N_JET_LEAF_CARDS; i++) {
00196     theJetLeafCards.at(i)->setBxRange(m_bxStart, m_numOfBx);
00197   }
00198 
00199   // Wheel Cards
00200   for (int i=0; i<N_WHEEL_CARDS; i++) {
00201     theWheelJetFpgas.at(i)->setBxRange(m_bxStart, m_numOfBx);
00202   }
00203 
00204   for (int i=0; i<N_WHEEL_CARDS; i++) {
00205     theWheelEnergyFpgas.at(i)->setBxRange(m_bxStart, m_numOfBx);
00206   }
00207 
00208   // Electron Final Stage
00209   theIsoEmFinalStage->setBxRange(m_bxStart, m_numOfBx);
00210   theNonIsoEmFinalStage->setBxRange(m_bxStart, m_numOfBx);
00211 
00212   // Jet Final Stage
00213   theJetFinalStage->setBxRange(m_bxStart, m_numOfBx);
00214 
00215   // Energy Final Stage
00216   theEnergyFinalStage->setBxRange(m_bxStart, m_numOfBx);
00217 }
00218 
00220 void L1GlobalCaloTrigger::bxReset(const int bx) {
00221   // EM Leaf Card
00222   for (int i=0; i<N_EM_LEAF_CARDS; i++) {
00223     theEmLeafCards.at(i)->setNextBx(bx);
00224   }
00225 
00226   // Jet Leaf cards
00227   for (int i=0; i<N_JET_LEAF_CARDS; i++) {
00228     theJetLeafCards.at(i)->setNextBx(bx);
00229   }
00230 
00231   // Wheel Cards
00232   for (int i=0; i<N_WHEEL_CARDS; i++) {
00233     theWheelJetFpgas.at(i)->setNextBx(bx);
00234   }
00235 
00236   for (int i=0; i<N_WHEEL_CARDS; i++) {
00237     theWheelEnergyFpgas.at(i)->setNextBx(bx);
00238   }
00239 
00240   // Electron Final Stage
00241   theIsoEmFinalStage->setNextBx(bx);
00242   theNonIsoEmFinalStage->setNextBx(bx);
00243 
00244   // Jet Final Stage
00245   theJetFinalStage->setNextBx(bx);
00246 
00247   // Energy Final Stage
00248   theEnergyFinalStage->setNextBx(bx);
00249 
00250 }
00251 
00253 void L1GlobalCaloTrigger::bxProcess(const int bx) {
00254 
00255   // EM Leaf Card
00256   for (int i=0; i<N_EM_LEAF_CARDS; i++) {
00257     theEmLeafCards.at(i)->fetchInput();
00258     theEmLeafCards.at(i)->process();
00259   }
00260 
00261   // Jet Leaf cards - first stage processing
00262   for (int i=0; i<N_JET_LEAF_CARDS; i++) {
00263     theJetLeafCards.at(i)->fetchInput();
00264   }
00265 
00266   // Jet Leaf cards - second stage processing
00267   for (int i=0; i<N_JET_LEAF_CARDS; i++) {
00268     theJetLeafCards.at(i)->process();
00269   }
00270 
00271   // Wheel Cards
00272   for (int i=0; i<N_WHEEL_CARDS; i++) {
00273     theWheelJetFpgas.at(i)->fetchInput();
00274     theWheelJetFpgas.at(i)->process();
00275   }
00276 
00277   for (int i=0; i<N_WHEEL_CARDS; i++) {
00278     theWheelEnergyFpgas.at(i)->fetchInput();
00279     theWheelEnergyFpgas.at(i)->process();
00280   }
00281 
00282   // Electron Final Stage
00283   theIsoEmFinalStage->fetchInput();
00284   theIsoEmFinalStage->process();
00285 
00286   theNonIsoEmFinalStage->fetchInput();
00287   theNonIsoEmFinalStage->process();
00288 
00289 
00290   // Jet Final Stage
00291   theJetFinalStage->fetchInput();
00292   theJetFinalStage->process();
00293 
00294   // Energy Final Stage
00295   theEnergyFinalStage->fetchInput();
00296   theEnergyFinalStage->process();
00297 
00298 }
00299 
00304 void L1GlobalCaloTrigger::setJetFinderParams(const L1GctJetFinderParams* const jfpars) {
00305 
00306   // Some parameters not (yet?) implemented
00307   if ((jfpars->getCenForJetEtaBoundary()==7) &&
00308       (jfpars->getCenJetEtSeedGct()==jfpars->getTauJetEtSeedGct())) { 
00309 
00310     m_jetFinderParams = jfpars;
00311     // Need to propagate the new parameters to all the JetFinders
00312     for (int i=0; i<N_JET_LEAF_CARDS; i++) {
00313       theJetLeafCards.at(i)->getJetFinderA()->setJetFinderParams(jfpars);
00314       theJetLeafCards.at(i)->getJetFinderB()->setJetFinderParams(jfpars);
00315       theJetLeafCards.at(i)->getJetFinderC()->setJetFinderParams(jfpars);
00316     }
00317     // Also send to the final energy calculation (for missing Ht)
00318     theEnergyFinalStage->setJetFinderParams(jfpars);
00319   }
00320 }
00321 
00323 void L1GlobalCaloTrigger::setJetEtCalibrationLuts(const L1GlobalCaloTrigger::lutPtrVector& jfluts) {
00324 
00325   m_jetEtCalLuts = jfluts;
00326   // Need to propagate the new lut to all the JetFinders
00327   for (int i=0; i<N_JET_LEAF_CARDS; i++) {
00328     theJetLeafCards.at(i)->getJetFinderA()->setJetEtCalibrationLuts(jfluts);
00329     theJetLeafCards.at(i)->getJetFinderB()->setJetEtCalibrationLuts(jfluts);
00330     theJetLeafCards.at(i)->getJetFinderC()->setJetEtCalibrationLuts(jfluts);
00331   }
00332 }
00333 
00335 void L1GlobalCaloTrigger::setupTauAlgo(const bool useImprovedAlgo, const bool ignoreVetoBitsForIsolation)
00336 {
00337   // Need to propagate the new parameters to all the JetFinders
00338   for (int i=0; i<N_JET_LEAF_CARDS; i++) {
00339     theJetLeafCards.at(i)->getJetFinderA()->setupTauAlgo(useImprovedAlgo, ignoreVetoBitsForIsolation);
00340     theJetLeafCards.at(i)->getJetFinderB()->setupTauAlgo(useImprovedAlgo, ignoreVetoBitsForIsolation);
00341     theJetLeafCards.at(i)->getJetFinderC()->setupTauAlgo(useImprovedAlgo, ignoreVetoBitsForIsolation);
00342   }
00343 }
00344 
00346 void L1GlobalCaloTrigger::setHtMissScale(const L1CaloEtScale* const scale) {
00347   if (theEnergyFinalStage != 0) {
00348     theEnergyFinalStage->setHtMissScale(scale);
00349   }
00350 }
00351 
00353 void L1GlobalCaloTrigger::setupHfSumLuts(const L1CaloEtScale* const scale) {
00354   if (getHfSumProcessor() != 0) {
00355     getHfSumProcessor()->setupLuts(scale);
00356   }
00357 }
00358 
00360 void L1GlobalCaloTrigger::setChannelMask(const L1GctChannelMask* const mask) {
00361   m_inputChannelMask = mask;
00362   // Need to propagate the new mask to all the JetFinders
00363   for (int i=0; i<N_JET_LEAF_CARDS; i++) {
00364     theJetLeafCards.at(i)->getJetFinderA()->setEnergySumMasks(mask);
00365     theJetLeafCards.at(i)->getJetFinderB()->setEnergySumMasks(mask);
00366     theJetLeafCards.at(i)->getJetFinderC()->setEnergySumMasks(mask);
00367   }
00368 }
00369 
00371 bool L1GlobalCaloTrigger::setupOk() const { 
00372   bool result = true;
00373   result &= (m_inputChannelMask != 0);
00374   // EM Leaf Card
00375   for (int i=0; i<N_EM_LEAF_CARDS; i++) {
00376     result &= theEmLeafCards.at(i)->setupOk();
00377   }
00378 
00379   // Jet Leaf cards
00380   for (int i=0; i<N_JET_LEAF_CARDS; i++) {
00381     result &= theJetLeafCards.at(i)->setupOk();
00382   }
00383 
00384   // Jet Finders
00385   for (int i=0; i<N_JET_LEAF_CARDS*3; i++) {
00386     result &= theJetFinders.at(i)->setupOk();
00387   }
00388 
00389   // Wheel Cards
00390   for (int i=0; i<N_WHEEL_CARDS; i++) {
00391     result &= theWheelJetFpgas.at(i)->setupOk();
00392   }
00393 
00394   for (int i=0; i<N_WHEEL_CARDS; i++) {
00395     result &= theWheelEnergyFpgas.at(i)->setupOk();
00396   }
00397 
00398   // Electron Final Stage
00399   result &= theIsoEmFinalStage->setupOk();
00400   result &= theNonIsoEmFinalStage->setupOk();
00401 
00402   // Jet Final Stage
00403   result &= theJetFinalStage->setupOk();
00404 
00405   // Energy Final Stage
00406   result &= theEnergyFinalStage->setupOk();
00407 
00408   // All done.
00409   return result;
00410 }
00411 
00413 L1GctGlobalHfSumAlgos* L1GlobalCaloTrigger::getHfSumProcessor() const
00414 {
00415   L1GctGlobalHfSumAlgos* result = 0;
00416   if (theEnergyFinalStage !=0) {
00417     result = theEnergyFinalStage->getHfSumProcessor();
00418   }
00419   return result;
00420 }
00421 
00424 void L1GlobalCaloTrigger::setBxRange(const int firstBx, const int lastBx) { m_bxStart = firstBx; m_numOfBx = lastBx - firstBx + 1; m_bxRangeAuto = false; }
00426 void L1GlobalCaloTrigger::setBxRangeSymmetric(const int numOfBx) { m_bxStart = -numOfBx; m_numOfBx = 2*numOfBx + 1; m_bxRangeAuto = false; }
00428 void L1GlobalCaloTrigger::setBxRangeAutomatic()  { m_bxStart = 0; m_numOfBx = 1; m_bxRangeAuto = true; }
00429 
00435 void L1GlobalCaloTrigger::fillRegions(const vector<L1CaloRegion>& rgn)
00436 {
00437   // To enable multiple bunch crossing operation, we copy the input regions into a vector,
00438   // from which they will be extracted one bunch crossing at a time and sent to the processors
00439   vector<L1CaloRegion>::iterator itr=m_allInputRegions.end();
00440   m_allInputRegions.insert(itr, rgn.begin(), rgn.end());
00441 }
00442 
00444 void L1GlobalCaloTrigger::fillEmCands(const vector<L1CaloEmCand>& em)
00445 {
00446   // To enable multiple bunch crossing operation, we copy the input electrons into a vector,
00447   // from which they will be extracted one bunch crossing at a time and sent to the processors
00448   vector<L1CaloEmCand>::iterator itr=m_allInputEmCands.end();
00449   m_allInputEmCands.insert(itr, em.begin(), em.end());
00450 }
00451 
00453 void L1GlobalCaloTrigger::fillRegions(vector<L1CaloRegion>::iterator& rgn, const int bx) {
00454   while (rgn != m_allInputRegions.end() && rgn->bx() == bx) {
00455     setRegion(*rgn++);
00456   }
00457 }
00458 
00460 void L1GlobalCaloTrigger::fillEmCands(vector<L1CaloEmCand>::iterator& emc, const int bx){
00461   while (emc != m_allInputEmCands.end() && emc->bx() == bx) {
00462     if (emc->isolated()) {
00463       setIsoEm(*emc);
00464     } else {
00465       setNonIsoEm(*emc);
00466     } 
00467     emc++;
00468   }
00469 }
00470 
00474 void L1GlobalCaloTrigger::setRegion(const L1CaloRegion& region) 
00475 {
00476   if ( !m_inputChannelMask->regionMask( region.gctEta(), region.gctPhi() ) ) {
00477     unsigned crate = region.rctCrate();
00478     // Find the relevant jetFinders
00479     static const unsigned NPHI = L1CaloRegionDetId::N_PHI/2;
00480     unsigned prevphi = crate % NPHI;
00481     unsigned thisphi = (crate+1) % NPHI;
00482     unsigned nextphi = (crate+2) % NPHI;
00483 
00484     // Send the region to six jetFinders.
00485     theJetFinders.at(thisphi)->setInputRegion(region);
00486     theJetFinders.at(nextphi)->setInputRegion(region);
00487     theJetFinders.at(prevphi)->setInputRegion(region);
00488     theJetFinders.at(thisphi+NPHI)->setInputRegion(region);
00489     theJetFinders.at(nextphi+NPHI)->setInputRegion(region);
00490     theJetFinders.at(prevphi+NPHI)->setInputRegion(region);
00491   }
00492 }
00493 
00496 void L1GlobalCaloTrigger::setRegion(const unsigned et, const unsigned ieta, const unsigned iphi,
00497                                     const bool overFlow, const bool fineGrain)
00498 {
00499   //  L1CaloRegion temp = L1CaloRegion::makeRegionFromGctIndices(et, overFlow, fineGrain, false, false, ieta, iphi, 0);
00500   L1CaloRegion temp(et, overFlow, fineGrain, false, false, ieta, iphi, 0);
00501   setRegion(temp);
00502 }
00503 
00507 void L1GlobalCaloTrigger::setIsoEm(const L1CaloEmCand& em) 
00508 {
00509   if ( !m_inputChannelMask->emCrateMask( em.rctCrate() ) )
00510     theIsoElectronSorters.at(sorterNo(em))->setInputEmCand(em);
00511 }
00512 
00516 void L1GlobalCaloTrigger::setNonIsoEm(const L1CaloEmCand& em) 
00517 {
00518   if ( !m_inputChannelMask->emCrateMask( em.rctCrate() ) )
00519     theNonIsoElectronSorters.at(sorterNo(em))->setInputEmCand(em);
00520 }
00521 
00525 void L1GlobalCaloTrigger::print() {
00526 
00527   using edm::LogInfo;
00528   using std::endl;
00529 
00530   LogInfo("L1GlobalCaloTrigger") << "=== Global Calo Trigger ===" << endl;
00531   LogInfo("L1GlobalCaloTrigger") << "=== START DEBUG OUTPUT  ===" << endl;
00532 
00533   LogInfo("L1GlobalCaloTrigger") << endl;
00534   LogInfo("L1GlobalCaloTrigger") << "N Jet Leaf Cards " << theJetLeafCards.size() << endl;
00535   LogInfo("L1GlobalCaloTrigger") << "N Wheel Jet Fpgas " << theWheelJetFpgas.size() << endl;
00536   LogInfo("L1GlobalCaloTrigger") << "N Wheel Energy Fpgas " << theWheelEnergyFpgas.size() << endl;
00537   LogInfo("L1GlobalCaloTrigger") << "N Em Leaf Cards " << theEmLeafCards.size() << endl;
00538   LogInfo("L1GlobalCaloTrigger") << endl;
00539 
00540   for (unsigned i=0; i<theJetLeafCards.size(); i++) {
00541     LogInfo("L1GlobalCaloTrigger") << "Jet Leaf Card " << i << " : " << theJetLeafCards.at(i) << endl;
00542     LogInfo("L1GlobalCaloTrigger") << (*theJetLeafCards.at(i));
00543   }
00544   LogInfo("L1GlobalCaloTrigger") << endl;
00545 
00546   for (unsigned i=0; i<theWheelJetFpgas.size(); i++) {
00547     LogInfo("L1GlobalCaloTrigger") << "Wheel Jet FPGA " << i << " : " << theWheelJetFpgas.at(i) << endl; 
00548     LogInfo("L1GlobalCaloTrigger") << (*theWheelJetFpgas.at(i));
00549   }
00550   LogInfo("L1GlobalCaloTrigger") << endl;
00551 
00552   for (unsigned i=0; i<theWheelEnergyFpgas.size(); i++) {
00553     LogInfo("L1GlobalCaloTrigger") << "Wheel Energy FPGA " << i <<" : " << theWheelEnergyFpgas.at(i) << endl; 
00554     LogInfo("L1GlobalCaloTrigger") << (*theWheelEnergyFpgas.at(i));
00555   }
00556   LogInfo("L1GlobalCaloTrigger") << endl;
00557 
00558   LogInfo("L1GlobalCaloTrigger") << (*theJetFinalStage);
00559   LogInfo("L1GlobalCaloTrigger") << endl;
00560 
00561   LogInfo("L1GlobalCaloTrigger") << (*theEnergyFinalStage);
00562   LogInfo("L1GlobalCaloTrigger") << endl;
00563 
00564   for (unsigned i=0; i<theEmLeafCards.size(); i++) {
00565     LogInfo("L1GlobalCaloTrigger") << ( (i==0) ? "Positive eta " : "Negative eta " ); 
00566     LogInfo("L1GlobalCaloTrigger") << "EM Leaf Card " << i << " : " << theEmLeafCards.at(i) << endl;
00567     LogInfo("L1GlobalCaloTrigger") << (*theEmLeafCards.at(i));
00568   }
00569   LogInfo("L1GlobalCaloTrigger") << endl;
00570 
00571   LogInfo("L1GlobalCaloTrigger") << (*theIsoEmFinalStage);
00572   LogInfo("L1GlobalCaloTrigger") << endl;
00573 
00574   LogInfo("L1GlobalCaloTrigger") << (*theNonIsoEmFinalStage);
00575 
00576   LogInfo("L1GlobalCaloTrigger") << "=== Global Calo Trigger ===" << endl;
00577   LogInfo("L1GlobalCaloTrigger") << "===  END DEBUG OUTPUT   ===" << endl;
00578  
00579 }
00580 
00584 // isolated EM outputs
00585 L1GctEmCandCollection L1GlobalCaloTrigger::getIsoElectrons() const { 
00586   return theIsoEmFinalStage->getOutputCands();
00587 }       
00588 
00589 // non isolated EM outputs
00590 L1GctEmCandCollection L1GlobalCaloTrigger::getNonIsoElectrons() const {
00591   return theNonIsoEmFinalStage->getOutputCands(); 
00592 }
00593 
00594 // central jet outputs to GT
00595 L1GctJetCandCollection L1GlobalCaloTrigger::getCentralJets() const {
00596   return theJetFinalStage->getCentralJets();
00597 }
00598 
00599 // forward jet outputs to GT
00600 L1GctJetCandCollection L1GlobalCaloTrigger::getForwardJets() const { 
00601   return theJetFinalStage->getForwardJets(); 
00602 }
00603 
00604 // tau jet outputs to GT
00605 L1GctJetCandCollection L1GlobalCaloTrigger::getTauJets() const { 
00606   return theJetFinalStage->getTauJets(); 
00607 }
00608 
00610 L1GctInternJetDataCollection L1GlobalCaloTrigger::getInternalJets() const {
00611   L1GctInternJetDataCollection allJets, jfJets;
00612 
00613   // Loop over jetfinders, find the internal jets and add them to the list
00614   for (unsigned jf=0; jf<theJetFinders.size(); jf++) {
00615     jfJets = theJetFinders.at(jf)->getInternalJets();
00616     allJets.insert(allJets.end(), jfJets.begin(), jfJets.end());
00617   }
00618 
00619   return allJets;
00620 }
00621 
00622 // total Et output
00623 L1GctEtTotalCollection L1GlobalCaloTrigger::getEtSumCollection() const {
00624   L1GctEtTotalCollection result(m_numOfBx);
00625   int bx = m_bxStart;
00626   for (int i=0; i<m_numOfBx; i++) {
00627     L1GctEtTotal temp(theEnergyFinalStage->getEtSumColl().at(i).value(),
00628                       theEnergyFinalStage->getEtSumColl().at(i).overFlow(),
00629                       bx++ );
00630     result.at(i) = temp;
00631   }
00632   return result;
00633 }
00634 
00635 L1GctEtHadCollection   L1GlobalCaloTrigger::getEtHadCollection() const {
00636   L1GctEtHadCollection result(m_numOfBx);
00637   int bx = m_bxStart;
00638   for (int i=0; i<m_numOfBx; i++) {
00639     L1GctEtHad temp(theEnergyFinalStage->getEtHadColl().at(i).value(),
00640                     theEnergyFinalStage->getEtHadColl().at(i).overFlow(),
00641                     bx++ );
00642     result.at(i) = temp;
00643   }
00644   return result;
00645 }
00646 
00647 L1GctEtMissCollection  L1GlobalCaloTrigger::getEtMissCollection() const {
00648   L1GctEtMissCollection result(m_numOfBx);
00649   int bx = m_bxStart;
00650   for (int i=0; i<m_numOfBx; i++) {
00651     L1GctEtMiss temp(theEnergyFinalStage->getEtMissColl().at(i).value(),
00652                      theEnergyFinalStage->getEtMissPhiColl().at(i).value(),
00653                      theEnergyFinalStage->getEtMissColl().at(i).overFlow(),
00654                      bx++ );
00655     result.at(i) = temp;
00656   }
00657   return result;
00658 }
00659 
00660 L1GctHtMissCollection  L1GlobalCaloTrigger::getHtMissCollection() const {
00661   L1GctHtMissCollection result(m_numOfBx);
00662   int bx = m_bxStart;
00663   for (int i=0; i<m_numOfBx; i++) {
00664     L1GctHtMiss temp(theEnergyFinalStage->getHtMissColl().at(i).value(),
00665                      theEnergyFinalStage->getHtMissPhiColl().at(i).value(),
00666                      theEnergyFinalStage->getHtMissColl().at(i).overFlow(),
00667                      bx++ );
00668     result.at(i) = temp;
00669   }
00670   return result;
00671 }
00672 
00673 L1GctInternEtSumCollection L1GlobalCaloTrigger::getInternalEtSums() const
00674 {
00675   L1GctInternEtSumCollection allSums, procSums;
00676 
00677   // Go through all the processor types that process et sums
00678   // JetFinders
00679   for (unsigned jf=0; jf<theJetFinders.size(); jf++) {
00680     procSums = theJetFinders.at(jf)->getInternalEtSums();
00681     allSums.insert(allSums.end(), procSums.begin(), procSums.end());
00682   }
00683 
00684   // Jet Leaf cards
00685   for (int i=0; i<N_JET_LEAF_CARDS; i++) {
00686     procSums = theJetLeafCards.at(i)->getInternalEtSums();
00687     allSums.insert(allSums.end(), procSums.begin(), procSums.end());
00688   }
00689 
00690   // Wheel Cards
00691   for (int i=0; i<N_WHEEL_CARDS; i++) {
00692     procSums = theWheelEnergyFpgas.at(i)->getInternalEtSums();
00693     allSums.insert(allSums.end(), procSums.begin(), procSums.end());
00694   }
00695 
00696   return allSums;
00697 }
00698 
00699 L1GctInternHtMissCollection L1GlobalCaloTrigger::getInternalHtMiss() const
00700 {
00701   L1GctInternHtMissCollection allSums, procSums;
00702 
00703   // Go through all the processor types that process et sums
00704   // JetFinders
00705   for (unsigned jf=0; jf<theJetFinders.size(); jf++) {
00706     procSums = theJetFinders.at(jf)->getInternalHtMiss();
00707     allSums.insert(allSums.end(), procSums.begin(), procSums.end());
00708   }
00709 
00710   // Jet Leaf cards
00711   for (int i=0; i<N_JET_LEAF_CARDS; i++) {
00712     procSums = theJetLeafCards.at(i)->getInternalHtMiss();
00713     allSums.insert(allSums.end(), procSums.begin(), procSums.end());
00714   }
00715 
00716   // Wheel Cards
00717   for (int i=0; i<N_WHEEL_CARDS; i++) {
00718     procSums = theWheelJetFpgas.at(i)->getInternalHtMiss();
00719     allSums.insert(allSums.end(), procSums.begin(), procSums.end());
00720   }
00721 
00722   return allSums;
00723 }
00724 
00725 
00726 L1GctHFBitCountsCollection L1GlobalCaloTrigger::getHFBitCountsCollection() const {
00727   L1GctHFBitCountsCollection result(m_numOfBx);
00728   if (getHfSumProcessor() != 0) {
00729     int bx = m_bxStart;
00730     for (int i=0; i<m_numOfBx; i++) {
00731       L1GctHFBitCounts temp =
00732         L1GctHFBitCounts::fromGctEmulator(static_cast<int16_t>(bx),
00733                                           getHfSumProcessor()->hfSumsOutput(L1GctHfEtSumsLut::bitCountPosEtaRing1).at(i),
00734                                           getHfSumProcessor()->hfSumsOutput(L1GctHfEtSumsLut::bitCountNegEtaRing1).at(i),
00735                                           getHfSumProcessor()->hfSumsOutput(L1GctHfEtSumsLut::bitCountPosEtaRing2).at(i),
00736                                           getHfSumProcessor()->hfSumsOutput(L1GctHfEtSumsLut::bitCountNegEtaRing2).at(i));
00737       result.at(i) = temp;
00738       bx++;
00739     }
00740   }
00741   return result;
00742 }
00743 
00744 L1GctHFRingEtSumsCollection L1GlobalCaloTrigger::getHFRingEtSumsCollection() const {
00745   L1GctHFRingEtSumsCollection result(m_numOfBx);
00746   if (getHfSumProcessor() != 0) {
00747     int bx = m_bxStart;
00748     for (int i=0; i<m_numOfBx; i++) {
00749       L1GctHFRingEtSums temp =
00750         L1GctHFRingEtSums::fromGctEmulator(static_cast<int16_t>(bx),
00751                                            getHfSumProcessor()->hfSumsOutput(L1GctHfEtSumsLut::etSumPosEtaRing1).at(i),
00752                                            getHfSumProcessor()->hfSumsOutput(L1GctHfEtSumsLut::etSumNegEtaRing1).at(i),
00753                                            getHfSumProcessor()->hfSumsOutput(L1GctHfEtSumsLut::etSumPosEtaRing2).at(i),
00754                                            getHfSumProcessor()->hfSumsOutput(L1GctHfEtSumsLut::etSumNegEtaRing2).at(i));
00755       result.at(i) = temp;
00756       bx++;
00757     }
00758   }
00759   return result;
00760 }
00761 
00762 
00764 void L1GlobalCaloTrigger::setVerbose() {
00765   // EM Leaf Card
00766   for (int i=0; i<N_EM_LEAF_CARDS; i++) {
00767     theEmLeafCards.at(i)->setVerbose();
00768   }
00769 
00770   // Jet Leaf cards
00771   for (int i=0; i<N_JET_LEAF_CARDS; i++) {
00772     theJetLeafCards.at(i)->setVerbose();
00773   }
00774 
00775   // Jet Finders
00776   for (int i=0; i<N_JET_LEAF_CARDS*3; i++) {
00777     theJetFinders.at(i)->setVerbose();
00778   }
00779 
00780   // Wheel Cards
00781   for (int i=0; i<N_WHEEL_CARDS; i++) {
00782     theWheelJetFpgas.at(i)->setVerbose();
00783   }
00784 
00785   for (int i=0; i<N_WHEEL_CARDS; i++) {
00786     theWheelEnergyFpgas.at(i)->setVerbose();
00787   }
00788 
00789   // Electron Final Stage
00790   theIsoEmFinalStage->setVerbose();
00791   theNonIsoEmFinalStage->setVerbose();
00792 
00793   // Jet Final Stage
00794   theJetFinalStage->setVerbose();
00795 
00796   // Energy Final Stage
00797   theEnergyFinalStage->setVerbose();
00798 }
00799 
00800 void L1GlobalCaloTrigger::setTerse() {
00801   // EM Leaf Card
00802   for (int i=0; i<N_EM_LEAF_CARDS; i++) {
00803     theEmLeafCards.at(i)->setTerse();
00804   }
00805 
00806   // Jet Leaf cards
00807   for (int i=0; i<N_JET_LEAF_CARDS; i++) {
00808     theJetLeafCards.at(i)->setTerse();
00809   }
00810 
00811   // Jet Finders
00812   for (int i=0; i<N_JET_LEAF_CARDS*3; i++) {
00813     theJetFinders.at(i)->setTerse();
00814   }
00815 
00816   // Wheel Cards
00817   for (int i=0; i<N_WHEEL_CARDS; i++) {
00818     theWheelJetFpgas.at(i)->setTerse();
00819   }
00820 
00821   for (int i=0; i<N_WHEEL_CARDS; i++) {
00822     theWheelEnergyFpgas.at(i)->setTerse();
00823   }
00824 
00825   // Electron Final Stage
00826   theIsoEmFinalStage->setTerse();
00827   theNonIsoEmFinalStage->setTerse();
00828 
00829   // Jet Final Stage
00830   theJetFinalStage->setTerse();
00831 
00832   // Energy Final Stage
00833   theEnergyFinalStage->setTerse();
00834 }
00835 
00836 /* PRIVATE METHODS */
00837 
00838 // instantiate hardware/algorithms
00839 void L1GlobalCaloTrigger::build(L1GctJetLeafCard::jetFinderType jfType, unsigned jetLeafMask) {
00840 
00841   // The first half of the jet leaf cards are at negative eta,
00842   // followed by positive eta
00843   // Jet Leaf cards
00844   if (jetLeafMask==0) {
00845     for (int jlc=0; jlc<N_JET_LEAF_CARDS; jlc++) {
00846       theJetLeafCards.at(jlc) = new L1GctJetLeafCard(jlc,jlc % 3, jfType);
00847       theJetFinders.at( 3*jlc ) = theJetLeafCards.at(jlc)->getJetFinderA();
00848       theJetFinders.at(3*jlc+1) = theJetLeafCards.at(jlc)->getJetFinderB();
00849       theJetFinders.at(3*jlc+2) = theJetLeafCards.at(jlc)->getJetFinderC();
00850     }
00851   } else {
00852     // Setup for hardware testing with reduced number of leaf cards
00853     unsigned mask = jetLeafMask;
00854     for (int jlc=0; jlc<N_JET_LEAF_CARDS; jlc++) {
00855       if ((mask&1) == 0) {
00856         theJetLeafCards.at(jlc) = new L1GctJetLeafCard(jlc,jlc % 3, jfType);
00857       } else {
00858         theJetLeafCards.at(jlc) = new L1GctJetLeafCard(jlc,jlc % 3, L1GctJetLeafCard::nullJetFinder);
00859       }
00860       theJetFinders.at( 3*jlc ) = theJetLeafCards.at(jlc)->getJetFinderA();
00861       theJetFinders.at(3*jlc+1) = theJetLeafCards.at(jlc)->getJetFinderB();
00862       theJetFinders.at(3*jlc+2) = theJetLeafCards.at(jlc)->getJetFinderC();
00863       mask = mask >> 1;
00864     }
00865   }
00866 
00867   //Link jet leaf cards together
00868   vector<L1GctJetLeafCard*> neighbours(2);
00869   for (int jlc=0 ; jlc<N_JET_LEAF_CARDS/2; jlc++) {
00870     // Define local constant for ease of typing
00871     static const int NL = N_JET_LEAF_CARDS/2;
00872     int nlc = (jlc+1)%NL;
00873     int mlc = (jlc+(NL-1))%NL;
00874     neighbours.at(0) = theJetLeafCards.at(mlc);
00875     neighbours.at(1) = theJetLeafCards.at(nlc);
00876     theJetLeafCards.at(jlc)->setNeighbourLeafCards(neighbours);
00877     neighbours.at(0) = theJetLeafCards.at(NL+mlc);
00878     neighbours.at(1) = theJetLeafCards.at(NL+nlc);
00879     theJetLeafCards.at(NL+jlc)->setNeighbourLeafCards(neighbours);
00880   }
00881 
00882   // EM leaf cards  
00883   // Card 0 is positive eta, card 1 is negative eta
00884   for (int i=0; i<N_EM_LEAF_CARDS; i++) {
00885     theEmLeafCards.at(i) = new L1GctEmLeafCard(i);
00886     theIsoElectronSorters.at( 2*i ) = theEmLeafCards.at(i)->getIsoElectronSorterU1();
00887     theIsoElectronSorters.at(2*i+1) = theEmLeafCards.at(i)->getIsoElectronSorterU2();
00888     theNonIsoElectronSorters.at( 2*i ) = theEmLeafCards.at(i)->getNonIsoElectronSorterU1();
00889     theNonIsoElectronSorters.at(2*i+1) = theEmLeafCards.at(i)->getNonIsoElectronSorterU2();
00890   }
00891 
00892    // Wheel Fpgas
00893    vector<L1GctJetLeafCard*> wheelJetLeafCards(3);
00894    vector<L1GctJetLeafCard*> wheelEnergyLeafCards(3);
00895 
00896    // The first wheel card is at negative eta,
00897    // the second one is at positive eta
00898    for (int i=0; i<N_WHEEL_CARDS; i++) {
00899      for (int j=0; j<3; j++) {
00900        wheelJetLeafCards.at(j)=theJetLeafCards.at(i*3+j);
00901        wheelEnergyLeafCards.at(j)=theJetLeafCards.at(i*3+j);
00902      }
00903      theWheelJetFpgas.at(i)    = new L1GctWheelJetFpga   (i,wheelJetLeafCards);
00904      theWheelEnergyFpgas.at(i) = new L1GctWheelEnergyFpga(i,wheelEnergyLeafCards);
00905    }
00906 
00907    // Jet Final Stage  
00908    theJetFinalStage = new L1GctJetFinalStage(theWheelJetFpgas);
00909 
00910   // Electron Final Sort
00911    theIsoEmFinalStage = new L1GctElectronFinalSort(true,theEmLeafCards.at(0), theEmLeafCards.at(1));
00912    theNonIsoEmFinalStage = new L1GctElectronFinalSort(false,theEmLeafCards.at(0), theEmLeafCards.at(1));  
00913 
00914   // Global Energy Algos
00915   theEnergyFinalStage = new L1GctGlobalEnergyAlgos(theWheelEnergyFpgas, theWheelJetFpgas);
00916 
00917 }
00918 
00926 unsigned L1GlobalCaloTrigger::sorterNo(const L1CaloEmCand& em) const {
00927   unsigned crate = em.rctCrate();
00928   unsigned result = ( ((crate%9) < 4) ? 1 : 0 );
00929   if (crate>=9) result += 2;
00930   if (crate>=18) result = 0;
00931   return result; 
00932 }
00933