CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/L1Trigger/DTTrackFinder/src/L1MuDTEtaProcessor.cc

Go to the documentation of this file.
00001 //-------------------------------------------------
00002 //
00003 //   Class: L1MuDTEtaProcessor
00004 //
00005 //   Description: Eta Processor
00006 //
00007 //                An Eta Processor consists of :
00008 //                a receiver unit,
00009 //                one Eta Track Finder (ETF) and 
00010 //                one Eta Matching Unit (EMU) 
00011 //
00012 //   $Date: 2009/06/02 14:59:09 $
00013 //   $Revision: 1.19 $
00014 //
00015 //   Author :
00016 //   N. Neumeister            CERN EP
00017 //   J. Troconiz              UAM Madrid
00018 //
00019 //--------------------------------------------------
00020 
00021 //-----------------------
00022 // This Class's Header --
00023 //-----------------------
00024 
00025 #include "L1Trigger/DTTrackFinder/src/L1MuDTEtaProcessor.h"
00026 
00027 //---------------
00028 // C++ Headers --
00029 //---------------
00030 
00031 #include <iostream>
00032 #include <iomanip>
00033 #include <bitset>
00034 
00035 //-------------------------------
00036 // Collaborating Class Headers --
00037 //-------------------------------
00038 
00039 #include "L1Trigger/DTTrackFinder/src/L1MuDTTFConfig.h"
00040 #include "L1Trigger/DTTrackFinder/src/L1MuDTTrackSegEta.h"
00041 #include "L1Trigger/DTTrackFinder/src/L1MuDTSecProcId.h"
00042 #include "L1Trigger/DTTrackFinder/src/L1MuDTSectorProcessor.h"
00043 #include "L1Trigger/DTTrackFinder/interface/L1MuDTTrackFinder.h"
00044 #include "L1Trigger/DTTrackFinder/interface/L1MuDTTrack.h"
00045 #include "CondFormats/L1TObjects/interface/L1MuDTEtaPattern.h"
00046 #include "CondFormats/L1TObjects/interface/L1MuDTEtaPatternLut.h"
00047 #include "CondFormats/DataRecord/interface/L1MuDTEtaPatternLutRcd.h"
00048 #include "CondFormats/L1TObjects/interface/L1MuDTQualPatternLut.h"
00049 #include "CondFormats/DataRecord/interface/L1MuDTQualPatternLutRcd.h"
00050 #include "CondFormats/L1TObjects/interface/L1MuDTTFMasks.h"
00051 #include "CondFormats/DataRecord/interface/L1MuDTTFMasksRcd.h"
00052 #include "DataFormats/L1DTTrackFinder/interface/L1MuDTChambThDigi.h"
00053 #include "DataFormats/L1DTTrackFinder/interface/L1MuDTChambThContainer.h"
00054 
00055 using namespace std;
00056 
00057 // --------------------------------
00058 //       class L1MuDTEtaProcessor
00059 //---------------------------------
00060 
00061 //----------------
00062 // Constructors --
00063 //----------------
00064 
00065 L1MuDTEtaProcessor::L1MuDTEtaProcessor(const L1MuDTTrackFinder& tf, int id) :
00066       m_tf(tf), m_epid(id), m_foundPattern(0), m_tseta(15) {
00067 
00068   m_tseta.reserve(15);
00069   
00070 }
00071 
00072 
00073 //--------------
00074 // Destructor --
00075 //--------------
00076 
00077 L1MuDTEtaProcessor::~L1MuDTEtaProcessor() {}
00078 
00079 
00080 //--------------
00081 // Operations --
00082 //--------------
00083 
00084 //
00085 // run Eta Processor
00086 //
00087 void L1MuDTEtaProcessor::run(int bx, const edm::Event& e, const edm::EventSetup& c) {
00088 
00089   if ( L1MuDTTFConfig::getEtaTF() ) {
00090     receiveData(bx,e,c);
00091     runEtaTrackFinder(c);
00092   }
00093 
00094   receiveAddresses();
00095   runEtaMatchingUnit(c);
00096 
00097   assign();
00098 
00099 }
00100 
00101 
00102 //
00103 // reset Eta Processor
00104 //
00105 void L1MuDTEtaProcessor::reset() {
00106 
00107   vector<const L1MuDTTrackSegEta*>::iterator iter = m_tseta.begin();
00108   while ( iter != m_tseta.end() ) {
00109     if ( *iter ) {
00110       delete *iter;
00111       *iter = 0;
00112     }
00113     iter++;
00114   }
00115 
00116   m_tseta.clear();
00117   
00118   for ( int i = 0; i < 12; i++ ) {
00119     m_eta[i] = 99;
00120     m_fine[i] = false;
00121     m_pattern[i] = 0;
00122     m_address[i] = 0;
00123     m_TrackCand[i] = 0;
00124     m_TracKCand[i] = 0;
00125   }
00126 
00127   m_foundPattern.clear();
00128 
00129   m_mask = true;
00130 
00131 } 
00132 
00133 
00134 //
00135 // print track candidates found in Eta Processor
00136 //
00137 void L1MuDTEtaProcessor::print() const {
00138 
00139   bool empty1 = true;
00140   for ( int i = 0; i < 15; i++ ) {
00141     empty1 &= ( m_tseta[i] == 0 || m_tseta[i]->empty() );
00142   }
00143 
00144   bool empty2 = true;
00145   for ( int i = 0; i < 12; i++ ) {  
00146     empty2 &= ( m_address[i] == 0 );
00147   }
00148 
00149   if ( !empty1 || !empty2 ) {
00150     cout << "Eta processor " << m_epid << " : " << endl;
00151   
00152    // print local pattern
00153    if ( !empty1 ) {
00154      cout << "Local pattern : " << endl;
00155      for ( int i = 0; i < 15; i++ ) {
00156        if ( (i+5)%5 == 0 ) cout << "station " << m_tseta[i]->station() << " : ";
00157        bitset<7> pos(m_tseta[i]->position());
00158        bitset<7> qua(m_tseta[i]->quality());
00159        for ( int j = 6; j >= 0; j-- ) {
00160          cout << pos[j]+qua[j];
00161        }
00162        cout << " ";
00163        if ( (i+1)%5 == 0 ) cout << endl;
00164      }
00165      cout << "Found patterns :" << endl;
00166      vector<int>::const_iterator iter;
00167      for ( iter = m_foundPattern.begin(); iter != m_foundPattern.end(); iter++ ) {
00168         const L1MuDTEtaPattern p = theEtaPatternLUT->getPattern(*iter);
00169         int qualitycode = p.quality();
00170         cout << "ID = " << setw(4) << p.id() << "  "
00171              << "eta = " << setw(3) << p.eta() << "  "
00172              << "quality = " << setw(2) << qualitycode << " ("
00173              << quality(qualitycode,1) << " "
00174              << quality(qualitycode,2) << " " 
00175              << quality(qualitycode,3) << ")";
00176         for ( int i = 0; i < 12; i++ ) { 
00177           if ( m_pattern[i] ==  p.id() ) cout << " <--";
00178         }
00179         cout << endl;     
00180       }
00181     }
00182     
00183     cout << "Received addresses : " << endl;
00184     for ( int i = 0; i < 12; i++ ) cout << setw(3) << m_address[i] << " ";
00185     cout << endl;
00186     
00187     if ( !empty1 ) {
00188       cout << "Matched patterns : " << endl;
00189       for ( int i = 0; i < 12; i++ ) {      
00190         if ( m_fine[i] ) {
00191           const L1MuDTEtaPattern p = theEtaPatternLUT->getPattern(m_pattern[i]);
00192           int fineeta = p.eta();
00193           int coarseeta = theQualPatternLUT->getCoarseEta(i/2+1,m_address[i]);
00194           cout << "Index = " << setw(2) << i << ", "
00195                << "address = " << setw(2) << m_address[i] << " --> " 
00196                << "pattern = " << setw(4) << m_pattern[i] << " "
00197                << "eta (coarse) = " << setw(3) << coarseeta << " "
00198                << "eta (fine) = " << setw(3) << fineeta << " "
00199                << "quality = " << setw(2) << p.quality() << endl;
00200         }
00201       }
00202     }
00203 
00204     cout << "Eta values and fine bits : " << endl;
00205     for ( int i = 0; i < 12; i++ ) cout << setw(3) << m_eta[i] << " ";
00206     cout << endl;
00207     for ( int i = 0; i < 12; i++ ) cout << setw(3) << m_fine[i] << " ";
00208     cout << endl;
00209   }
00210 
00211 }
00212 
00213 
00214 //
00215 // receive data ( 15*3 DTBX eta trigger primitives )
00216 //
00217 void L1MuDTEtaProcessor::receiveData(int bx, const edm::Event& e, const edm::EventSetup& c) {
00218 
00219   c.get< L1MuDTTFMasksRcd >().get( msks );
00220 
00221   edm::Handle<L1MuDTChambThContainer> dttrig;
00222   e.getByLabel(L1MuDTTFConfig::getDTDigiInputTag(),dttrig);
00223 
00224   // const int bx_offset = dttrig->correctBX();
00225   int bx_offset=0;
00226   bx = bx + bx_offset;
00227   
00228   //
00229   // get 5*3 eta track segments
00230   //
00231   int sector = m_epid;
00232   for ( int stat = 1; stat <= 3; stat++ ) {
00233     for ( int wheel = -2; wheel <= 2; wheel++ ) {
00234       L1MuDTChambThDigi* tseta = dttrig->chThetaSegm(wheel,stat,sector,bx);
00235       bitset<7> pos;
00236       bitset<7> qual;
00237 
00238       int lwheel = wheel+1;
00239       if ( wheel < 0 ) lwheel = wheel-1;
00240 
00241       bool masked = false;
00242       if ( stat == 1 ) masked = msks->get_etsoc_chdis_st1(lwheel, sector);
00243       if ( stat == 2 ) masked = msks->get_etsoc_chdis_st2(lwheel, sector);
00244       if ( stat == 3 ) masked = msks->get_etsoc_chdis_st3(lwheel, sector);
00245 
00246       if ( !masked ) m_mask = false;
00247 
00248       if ( tseta && !masked ) {
00249 
00250         if ( wheel == -2 || wheel == -1 || 
00251              ( wheel == 0 && (sector == 0 || sector == 3 || sector == 4 || sector == 7 || sector == 8 || sector == 11) ) ) {
00252           for ( int i = 0; i < 7; i++ ) {
00253             if ( tseta->position(i) ) pos.set(6-i);
00254             if ( tseta->quality(i) ) qual.set(6-i);
00255           }
00256         } else {
00257           for ( int i = 0; i < 7; i++ ) {
00258             if ( tseta->position(i) ) pos.set(i);
00259             if ( tseta->quality(i) ) qual.set(i);
00260           }
00261         }
00262       }
00263 
00264       const L1MuDTTrackSegEta* tmpts = new L1MuDTTrackSegEta(wheel,sector,stat,pos.to_ulong(),qual.to_ulong(),bx-bx_offset);
00265       m_tseta.push_back(tmpts);
00266     } 
00267   }
00268   
00269 }
00270 
00271 
00272 //
00273 // receive track addresses from 6 Sector Processors
00274 //
00275 void L1MuDTEtaProcessor::receiveAddresses() {
00276 
00277   // get track address code of all track segments
00278   // 6*2 times 5 bits; valid range [1-22]
00279 
00280   int sector = m_epid;
00281   
00282   int i = 0;
00283   for ( int wheel = -3; wheel <= 3; wheel++ ) {
00284     if ( wheel == 0 ) continue;
00285     L1MuDTSecProcId tmpspid(wheel,sector);
00286     for ( int number = 0; number < 2; number++ ) { 
00287       const L1MuDTTrack* cand = m_tf.sp(tmpspid)->track(number);
00288       const L1MuDTTrack* canD = m_tf.sp(tmpspid)->tracK(number);
00289       if ( cand ) {
00290         m_address[i] = cand->address().trackAddressCode();
00291         if ( !cand->empty() ) {
00292           m_TrackCand[i] = const_cast<L1MuDTTrack*>(cand);
00293           m_TracKCand[i] = const_cast<L1MuDTTrack*>(canD);
00294         }
00295         i++;
00296       }
00297     }
00298   }
00299   
00300 }  
00301 
00302 
00303 //
00304 // run Eta Track Finder (ETF)
00305 //
00306 void L1MuDTEtaProcessor::runEtaTrackFinder(const edm::EventSetup& c) {
00307 
00308   c.get< L1MuDTEtaPatternLutRcd >().get( theEtaPatternLUT );
00309 
00310   // check if there are any data
00311   bool empty = true;
00312   for ( int i = 0; i < 15; i++ ) {
00313     empty &= m_tseta[i]->empty();
00314   }
00315   if ( empty ) return;
00316 
00317   // Pattern comparator: 
00318   // loop over all patterns and compare with local chamber pattern
00319   // result : list of valid pattern IDs ( m_foundPattern )
00320   L1MuDTEtaPatternLut::ETFLut_iter it = theEtaPatternLUT->begin();
00321   while ( it != theEtaPatternLUT->end() ) {
00322   
00323     const L1MuDTEtaPattern pattern = (*it).second;
00324     int qualitycode = pattern.quality();
00325 
00326     bool good = true;
00327 
00328     for ( int station = 0; station < 3; station++) {
00329       int q = quality(qualitycode,station+1);
00330       int wheel = pattern.wheel(station+1);
00331       int bin = pattern.position(station+1);
00332       if ( bin == 0 ) continue;
00333       bitset<7> pos  = m_tseta[wheel+2 + station*5]->position();
00334       bitset<7> qual = m_tseta[wheel+2 + station*5]->quality();
00335       // compare position
00336       good &= pos.test(bin-1);
00337       // compare quality
00338       if ( q == 2 ) good &= qual.test(bin-1);  
00339     }
00340 
00341     if ( good ) m_foundPattern.push_back(pattern.id());
00342 
00343     it++;
00344     
00345   }
00346 
00347 }
00348 
00349 
00350 //
00351 // run Eta Matching Unit (EMU)
00352 //
00353 void L1MuDTEtaProcessor::runEtaMatchingUnit(const edm::EventSetup& c) {
00354   
00355   c.get< L1MuDTQualPatternLutRcd >().get( theQualPatternLUT );
00356 
00357   // loop over all addresses
00358   for ( int i = 0; i < 12; i++ ) {
00359   
00360     int adr = m_address[i];
00361     if ( adr == 0 ) continue;
00362     int sp = i/2 + 1;       //sector processor [1,6]
00363     
00364     // assign coarse eta value
00365     if ( !m_mask ) m_eta[i] = theQualPatternLUT->getCoarseEta(sp,adr);
00366     if ( m_eta[i] == 99 ) m_eta[i] = 32;
00367     if ( m_eta[i] > 31 ) m_eta[i] -= 64;
00368     m_eta[i] += 32;
00369     
00370     if ( m_foundPattern.empty() ) continue;
00371     
00372     // get list of qualified patterns ordered by quality 
00373     // and compare with found patterns
00374     const vector<short>& qualifiedPatterns = theQualPatternLUT->getQualifiedPatterns(sp,adr);
00375     vector<short>::const_iterator iter;
00376     vector<int>::const_iterator f_iter;
00377     for ( iter = qualifiedPatterns.begin(); iter != qualifiedPatterns.end(); iter++ ) {
00378       f_iter = find(m_foundPattern.begin(),m_foundPattern.end(),(*iter));
00379       // found
00380       if ( f_iter != m_foundPattern.end() ) {
00381         const L1MuDTEtaPattern p = theEtaPatternLUT->getPattern(*f_iter);
00382         // assign fine eta value     
00383         m_fine[i] = true;
00384         m_eta[i]  = p.eta();  // improved eta
00385         if ( m_eta[i] == 99 ) m_eta[i] = 32;
00386         if ( m_eta[i] > 31 ) m_eta[i] -= 64;
00387         m_eta[i] += 32;
00388         m_pattern[i] = (*f_iter);
00389         break;
00390       }
00391     }
00392     
00393   }
00394   
00395   // if both tracks from one sector processor deliver the same track address
00396   // both tracks get only a coarse eta value!  
00397   
00398   // loop over sector processors
00399   for ( int i = 0; i < 6; i++ ) {
00400     int idx1 = 2*i;
00401     int idx2 = 2*i+1;
00402     int adr1 = m_address[idx1];
00403     int adr2 = m_address[idx2];
00404     if ( adr1 == 0 || adr2 == 0 ) continue;
00405     if ( adr1 == adr2 && !m_mask ) {
00406       // both tracks get coarse (default) eta value
00407       m_eta[idx1]  = theQualPatternLUT->getCoarseEta(i+1,adr1);
00408       if ( m_eta[idx1] == 99 ) m_eta[idx1] = 32;
00409       if ( m_eta[idx1] > 31 ) m_eta[idx1] -= 64;
00410       m_eta[idx1] += 32;
00411       m_pattern[idx1] = 0;
00412       m_fine[idx1] = false; 
00413       m_eta[idx2]  = theQualPatternLUT->getCoarseEta(i+1,adr2);
00414       if ( m_eta[idx2] == 99 ) m_eta[idx2] = 32;
00415       if ( m_eta[idx2] > 31 ) m_eta[idx2] -= 64;
00416       m_eta[idx2] += 32;
00417       m_pattern[idx2] = 0;
00418       m_fine[idx2] = false; 
00419     }  
00420   }
00421 
00422 }  
00423 
00424 
00425 //
00426 // assign values to track candidates
00427 //
00428 void L1MuDTEtaProcessor::assign() {
00429 
00430   for ( int i = 0; i < 12; i++ ) {
00431     if ( m_TrackCand[i] ) {
00432       if ( m_eta[i] != 99 ) { 
00433         m_TrackCand[i]->setEta(m_eta[i]);
00434         m_TracKCand[i]->setEta(m_eta[i]);
00435       }
00436       else {  
00437         //        if ( i/2 != 2 ) cerr << "L1MuDTEtaProcessor: assign invalid eta" << " " << m_address[i] << endl;
00438       }
00439       if ( m_fine[i] ) {
00440         m_TrackCand[i]->setFineEtaBit();
00441         m_TracKCand[i]->setFineEtaBit();
00442         // find all contributing track segments 
00443         const L1MuDTEtaPattern p = theEtaPatternLUT->getPattern(m_pattern[i]);
00444         vector<const L1MuDTTrackSegEta*> TSeta;
00445         const L1MuDTTrackSegEta* ts = 0;
00446         for ( int stat = 0; stat < 3; stat++ ) {
00447           int wh = p.wheel(stat+1);
00448           int pos = p.position(stat+1);
00449           if ( pos == 0 ) continue;
00450           ts = m_tseta[wh+2 + stat*5];
00451           TSeta.push_back(ts);
00452         }
00453         m_TrackCand[i]->setTSeta(TSeta);
00454         m_TracKCand[i]->setTSeta(TSeta);
00455       }  
00456     }
00457   }
00458 
00459 }
00460   
00461 
00462 //
00463 // get quality:  id [0,26], stat [1,3]
00464 //    
00465 int L1MuDTEtaProcessor::quality(int id, int stat) {
00466 
00467   // quality codes as defined in CMS Note 2001/027
00468   // This QualityPatterns are used to have a defined Quality-Identifier for
00469   // all possible found tracks.
00470   // Therefore three integer numbers ( Station 1, 2, 3 from left to right )
00471   // can have numbers like 0, 1 or 2
00472   //    0 ... no hit is given
00473   //    1 ... a LTRG is given
00474   //    2 ... a HTRG is given
00475 
00476   const int qualcode[27][3] = { {0,0,0},{1,0,0},{0,1,0},{0,0,1},{2,0,0},
00477                                 {0,2,0},{0,0,2},{1,1,0},{1,0,1},{0,1,1},
00478                                 {2,1,0},{1,2,0},{2,0,1},{1,0,2},{0,2,1},
00479                                 {0,1,2},{2,2,0},{2,0,2},{0,2,2},{1,1,1},
00480                                 {2,1,1},{1,2,1},{1,1,2},{2,2,1},{2,1,2},
00481                                 {1,2,2},{2,2,2} };
00482 
00483   return qualcode[id][stat-1];
00484 
00485 }