CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME11.cc

Go to the documentation of this file.
00001 //-----------------------------------------------------------------------------
00002 //
00003 //   Class: CSCMotherboardME11
00004 //
00005 //   Description:
00006 //    Extended CSCMotherboard for ME11 to handle ME1a and ME1b separately
00007 //
00008 //   Author List: Vadim Khotilovich 12 May 2009
00009 //
00010 //   $Date: 2012/12/05 21:14:22 $
00011 //   $Revision: 1.2 $
00012 //
00013 //-----------------------------------------------------------------------------
00014 
00015 #include <L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME11.h>
00016 //#include <Utilities/Timing/interface/TimingReport.h>
00017 #include <FWCore/MessageLogger/interface/MessageLogger.h>
00018 #include <DataFormats/MuonDetId/interface/CSCTriggerNumbering.h>
00019 
00020 
00021 
00022 // LUT for which ME1/1 wire group can cross which ME1/a halfstrip
00023 // 1st index: WG number
00024 // 2nd index: inclusive HS range
00025 const int CSCMotherboardME11::lut_wg_vs_hs_me1a[48][2] = {
00026 {0, 95},{0, 95},{0, 95},{0, 95},{0, 95},
00027 {0, 95},{0, 95},{0, 95},{0, 95},{0, 95},
00028 {0, 95},{0, 95},{0, 77},{0, 61},{0, 39},
00029 {0, 22},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
00030 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
00031 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
00032 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
00033 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
00034 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
00035 {-1,-1},{-1,-1},{-1,-1} };
00036 // a modified LUT for ganged ME1a
00037 const int CSCMotherboardME11::lut_wg_vs_hs_me1ag[48][2] = {
00038 {0, 31},{0, 31},{0, 31},{0, 31},{0, 31},
00039 {0, 31},{0, 31},{0, 31},{0, 31},{0, 31},
00040 {0, 31},{0, 31},{0, 31},{0, 31},{0, 31},
00041 {0, 22},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
00042 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
00043 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
00044 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
00045 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
00046 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
00047 {-1,-1},{-1,-1},{-1,-1} };
00048 
00049 // LUT for which ME1/1 wire group can cross which ME1/b halfstrip
00050 // 1st index: WG number
00051 // 2nd index: inclusive HS range
00052 const int CSCMotherboardME11::lut_wg_vs_hs_me1b[48][2] = {
00053 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
00054 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
00055 {100, 127},{73, 127},{47, 127},{22, 127},{0, 127},
00056 {0, 127},{0, 127},{0, 127},{0, 127},{0, 127},
00057 {0, 127},{0, 127},{0, 127},{0, 127},{0, 127},
00058 {0, 127},{0, 127},{0, 127},{0, 127},{0, 127},
00059 {0, 127},{0, 127},{0, 127},{0, 127},{0, 127},
00060 {0, 127},{0, 127},{0, 127},{0, 127},{0, 127},
00061 {0, 127},{0, 127},{0, 127},{0, 127},{0, 105},
00062 {0, 93},{0, 78},{0, 63} };
00063 
00064 
00065 CSCMotherboardME11::CSCMotherboardME11(unsigned endcap, unsigned station,
00066                                unsigned sector, unsigned subsector,
00067                                unsigned chamber,
00068                                const edm::ParameterSet& conf) :
00069                 CSCMotherboard(endcap, station, sector, subsector, chamber, conf)
00070 {
00071   edm::ParameterSet commonParams = conf.getParameter<edm::ParameterSet>("commonParam");
00072 
00073   // special configuration parameters for ME11 treatment
00074   smartME1aME1b = commonParams.getUntrackedParameter<bool>("smartME1aME1b", true);
00075   disableME1a = commonParams.getUntrackedParameter<bool>("disableME1a", false);
00076   gangedME1a = commonParams.getUntrackedParameter<bool>("gangedME1a", false);
00077 
00078   if (!isSLHC) edm::LogError("L1CSCTPEmulatorConfigError")
00079     << "+++ Upgrade CSCMotherboardME11 constructed while isSLHC is not set! +++\n";
00080   if (!smartME1aME1b) edm::LogError("L1CSCTPEmulatorConfigError")
00081     << "+++ Upgrade CSCMotherboardME11 constructed while smartME1aME1b is not set! +++\n";
00082 
00083   edm::ParameterSet alctParams = conf.getParameter<edm::ParameterSet>("alctSLHC");
00084   edm::ParameterSet clctParams = conf.getParameter<edm::ParameterSet>("clctSLHC");
00085   edm::ParameterSet tmbParams = conf.getParameter<edm::ParameterSet>("tmbSLHC");
00086 
00087   clct1a = new CSCCathodeLCTProcessor(endcap, station, sector, subsector, chamber, clctParams, commonParams, tmbParams);
00088   clct1a->setRing(4);
00089 
00090   match_earliest_alct_me11_only = tmbParams.getUntrackedParameter<bool>("matchEarliestAlctME11Only",true);
00091   match_earliest_clct_me11_only = tmbParams.getUntrackedParameter<bool>("matchEarliestClctME11Only",true);
00092 
00093   // if true: use regular CLCT-to-ALCT matching in TMB
00094   // if false: do ALCT-to-CLCT matching
00095   clct_to_alct = tmbParams.getUntrackedParameter<bool>("clctToAlct",true);
00096 
00097   // whether to not reuse CLCTs that were used by previous matching ALCTs
00098   // in ALCT-to-CLCT algorithm
00099   drop_used_clcts = tmbParams.getUntrackedParameter<bool>("tmbDropUsedClcts",true);
00100 
00101   tmb_cross_bx_algo = tmbParams.getUntrackedParameter<unsigned int>("tmbCrossBxAlgorithm");
00102 
00103   // maximum lcts per BX in ME11: 2, 3, 4 or 999
00104   max_me11_lcts = tmbParams.getUntrackedParameter<unsigned int>("maxME11LCTs",4);
00105 
00106   pref[0] = match_trig_window_size/2;
00107   for (unsigned int m=2; m<match_trig_window_size; m+=2)
00108   {
00109     pref[m-1] = pref[0] - m/2;
00110     pref[m]   = pref[0] + m/2;
00111   }
00112 }
00113 
00114 
00115 CSCMotherboardME11::CSCMotherboardME11() : CSCMotherboard()
00116 {
00117   // Constructor used only for testing.
00118 
00119   clct1a = new CSCCathodeLCTProcessor();
00120   clct1a->setRing(4);
00121 
00122   pref[0] = match_trig_window_size/2;
00123   for (unsigned int m=2; m<match_trig_window_size; m+=2)
00124   {
00125     pref[m-1] = pref[0] - m/2;
00126     pref[m]   = pref[0] + m/2;
00127   }
00128 }
00129 
00130 
00131 CSCMotherboardME11::~CSCMotherboardME11()
00132 {
00133   if (clct1a) delete clct1a;
00134 }
00135 
00136 
00137 void CSCMotherboardME11::clear()
00138 {
00139   CSCMotherboard::clear();
00140   if (clct1a) clct1a->clear();
00141   for (int bx = 0; bx < MAX_LCT_BINS; bx++)
00142   {
00143     //firstLCT1a[bx].clear();
00144     //secondLCT1a[bx].clear();
00145     for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
00146       for (int i=0;i<2;i++)
00147       {
00148         allLCTs1b[bx][mbx][i].clear();
00149         allLCTs1a[bx][mbx][i].clear();
00150       }
00151   }
00152 }
00153 
00154 // Set configuration parameters obtained via EventSetup mechanism.
00155 void CSCMotherboardME11::setConfigParameters(const CSCDBL1TPParameters* conf)
00156 {
00157   alct->setConfigParameters(conf);
00158   clct->setConfigParameters(conf);
00159   clct1a->setConfigParameters(conf);
00160   // No config. parameters in DB for the TMB itself yet.
00161 }
00162 
00163 
00164 void CSCMotherboardME11::run(const CSCWireDigiCollection* wiredc,
00165                              const CSCComparatorDigiCollection* compdc)
00166 {
00167   clear();
00168   
00169   if (!( alct && clct &&  clct1a && smartME1aME1b))
00170   {
00171     if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError")
00172       << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n";
00173     return;
00174   }
00175 
00176   alctV = alct->run(wiredc); // run anodeLCT
00177   clctV1b = clct->run(compdc); // run cathodeLCT in ME1/b
00178   clctV1a = clct1a->run(compdc); // run cathodeLCT in ME1/a
00179 
00180   //int n_clct_a=0, n_clct_b=0;
00181   //if (clct1a->bestCLCT[6].isValid() && clct1a->bestCLCT[6].getBX()==6) n_clct_a++;
00182   //if (clct1a->secondCLCT[6].isValid() && clct1a->secondCLCT[6].getBX()==6) n_clct_a++;
00183 
00184   int used_alct_mask[20], used_alct_mask_1a[20];
00185   int used_clct_mask[20], used_clct_mask_1a[20];
00186   for (int b=0;b<20;b++)
00187     used_alct_mask[b] = used_alct_mask_1a[b] = used_clct_mask[b] = used_clct_mask_1a[b] = 0;
00188 
00189   // CLCT-centric CLCT-to-ALCT matching
00190   if (clct_to_alct) for (int bx_clct = 0; bx_clct < CSCCathodeLCTProcessor::MAX_CLCT_BINS; bx_clct++)
00191   {
00192     // matching in ME1b
00193     if (clct->bestCLCT[bx_clct].isValid())
00194     {
00195       int bx_alct_start = bx_clct - match_trig_window_size/2;
00196       int bx_alct_stop  = bx_clct + match_trig_window_size/2;
00197       for (int bx_alct = bx_alct_start; bx_alct <= bx_alct_stop; bx_alct++)
00198       {
00199         if (bx_alct < 0 || bx_alct >= CSCAnodeLCTProcessor::MAX_ALCT_BINS) continue;
00200         if (drop_used_alcts && used_alct_mask[bx_alct]) continue;
00201         if (alct->bestALCT[bx_alct].isValid())
00202         {
00203           if (infoV > 1) LogTrace("CSCMotherboard")
00204             << "Successful CLCT-ALCT match in ME1b: bx_clct = " << bx_clct
00205             << "; match window: [" << bx_alct_start << "; " << bx_alct_stop
00206             << "]; bx_alct = " << bx_alct;
00207           int mbx = bx_alct_stop - bx_alct;
00208           correlateLCTs(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
00209                         clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct],
00210                         allLCTs1b[bx_alct][mbx][0], allLCTs1b[bx_alct][mbx][1], ME1B);
00211           if (allLCTs1b[bx_alct][mbx][0].isValid())
00212           {
00213             used_alct_mask[bx_alct] += 1;
00214             if (match_earliest_alct_me11_only) break;
00215           }
00216         }
00217       }
00218       // Do not report CLCT-only LCT for ME1b
00219     }
00220     // matching in ME1a
00221     if (clct1a->bestCLCT[bx_clct].isValid())
00222     {
00223       int bx_alct_start = bx_clct - match_trig_window_size/2;
00224       int bx_alct_stop  = bx_clct + match_trig_window_size/2;
00225       for (int bx_alct = bx_alct_start; bx_alct <= bx_alct_stop; bx_alct++)
00226       {
00227         if (bx_alct < 0 || bx_alct >= CSCAnodeLCTProcessor::MAX_ALCT_BINS) continue;
00228         if (drop_used_alcts && used_alct_mask_1a[bx_alct]) continue;
00229         if (alct->bestALCT[bx_alct].isValid())
00230         {
00231           if (infoV > 1) LogTrace("CSCMotherboard")
00232             << "Successful CLCT-ALCT match in ME1a: bx_clct = " << bx_clct
00233             << "; match window: [" << bx_alct_start << "; " << bx_alct_stop
00234             << "]; bx_alct = " << bx_alct;
00235           int mbx = bx_alct_stop - bx_alct;
00236           correlateLCTs(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
00237                         clct1a->bestCLCT[bx_clct], clct1a->secondCLCT[bx_clct],
00238                         allLCTs1a[bx_alct][mbx][0], allLCTs1a[bx_alct][mbx][1], ME1A);
00239           if (allLCTs1a[bx_alct][mbx][0].isValid())
00240           {
00241             used_alct_mask_1a[bx_alct] += 1;
00242             if (match_earliest_alct_me11_only) break;
00243           }
00244         }
00245       }
00246       // Do not report CLCT-only LCT for ME1b
00247     }
00248     // Do not attempt to make ALCT-only LCT for ME1b
00249   } // end of CLCT-centric matching
00250 
00251   // ALCT-centric ALCT-to-CLCT matching
00252   else for (int bx_alct = 0; bx_alct < CSCAnodeLCTProcessor::MAX_ALCT_BINS; bx_alct++)
00253   {
00254     if (alct->bestALCT[bx_alct].isValid())
00255     {
00256       int bx_clct_start = bx_alct - match_trig_window_size/2;
00257       int bx_clct_stop  = bx_alct + match_trig_window_size/2;
00258       
00259       // matching in ME1b
00260       for (int bx_clct = bx_clct_start; bx_clct <= bx_clct_stop; bx_clct++)
00261       {
00262         if (bx_clct < 0 || bx_clct >= CSCCathodeLCTProcessor::MAX_CLCT_BINS) continue;
00263         if (drop_used_clcts && used_clct_mask[bx_clct]) continue;
00264         if (clct->bestCLCT[bx_clct].isValid())
00265         {
00266           if (infoV > 1) LogTrace("CSCMotherboard")
00267             << "Successful ALCT-CLCT match in ME1b: bx_alct = " << bx_alct
00268             << "; match window: [" << bx_clct_start << "; " << bx_clct_stop
00269             << "]; bx_clct = " << bx_clct;
00270           int mbx = bx_clct-bx_clct_start;
00271           correlateLCTs(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
00272                         clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct],
00273                         allLCTs1b[bx_alct][mbx][0], allLCTs1b[bx_alct][mbx][1], ME1B);
00274           if (allLCTs1b[bx_alct][mbx][0].isValid())
00275           {
00276             used_clct_mask[bx_clct] += 1;
00277             if (match_earliest_clct_me11_only) break;
00278           }
00279         }
00280       }
00281 
00282       // matching in ME1a
00283       for (int bx_clct = bx_clct_start; bx_clct <= bx_clct_stop; bx_clct++)
00284       {
00285         if (bx_clct < 0 || bx_clct >= CSCCathodeLCTProcessor::MAX_CLCT_BINS) continue;
00286         if (drop_used_clcts && used_clct_mask_1a[bx_clct]) continue;
00287         if (clct1a->bestCLCT[bx_clct].isValid())
00288         {
00289           if (infoV > 1) LogTrace("CSCMotherboard")
00290             << "Successful ALCT-CLCT match in ME1a: bx_alct = " << bx_alct
00291             << "; match window: [" << bx_clct_start << "; " << bx_clct_stop
00292             << "]; bx_clct = " << bx_clct;
00293           int mbx = bx_clct-bx_clct_start;
00294           correlateLCTs(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
00295                         clct1a->bestCLCT[bx_clct], clct1a->secondCLCT[bx_clct],
00296                         allLCTs1a[bx_alct][mbx][0], allLCTs1a[bx_alct][mbx][1], ME1A);
00297           if (allLCTs1a[bx_alct][mbx][0].isValid())
00298           {
00299             used_clct_mask_1a[bx_clct] += 1;
00300             if (match_earliest_clct_me11_only) break;
00301           }
00302         }
00303       }
00304     }
00305   } // end of ALCT-centric matching
00306 
00307   // reduction of nLCTs per each BX
00308   for (int bx = 0; bx < MAX_LCT_BINS; bx++)
00309   {
00310     // counting
00311     unsigned int n1a=0, n1b=0;
00312     for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
00313       for (int i=0;i<2;i++)
00314       {
00315         int cbx = bx + mbx - match_trig_window_size/2;
00316         if (allLCTs1b[bx][mbx][i].isValid())
00317         {
00318           n1b++;
00319           if (infoV > 0) LogDebug("CSCMotherboard") << "1b LCT"<<i+1<<" "<<bx<<"/"<<cbx<<": "<<allLCTs1b[bx][mbx][i];
00320         }
00321         if (allLCTs1a[bx][mbx][i].isValid())
00322         {
00323           n1a++;
00324           if (infoV > 0) LogDebug("CSCMotherboard") << "1a LCT"<<i+1<<" "<<bx<<"/"<<cbx<<": "<<allLCTs1a[bx][mbx][i];
00325         }
00326       }
00327     if (infoV > 0 && n1a+n1b>0) LogDebug("CSCMotherboard") <<"bx "<<bx<<" nLCT:"<<n1a<<" "<<n1b<<" "<<n1a+n1b;
00328 
00329     // some simple cross-bx sorting algorithms
00330     if (tmb_cross_bx_algo == 1 && (n1a>2 || n1b>2) )
00331     {
00332       n1a=0, n1b=0;
00333       for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
00334         for (int i=0;i<2;i++)
00335         {
00336           if (allLCTs1b[bx][pref[mbx]][i].isValid())
00337           {
00338             n1b++;
00339             if (n1b>2) allLCTs1b[bx][pref[mbx]][i].clear();
00340           }
00341           if (allLCTs1a[bx][pref[mbx]][i].isValid())
00342           {
00343             n1a++;
00344             if (n1a>2) allLCTs1a[bx][pref[mbx]][i].clear();
00345           }
00346         }
00347 
00348       if (infoV > 0) LogDebug("CSCMotherboard") <<"After x-bx sorting:";
00349       n1a=0, n1b=0;
00350       for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
00351         for (int i=0;i<2;i++)
00352         {
00353           int cbx = bx + mbx - match_trig_window_size/2;
00354           if (allLCTs1b[bx][mbx][i].isValid())
00355           {
00356             n1b++;
00357             if (infoV > 0) LogDebug("CSCMotherboard") << "1b LCT"<<i+1<<" "<<bx<<"/"<<cbx<<": "<<allLCTs1b[bx][mbx][i];
00358           }
00359           if (allLCTs1a[bx][mbx][i].isValid())
00360           {
00361             n1a++;
00362             if (infoV > 0) LogDebug("CSCMotherboard") << "1a LCT"<<i+1<<" "<<bx<<"/"<<cbx<<": "<<allLCTs1a[bx][mbx][i];
00363           }
00364         }
00365       if (infoV > 0 && n1a+n1b>0) LogDebug("CSCMotherboard") <<"bx "<<bx<<" nnLCT:"<<n1a<<" "<<n1b<<" "<<n1a+n1b;
00366     } // x-bx sorting
00367 
00368     // Maximum 2 or 3 per whole ME11 per BX case:
00369     // (supposedly, now we should have max 2 per bx in each 1a and 1b)
00370     if ( n1a+n1b > max_me11_lcts )
00371     {
00372       // do it simple so far: take all low eta 1/b stubs
00373       unsigned int nLCT=n1b;
00374       n1a=0;
00375       // right now nLCT<=2; cut 1a if necessary
00376       for (unsigned int mbx=0; mbx<match_trig_window_size; mbx++)
00377         for (int i=0;i<2;i++)
00378           if (allLCTs1a[bx][mbx][i].isValid()) {
00379             nLCT++;
00380             if (nLCT>max_me11_lcts) allLCTs1a[bx][mbx][i].clear();
00381             else n1a++;
00382           }
00383       if (infoV > 0 && nLCT>0) LogDebug("CSCMotherboard") <<"bx "<<bx<<" nnnLCT:"<<n1a<<" "<<n1b<<" "<<n1a+n1b;
00384     }
00385   }// reduction per bx
00386 
00387   //if (infoV > 1) LogTrace("CSCMotherboardME11")<<"clct_count E:"<<theEndcap<<"S:"<<theStation<<"R:"<<1<<"C:"
00388   //  <<CSCTriggerNumbering::chamberFromTriggerLabels(theSector,theSubsector, theStation, theTrigChamber)
00389   //  <<"  a "<<n_clct_a<<"  b "<<n_clct_b<<"  ab "<<n_clct_a+n_clct_b;
00390 }
00391 
00392 
00393 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11::readoutLCTs1a()
00394 {
00395   return readoutLCTs(ME1A);
00396 }
00397 
00398 
00399 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11::readoutLCTs1b()
00400 {
00401   return readoutLCTs(ME1B);
00402 }
00403 
00404 
00405 // Returns vector of read-out correlated LCTs, if any.  Starts with
00406 // the vector of all found LCTs and selects the ones in the read-out
00407 // time window.
00408 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11::readoutLCTs(int me1ab)
00409 {
00410   std::vector<CSCCorrelatedLCTDigi> tmpV;
00411 
00412   // The start time of the L1A*LCT coincidence window should be related
00413   // to the fifo_pretrig parameter, but I am not completely sure how.
00414   // Just choose it such that the window is centered at bx=7.  This may
00415   // need further tweaking if the value of tmb_l1a_window_size changes.
00416   //static int early_tbins = 4;
00417   // The number of LCT bins in the read-out is given by the
00418   // tmb_l1a_window_size parameter, forced to be odd
00419   static int lct_bins   = 
00420     (tmb_l1a_window_size % 2 == 0) ? tmb_l1a_window_size + 1 : tmb_l1a_window_size;
00421   static int late_tbins = early_tbins + lct_bins;
00422 
00423 
00424   // Start from the vector of all found correlated LCTs and select
00425   // those within the LCT*L1A coincidence window.
00426   int bx_readout = -1;
00427   std::vector<CSCCorrelatedLCTDigi> all_lcts;
00428   if (me1ab == ME1A) all_lcts = getLCTs1a();
00429   if (me1ab == ME1B) all_lcts = getLCTs1b();
00430   std::vector <CSCCorrelatedLCTDigi>::const_iterator plct = all_lcts.begin();
00431   for (; plct != all_lcts.end(); plct++)
00432   {
00433     if (!plct->isValid()) continue;
00434 
00435     int bx = (*plct).getBX();
00436     // Skip LCTs found too early relative to L1Accept.
00437     if (bx <= early_tbins) continue;
00438 
00439     // Skip LCTs found too late relative to L1Accept.
00440     if (bx > late_tbins) continue;
00441 
00442     // If (readout_earliest_2) take only LCTs in the earliest bx in the read-out window:
00443     // in digi->raw step, LCTs have to be packed into the TMB header, and
00444     // currently there is room just for two.
00445     if (readout_earliest_2 && (bx_readout == -1 || bx == bx_readout) )
00446     {
00447       tmpV.push_back(*plct);
00448       if (bx_readout == -1) bx_readout = bx;
00449     }
00450     else tmpV.push_back(*plct);
00451   }
00452   return tmpV;
00453 }
00454 
00455 
00456 // Returns vector of found correlated LCTs, if any.
00457 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11::getLCTs1b()
00458 {
00459   std::vector<CSCCorrelatedLCTDigi> tmpV;
00460 
00461   for (int bx = 0; bx < MAX_LCT_BINS; bx++) 
00462     for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
00463       for (int i=0;i<2;i++)
00464         if (allLCTs1b[bx][mbx][i].isValid()) tmpV.push_back(allLCTs1b[bx][mbx][i]);
00465   return tmpV;
00466 }
00467 
00468 // Returns vector of found correlated LCTs, if any.
00469 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11::getLCTs1a()
00470 {
00471   std::vector<CSCCorrelatedLCTDigi> tmpV;
00472   
00473   // disabled ME1a
00474   if (mpc_block_me1a || disableME1a) return tmpV;
00475 
00476   // Report all LCTs found.
00477   for (int bx = 0; bx < MAX_LCT_BINS; bx++)
00478     for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) 
00479       for (int i=0;i<2;i++)
00480         if (allLCTs1a[bx][mbx][i].isValid())  tmpV.push_back(allLCTs1a[bx][mbx][i]);
00481   return tmpV;
00482 }
00483 
00484 
00485 bool CSCMotherboardME11::doesALCTCrossCLCT(CSCALCTDigi &a, CSCCLCTDigi &c, int me)
00486 {
00487   if ( !c.isValid() || !a.isValid() ) return false;
00488   int key_hs = c.getKeyStrip();
00489   int key_wg = a.getKeyWG();
00490   if ( me == ME1A )
00491   {
00492     if ( !gangedME1a )
00493     {
00494       // wrap around ME11 HS number for -z endcap
00495       if (theEndcap==2) key_hs = 95 - key_hs;
00496       if ( key_hs >= lut_wg_vs_hs_me1a[key_wg][0] && 
00497            key_hs <= lut_wg_vs_hs_me1a[key_wg][1]    ) return true;
00498       return false;
00499     }
00500     else
00501     {
00502       if (theEndcap==2) key_hs = 31 - key_hs;
00503       if ( key_hs >= lut_wg_vs_hs_me1ag[key_wg][0] &&
00504            key_hs <= lut_wg_vs_hs_me1ag[key_wg][1]    ) return true;
00505       return false;
00506     }
00507   }
00508   if ( me == ME1B)
00509   {
00510     if (theEndcap==2) key_hs = 127 - key_hs;
00511     if ( key_hs >= lut_wg_vs_hs_me1b[key_wg][0] && 
00512          key_hs <= lut_wg_vs_hs_me1b[key_wg][1]      ) return true;
00513   }
00514   return false;
00515 }
00516 
00517 
00518 void CSCMotherboardME11::correlateLCTs(CSCALCTDigi bestALCT,
00519                                    CSCALCTDigi secondALCT,
00520                                    CSCCLCTDigi bestCLCT,
00521                                    CSCCLCTDigi secondCLCT,
00522                                    CSCCorrelatedLCTDigi& lct1,
00523                                    CSCCorrelatedLCTDigi& lct2)
00524 {
00525   bool anodeBestValid     = bestALCT.isValid();
00526   bool anodeSecondValid   = secondALCT.isValid();
00527   bool cathodeBestValid   = bestCLCT.isValid();
00528   bool cathodeSecondValid = secondCLCT.isValid();
00529 
00530   if (anodeBestValid && !anodeSecondValid)     secondALCT = bestALCT;
00531   if (!anodeBestValid && anodeSecondValid)     bestALCT   = secondALCT;
00532   if (cathodeBestValid && !cathodeSecondValid) secondCLCT = bestCLCT;
00533   if (!cathodeBestValid && cathodeSecondValid) bestCLCT   = secondCLCT;
00534 
00535   // ALCT-CLCT matching conditions are defined by "trig_enable" configuration
00536   // parameters.
00537   if ((alct_trig_enable  && bestALCT.isValid()) ||
00538       (clct_trig_enable  && bestCLCT.isValid()) ||
00539       (match_trig_enable && bestALCT.isValid() && bestCLCT.isValid()))
00540   {
00541     lct1 = constructLCTs(bestALCT, bestCLCT);
00542     lct1.setTrknmb(1);
00543   }
00544 
00545   if (((secondALCT != bestALCT) || (secondCLCT != bestCLCT)) &&
00546       ((alct_trig_enable  && secondALCT.isValid()) ||
00547        (clct_trig_enable  && secondCLCT.isValid()) ||
00548        (match_trig_enable && secondALCT.isValid() && secondCLCT.isValid())))
00549   {
00550     lct2 = constructLCTs(secondALCT, secondCLCT);
00551     lct2.setTrknmb(2);
00552   }
00553 }
00554 
00555 
00556 void CSCMotherboardME11::correlateLCTs(CSCALCTDigi bestALCT,
00557                                    CSCALCTDigi secondALCT,
00558                                    CSCCLCTDigi bestCLCT,
00559                                    CSCCLCTDigi secondCLCT,
00560                                    CSCCorrelatedLCTDigi& lct1,
00561                                    CSCCorrelatedLCTDigi& lct2,
00562                                    int me)
00563 {
00564   // assume that always anodeBestValid && cathodeBestValid
00565   
00566   if (secondALCT == bestALCT) secondALCT.clear();
00567   if (secondCLCT == bestCLCT) secondCLCT.clear();
00568 
00569   int ok11 = doesALCTCrossCLCT( bestALCT, bestCLCT, me);
00570   int ok12 = doesALCTCrossCLCT( bestALCT, secondCLCT, me);
00571   int ok21 = doesALCTCrossCLCT( secondALCT, bestCLCT, me);
00572   int ok22 = doesALCTCrossCLCT( secondALCT, secondCLCT, me);
00573   int code = (ok11<<3) | (ok12<<2) | (ok21<<1) | (ok22);
00574 
00575   int dbg=0;
00576   int ring = me;
00577   int chamb= CSCTriggerNumbering::chamberFromTriggerLabels(theSector,theSubsector, theStation, theTrigChamber);
00578   CSCDetId did(theEndcap, theStation, ring, chamb, 0);
00579   if (dbg) LogTrace("CSCMotherboardME11")<<"debug correlateLCTs in "<<did<<std::endl
00580            <<"ALCT1: "<<bestALCT<<std::endl
00581            <<"ALCT2: "<<secondALCT<<std::endl
00582            <<"CLCT1: "<<bestCLCT<<std::endl
00583            <<"CLCT2: "<<secondCLCT<<std::endl
00584            <<"ok 11 12 21 22 code = "<<ok11<<" "<<ok12<<" "<<ok21<<" "<<ok22<<" "<<code<<std::endl;
00585 
00586   if ( code==0 ) return;
00587 
00588   // LUT defines correspondence between possible ok## combinations
00589   // and resulting lct1 and lct2
00590   int lut[16][2] = {
00591           //ok: 11 12 21 22
00592     {0 ,0 }, // 0  0  0  0
00593     {22,0 }, // 0  0  0  1
00594     {21,0 }, // 0  0  1  0
00595     {21,22}, // 0  0  1  1
00596     {12,0 }, // 0  1  0  0
00597     {12,22}, // 0  1  0  1
00598     {12,21}, // 0  1  1  0
00599     {12,21}, // 0  1  1  1
00600     {11,0 }, // 1  0  0  0
00601     {11,22}, // 1  0  0  1
00602     {11,21}, // 1  0  1  0
00603     {11,22}, // 1  0  1  1
00604     {11,12}, // 1  1  0  0
00605     {11,22}, // 1  1  0  1
00606     {11,12}, // 1  1  1  0
00607     {11,22}, // 1  1  1  1
00608   };
00609 
00610   if (dbg) LogTrace("CSCMotherboardME11")<<"lut 0 1 = "<<lut[code][0]<<" "<<lut[code][1]<<std::endl;
00611 
00612   switch (lut[code][0]) {
00613     case 11:
00614       lct1 = constructLCTs(bestALCT, bestCLCT);
00615       break;
00616     case 12:
00617       lct1 = constructLCTs(bestALCT, secondCLCT);
00618       break;
00619     case 21:
00620       lct1 = constructLCTs(secondALCT, bestCLCT);
00621       break;
00622     case 22:
00623       lct1 = constructLCTs(secondALCT, secondCLCT);
00624       break;
00625     default: return;  
00626   }
00627   lct1.setTrknmb(1);
00628 
00629   if (dbg) LogTrace("CSCMotherboardME11")<<"lct1: "<<lct1<<std::endl;
00630   
00631   switch (lut[code][1])
00632   {
00633     case 12:
00634       lct2 = constructLCTs(bestALCT, secondCLCT);
00635       lct2.setTrknmb(2);
00636       if (dbg) LogTrace("CSCMotherboardME11")<<"lct2: "<<lct2<<std::endl;
00637       return;
00638     case 21:
00639       lct2 = constructLCTs(secondALCT, bestCLCT);
00640       lct2.setTrknmb(2);
00641       if (dbg) LogTrace("CSCMotherboardME11")<<"lct2: "<<lct2<<std::endl;
00642       return;
00643     case 22:
00644       lct2 = constructLCTs(secondALCT, secondCLCT);
00645       lct2.setTrknmb(2);
00646       if (dbg) LogTrace("CSCMotherboardME11")<<"lct2: "<<lct2<<std::endl;
00647       return;
00648     default: return;
00649   }
00650   if (dbg) LogTrace("CSCMotherboardME11")<<"out of correlateLCTs"<<std::endl;
00651 
00652   return;
00653 }
00654