CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/L1Trigger/DTTrackFinder/src/L1MuDTAssignmentUnit.cc

Go to the documentation of this file.
00001 //-------------------------------------------------
00002 //
00003 //   Class: L1MuDTAssignmentUnit
00004 //
00005 //   Description: Assignment Unit
00006 //
00007 //
00008 //   $Date: 2010/09/10 12:26:35 $
00009 //   $Revision: 1.11 $
00010 //
00011 //   Author :
00012 //   N. Neumeister            CERN EP
00013 //   J. Troconiz              UAM Madrid
00014 //
00015 //--------------------------------------------------
00016 
00017 //-----------------------
00018 // This Class's Header --
00019 //-----------------------
00020 
00021 #include "L1Trigger/DTTrackFinder/src/L1MuDTAssignmentUnit.h"
00022 
00023 //---------------
00024 // C++ Headers --
00025 //---------------
00026 
00027 #include <iostream>
00028 #include <cmath>
00029 #include <cassert>
00030 
00031 //-------------------------------
00032 // Collaborating Class Headers --
00033 //-------------------------------
00034 
00035 #include "L1Trigger/DTTrackFinder/src/L1MuDTTFConfig.h"
00036 #include "L1Trigger/DTTrackFinder/src/L1MuDTSectorProcessor.h"
00037 #include "L1Trigger/DTTrackFinder/src/L1MuDTDataBuffer.h"
00038 #include "L1Trigger/DTTrackFinder/src/L1MuDTTrackSegPhi.h"
00039 #include "L1Trigger/DTTrackFinder/src/L1MuDTTrackSegLoc.h"
00040 #include "L1Trigger/DTTrackFinder/src/L1MuDTTrackAssembler.h"
00041 #include "L1Trigger/DTTrackFinder/src/L1MuDTTrackAssParam.h"
00042 #include "CondFormats/L1TObjects/interface/L1MuDTPhiLut.h"
00043 #include "CondFormats/DataRecord/interface/L1MuDTPhiLutRcd.h"
00044 #include "CondFormats/L1TObjects/interface/L1MuDTPtaLut.h"
00045 #include "CondFormats/DataRecord/interface/L1MuDTPtaLutRcd.h"
00046 #include "L1Trigger/DTTrackFinder/interface/L1MuDTTrack.h"
00047 
00048 using namespace std;
00049 
00050 // --------------------------------
00051 //       class L1MuDTAssignmentUnit
00052 //---------------------------------
00053 
00054 //----------------
00055 // Constructors --
00056 //----------------
00057 
00058 L1MuDTAssignmentUnit::L1MuDTAssignmentUnit(L1MuDTSectorProcessor& sp, int id) : 
00059                 m_sp(sp), m_id(id), 
00060                 m_addArray(), m_TSphi(), m_ptAssMethod(NODEF) {
00061 
00062   m_TSphi.reserve(4);  // a track candidate can consist of max 4 TS 
00063   reset();
00064 
00065   setPrecision();
00066 
00067 }
00068 
00069 
00070 //--------------
00071 // Destructor --
00072 //--------------
00073 
00074 L1MuDTAssignmentUnit::~L1MuDTAssignmentUnit() {}
00075 
00076 
00077 //--------------
00078 // Operations --
00079 //--------------
00080 
00081 //
00082 // run Assignment Unit
00083 //
00084 void L1MuDTAssignmentUnit::run(const edm::EventSetup& c) {
00085 
00086   // enable track candidate
00087   m_sp.track(m_id)->enable();
00088   m_sp.tracK(m_id)->enable();
00089 
00090   // set track class
00091   TrackClass tc = m_sp.TA()->trackClass(m_id);
00092   m_sp.track(m_id)->setTC(tc);
00093   m_sp.tracK(m_id)->setTC(tc);
00094 
00095   // get relative addresses of matching track segments
00096   m_addArray = m_sp.TA()->address(m_id);
00097   m_sp.track(m_id)->setAddresses(m_addArray);
00098   m_sp.tracK(m_id)->setAddresses(m_addArray);
00099 
00100   // get track segments (track segment router)
00101   TSR();
00102   m_sp.track(m_id)->setTSphi(m_TSphi);
00103   m_sp.tracK(m_id)->setTSphi(m_TSphi);
00104 
00105   // set bunch-crossing (use first track segment)
00106   vector<const L1MuDTTrackSegPhi*>::const_iterator iter = m_TSphi.begin();
00107   int bx = (*iter)->bx();
00108   m_sp.track(m_id)->setBx(bx);
00109   m_sp.tracK(m_id)->setBx(bx);
00110 
00111   // assign phi
00112   PhiAU(c);
00113 
00114   // assign pt and charge
00115   PtAU(c);
00116   
00117   // assign quality
00118   QuaAU();
00119   
00120   // special hack for overlap region
00121   //  for ( iter = m_TSphi.begin(); iter != m_TSphi.end(); iter++ ) {
00122   //    int wheel = abs((*iter)->wheel());
00123     //    if ( wheel == 3 && (*iter)->etaFlag() ) m_sp.track(m_id)->disable();
00124     //    if ( wheel == 3 && (*iter)->etaFlag() ) m_sp.tracK(m_id)->disable();
00125   //  }
00126 
00127 }
00128 
00129 
00130 //
00131 // reset Assignment Unit
00132 //
00133 void L1MuDTAssignmentUnit::reset() {
00134 
00135   m_addArray.reset();
00136   m_TSphi.clear();
00137   m_ptAssMethod = NODEF;
00138 
00139 }
00140 
00141 
00142 //
00143 // assign phi with 8 bit precision
00144 //
00145 void L1MuDTAssignmentUnit::PhiAU(const edm::EventSetup& c) {
00146 
00147   // calculate phi at station 2 using 8 bits (precision = 2.5 degrees) 
00148 
00149   c.get< L1MuDTPhiLutRcd >().get( thePhiLUTs );
00150 
00151   int sh_phi  = 12 - L1MuDTTFConfig::getNbitsPhiPhi();
00152   int sh_phib = 10 - L1MuDTTFConfig::getNbitsPhiPhib();
00153 
00154   const L1MuDTTrackSegPhi* second = getTSphi(2);  // track segment at station 2
00155   const L1MuDTTrackSegPhi* first  = getTSphi(1);  // track segment at station 1
00156   const L1MuDTTrackSegPhi* forth  = getTSphi(4);  // track segment at station 4
00157 
00158   int phi2 = 0;         // phi-value at station 2
00159   int sector = 0;
00160 
00161   if ( second ) {
00162     phi2 = second->phi() >> sh_phi;
00163     sector = second->sector();
00164   }
00165   else if ( second == 0 && first ) {
00166     phi2 = first->phi() >> sh_phi;
00167     sector = first->sector();
00168   }
00169   else if ( second == 0 && forth ) {
00170     phi2 = forth->phi() >> sh_phi;
00171     sector = forth->sector();
00172   }
00173 
00174   int sector0 = m_sp.id().sector();
00175 
00176   // convert sector difference to values in the range -6 to +5
00177 
00178   int sectordiff = (sector - sector0)%12;
00179   if ( sectordiff >= 6 ) sectordiff -= 12;
00180   if ( sectordiff < -6 ) sectordiff += 12;
00181   
00182   //  assert( abs(sectordiff) <= 1 );
00183 
00184   // get sector center in 8 bit coding
00185   int sector_8 = convertSector(sector0);
00186 
00187   // convert phi to 2.5 degree precision
00188   int phi_precision = 4096 >> sh_phi;
00189   const double k = 57.2958/2.5/static_cast<float>(phi_precision);
00190   double phi_f = static_cast<double>(phi2);
00191   int phi_8 = static_cast<int>(floor(phi_f*k));     
00192 
00193   if ( second == 0 && first ) {
00194     int bend_angle = (first->phib() >> sh_phib) << sh_phib;
00195     phi_8 = phi_8 + thePhiLUTs->getDeltaPhi(0,bend_angle);
00196   }
00197   else if ( second == 0 && forth ) {
00198     int bend_angle = (forth->phib() >> sh_phib) << sh_phib;
00199     phi_8 = phi_8 + thePhiLUTs->getDeltaPhi(1,bend_angle);
00200   }
00201 
00202   phi_8 += sectordiff*12;
00203 
00204   if (phi_8 >  15) phi_8 =  15;
00205   if (phi_8 < -16) phi_8 = -16;
00206 
00207   int phi = (sector_8 + phi_8 + 144)%144;
00208   phi_8 = (phi_8 + 32)%32;
00209 
00210   m_sp.track(m_id)->setPhi(phi);
00211   m_sp.tracK(m_id)->setPhi(phi_8);
00212 
00213 }
00214 
00215 
00216 //
00217 // assign pt with 5 bit precision
00218 //
00219 void L1MuDTAssignmentUnit::PtAU(const edm::EventSetup& c) {
00220 
00221   c.get< L1MuDTPtaLutRcd >().get( thePtaLUTs );
00222 
00223   // get pt-assignment method as function of track class and TS phib values
00224   m_ptAssMethod = getPtMethod();
00225 
00226   // get input address for look-up table
00227   int bend_angle = getPtAddress(m_ptAssMethod);
00228   int bend_carga = getPtAddress(m_ptAssMethod, 1);
00229 
00230   // retrieve pt value from look-up table
00231   int lut_idx = m_ptAssMethod;
00232   int pt = thePtaLUTs->getPt(lut_idx,bend_angle );
00233 
00234   m_sp.track(m_id)->setPt(pt);
00235   m_sp.tracK(m_id)->setPt(pt);
00236 
00237   // assign charge
00238   int chsign = getCharge(m_ptAssMethod);
00239   int charge = ( bend_carga >= 0 ) ? chsign : -1 * chsign;
00240   m_sp.track(m_id)->setCharge(charge);
00241   m_sp.tracK(m_id)->setCharge(charge);
00242 
00243 }
00244 
00245 
00246 //
00247 // assign 3 bit quality code
00248 //
00249 void L1MuDTAssignmentUnit::QuaAU() {
00250 
00251   unsigned int quality = 0;
00252   
00253   const TrackClass tc = m_sp.TA()->trackClass(m_id);
00254   
00255   switch ( tc ) {
00256     case T1234 : { quality = 7; break; }
00257     case T123  : { quality = 6; break; }
00258     case T124  : { quality = 6; break; }
00259     case T134  : { quality = 5; break; }
00260     case T234  : { quality = 4; break; }
00261     case T12   : { quality = 3; break; }
00262     case T13   : { quality = 3; break; }
00263     case T14   : { quality = 3; break; } 
00264     case T23   : { quality = 2; break; }
00265     case T24   : { quality = 2; break; } 
00266     case T34   : { quality = 1; break; }
00267     default    : { quality = 0; break; }
00268   }
00269 
00270   m_sp.track(m_id)->setQuality(quality);
00271   m_sp.tracK(m_id)->setQuality(quality);
00272 
00273 }
00274 
00275 
00276 //
00277 // Track Segment Router (TSR)
00278 //
00279 void L1MuDTAssignmentUnit::TSR() {
00280 
00281   // get the track segments from the data buffer 
00282   const L1MuDTTrackSegPhi* ts = 0;
00283   for ( int stat = 1; stat <= 4; stat++ ) {
00284     int adr = m_addArray.station(stat);
00285     if ( adr != 15 ) {
00286       ts = m_sp.data()->getTSphi(stat,adr);
00287       if ( ts != 0 ) m_TSphi.push_back( ts );
00288     }
00289   }
00290 
00291 }
00292 
00293 
00294 //
00295 // get track segment from a given station
00296 //
00297 const L1MuDTTrackSegPhi* L1MuDTAssignmentUnit::getTSphi(int station) const {
00298 
00299   vector<const L1MuDTTrackSegPhi*>::const_iterator iter;
00300   for ( iter = m_TSphi.begin(); iter != m_TSphi.end(); iter++ ) {
00301     int stat = (*iter)->station();
00302     if ( station == stat ) {
00303       return (*iter);
00304       break;
00305     }
00306   }
00307 
00308   return 0;
00309 
00310 }
00311 
00312 
00313 //
00314 // convert sector Id to a precision of 2.5 degrees using 8 bits (= sector center)
00315 //
00316 int L1MuDTAssignmentUnit::convertSector(int sector) {
00317 
00318   //  assert( sector >=0 && sector < 12 );
00319   const int sectorvalues[12] = {  0,  12,  24,  36, 48, 60, 72, 84, 
00320                                  96, 108, 120, 132 };
00321 
00322   return sectorvalues[sector];
00323 
00324 }
00325 
00326 
00327 //
00328 // determine charge
00329 //
00330 int L1MuDTAssignmentUnit::getCharge(PtAssMethod method) {
00331 
00332   int chargesign = 0;
00333   switch ( method ) {
00334     case PT12L  : { chargesign = -1; break; }
00335     case PT12H  : { chargesign = -1; break; }
00336     case PT13L  : { chargesign = -1; break; }
00337     case PT13H  : { chargesign = -1; break; }
00338     case PT14L  : { chargesign = -1; break; }
00339     case PT14H  : { chargesign = -1; break; }
00340     case PT23L  : { chargesign = -1; break; }
00341     case PT23H  : { chargesign = -1; break; }
00342     case PT24L  : { chargesign = -1; break; }
00343     case PT24H  : { chargesign = -1; break; }
00344     case PT34L  : { chargesign =  1; break; }
00345     case PT34H  : { chargesign =  1; break; }
00346     case PT12LO : { chargesign = -1; break; }
00347     case PT12HO : { chargesign = -1; break; }
00348     case PT13LO : { chargesign = -1; break; }
00349     case PT13HO : { chargesign = -1; break; }
00350     case PT14LO : { chargesign = -1; break; }
00351     case PT14HO : { chargesign = -1; break; }
00352     case PT23LO : { chargesign = -1; break; }
00353     case PT23HO : { chargesign = -1; break; }
00354     case PT24LO : { chargesign = -1; break; }
00355     case PT24HO : { chargesign = -1; break; }
00356     case PT34LO : { chargesign =  1; break; }
00357     case PT34HO : { chargesign =  1; break; }
00358     case PT15LO : { chargesign = -1; break; }
00359     case PT15HO : { chargesign = -1; break; }
00360     case PT25LO : { chargesign = -1; break; }
00361     case PT25HO : { chargesign = -1; break; }    
00362     case NODEF  : { chargesign = 0; 
00363     //                    cerr << "AssignmentUnit::getCharge : undefined PtAssMethod!"
00364     //                         << endl;
00365                     break;
00366                   }
00367   }
00368 
00369   return chargesign;
00370 
00371 }
00372 
00373 
00374 //
00375 // determine pt-assignment method
00376 //
00377 PtAssMethod L1MuDTAssignmentUnit::getPtMethod() const {
00378    
00379   // determine which pt-assignment method should be used as a function 
00380   // of the track class and
00381   // of the phib values of the track segments making up this track candidate.
00382 
00383   // get bitmap of track candidate
00384   const bitset<4> s = m_sp.TA()->trackBitMap(m_id);
00385   
00386   int method = -1;
00387   
00388   if (  s.test(0) &&  s.test(3) ) method = 2; // stations 1 and 4
00389   if (  s.test(0) &&  s.test(2) ) method = 1; // stations 1 and 3
00390   if (  s.test(0) &&  s.test(1) ) method = 0; // stations 1 and 2
00391   if ( !s.test(0) &&  s.test(1) && s.test(3) ) method = 4; // stations 2 and 4
00392   if ( !s.test(0) &&  s.test(1) && s.test(2) ) method = 3; // stations 2 and 3
00393   if ( !s.test(0) && !s.test(1) && s.test(2) && s.test(3) ) method = 5; // stations 3 and 4
00394 
00395   if ( m_sp.ovl() ) {
00396     int adr = m_addArray.station(3);
00397     bool s5 = (adr == 15) ? false : ((adr/2)%2 == 1);    
00398     if (  s.test(0) &&  s.test(3) ) method = 8;  // stations 1 and 4
00399     if (  s.test(0) &&  s.test(2) &&  s5 ) method = 12; // stations 1 and 5
00400     if (  s.test(0) &&  s.test(2) && !s5 ) method = 7;  // stations 1 and 3
00401     if (  s.test(0) &&  s.test(1) ) method = 6;  // stations 1 and 2
00402     if ( !s.test(0) &&  s.test(1) && s.test(3) ) method = 10; // stations 2 and 4
00403     if ( !s.test(0) &&  s.test(1) && s.test(2) &&  s5 ) method = 13; // stations 2 and 5
00404     if ( !s.test(0) &&  s.test(1) && s.test(2) && !s5 ) method = 9;  // stations 2 and 3
00405     if ( !s.test(0) && !s.test(1) && s.test(2) &&  s.test(3) ) method = 11; // stations 3 and 4
00406   }
00407 
00408   int threshold = thePtaLUTs->getPtLutThreshold(method);
00409   
00410   // phib values of track segments from stations 1, 2 and 4
00411   int phib1 = ( getTSphi(1) != 0 ) ? getTSphi(1)->phib() : 0;
00412   int phib2 = ( getTSphi(2) != 0 ) ? getTSphi(2)->phib() : 0;
00413   int phib4 = ( getTSphi(4) != 0 ) ? getTSphi(4)->phib() : 0;
00414 
00415   PtAssMethod pam = NODEF;
00416   
00417   switch ( method ) {
00418     case 0 :  { pam = ( abs(phib1) < threshold ) ? PT12H  : PT12L;  break; }
00419     case 1 :  { pam = ( abs(phib1) < threshold ) ? PT13H  : PT13L;  break; }
00420     case 2 :  { pam = ( abs(phib1) < threshold ) ? PT14H  : PT14L;  break; }
00421     case 3 :  { pam = ( abs(phib2) < threshold ) ? PT23H  : PT23L;  break; }
00422     case 4 :  { pam = ( abs(phib2) < threshold ) ? PT24H  : PT24L;  break; }
00423     case 5 :  { pam = ( abs(phib4) < threshold ) ? PT34H  : PT34L;  break; }
00424     case 6 :  { pam = ( abs(phib1) < threshold ) ? PT12HO : PT12LO; break; }
00425     case 7 :  { pam = ( abs(phib1) < threshold ) ? PT13HO : PT13LO; break; }
00426     case 8 :  { pam = ( abs(phib1) < threshold ) ? PT14HO : PT14LO; break; }
00427     case 9 :  { pam = ( abs(phib2) < threshold ) ? PT23HO : PT23LO; break; }
00428     case 10 : { pam = ( abs(phib2) < threshold ) ? PT24HO : PT24LO; break; }
00429     case 11 : { pam = ( abs(phib4) < threshold ) ? PT34HO : PT34LO; break; }
00430     case 12 : { pam = ( abs(phib1) < threshold ) ? PT15HO : PT15LO; break; }
00431     case 13 : { pam = ( abs(phib2) < threshold ) ? PT25HO : PT25LO; break; }
00432     default : ;
00433       //cout << "L1MuDTAssignmentUnit : Error in PT ass method evaluation" << endl;
00434   }
00435               
00436   return pam;
00437 
00438 }
00439 
00440 
00441 //
00442 // calculate bend angle
00443 //
00444 int L1MuDTAssignmentUnit::getPtAddress(PtAssMethod method, int bendcharge) const {
00445 
00446   // calculate bend angle as difference of two azimuthal positions 
00447 
00448   int bendangle = 0;
00449   switch (method) {
00450     case PT12L  : { bendangle = phiDiff(1,2); break; }
00451     case PT12H  : { bendangle = phiDiff(1,2); break; }
00452     case PT13L  : { bendangle = phiDiff(1,3); break; }
00453     case PT13H  : { bendangle = phiDiff(1,3); break; }
00454     case PT14L  : { bendangle = phiDiff(1,4); break; }
00455     case PT14H  : { bendangle = phiDiff(1,4); break; }
00456     case PT23L  : { bendangle = phiDiff(2,3); break; }
00457     case PT23H  : { bendangle = phiDiff(2,3); break; }
00458     case PT24L  : { bendangle = phiDiff(2,4); break; }
00459     case PT24H  : { bendangle = phiDiff(2,4); break; }
00460     case PT34L  : { bendangle = phiDiff(4,3); break; }
00461     case PT34H  : { bendangle = phiDiff(4,3); break; }
00462     case PT12LO : { bendangle = phiDiff(1,2); break; }
00463     case PT12HO : { bendangle = phiDiff(1,2); break; }
00464     case PT13LO : { bendangle = phiDiff(1,3); break; }
00465     case PT13HO : { bendangle = phiDiff(1,3); break; }
00466     case PT14LO : { bendangle = phiDiff(1,4); break; }
00467     case PT14HO : { bendangle = phiDiff(1,4); break; }
00468     case PT23LO : { bendangle = phiDiff(2,3); break; }
00469     case PT23HO : { bendangle = phiDiff(2,3); break; }
00470     case PT24LO : { bendangle = phiDiff(2,4); break; }
00471     case PT24HO : { bendangle = phiDiff(2,4); break; }
00472     case PT34LO : { bendangle = phiDiff(4,3); break; }
00473     case PT34HO : { bendangle = phiDiff(4,3); break; }    
00474     case PT15LO : { bendangle = phiDiff(1,3); break; }
00475     case PT15HO : { bendangle = phiDiff(1,3); break; }
00476     case PT25LO : { bendangle = phiDiff(2,3); break; }
00477     case PT25HO : { bendangle = phiDiff(2,3); break; }        
00478     case NODEF :  { bendangle = 0;
00479     //                    cerr << "AssignmentUnit::getPtAddress : undefined PtAssMethod" << endl;
00480                     break;
00481                   }
00482   }
00483 
00484   int signo = 1;
00485   bendangle = (bendangle+8192)%4096;
00486   if ( bendangle > 2047 ) bendangle -= 4096;
00487   if ( bendangle < 0 ) signo = -1;
00488 
00489   if (bendcharge) return signo;
00490 
00491   bendangle = (bendangle+2048)%1024;
00492   if ( bendangle > 511 ) bendangle -= 1024;
00493 
00494   return bendangle;
00495 
00496 }
00497 
00498 
00499 //
00500 // build difference of two phi values
00501 //
00502 int L1MuDTAssignmentUnit::phiDiff(int stat1, int stat2) const {
00503 
00504   // calculate bit shift
00505 
00506   int sh_phi  = 12 - nbit_phi;
00507 
00508   // get 2 phi values and add offset (30 degrees ) for adjacent sector
00509   int sector1 = getTSphi(stat1)->sector();
00510   int sector2 = getTSphi(stat2)->sector();
00511   int phi1 = getTSphi(stat1)->phi() >> sh_phi;
00512   int phi2 = getTSphi(stat2)->phi() >> sh_phi; 
00513 
00514   // convert sector difference to values in the range -6 to +5
00515 
00516   int sectordiff = (sector2 - sector1)%12;
00517   if ( sectordiff >= 6 ) sectordiff -= 12;
00518   if ( sectordiff < -6 ) sectordiff += 12;
00519   
00520   //  assert( abs(sectordiff) <= 1 );
00521   
00522   int offset = (2144 >> sh_phi) * sectordiff;
00523   int bendangle = (phi2 - phi1 + offset) << sh_phi;
00524 
00525   return bendangle;
00526     
00527 }    
00528 
00529 
00530 //
00531 // set precision for pt-assignment of phi and phib
00532 // default is 12 bits for phi and 10 bits for phib
00533 //
00534 void L1MuDTAssignmentUnit::setPrecision() {
00535 
00536   nbit_phi  = L1MuDTTFConfig::getNbitsPtaPhi();
00537   nbit_phib = L1MuDTTFConfig::getNbitsPtaPhib();
00538 
00539 }
00540 
00541 
00542 // static data members
00543 
00544 unsigned short int L1MuDTAssignmentUnit::nbit_phi  = 12;
00545 unsigned short int L1MuDTAssignmentUnit::nbit_phib = 10;