CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/EventFilter/CSCTFRawToDigi/src/CSCSPEvent.cc

Go to the documentation of this file.
00001 #include "EventFilter/CSCTFRawToDigi/src/CSCSPEvent.h"
00002 #include <map>
00003 #include <list>
00004 #include <iostream>
00005 
00006 bool CSCSPEvent::unpack(const unsigned short *&buf) throw() {
00007         bool unpackError = false;
00008 
00009         if( (buf[0]&0xF000) != 0x9000 || (buf[1]&0xF000) != 0x9000 || (buf[2]&0xF000) != 0x9000 || (buf[3]&0xF000) != 0x9000 ||
00010                 (buf[4]&0xF000) != 0xA000 || (buf[5]&0xF000) != 0xA000 || (buf[6]&0xF000) != 0xA000 || (buf[7]&0xF000) != 0xA000 )
00011                 return true;
00012         else
00013                 unpackError |= header_.unpack(buf);
00014 
00015         if( !header_.empty() ){
00016                 // Block of Counters is added in format version 4.3 (dated by 05/27/2007)
00017                 if( header_.format_version() )
00018                         unpackError |= counters_.unpack(buf);
00019 
00020                 if( header_.format_version()<3 || !header_.suppression() ){
00021                         for(unsigned short tbin=0; tbin<header_.nTBINs(); tbin++)
00022                                 unpackError |= record_[tbin].unpack(buf,header_.active(),header_.suppression(),tbin);
00023                 } else {
00024                         // For the v.5.3 zero supression tbin has to be identified from the Data Block Header (BH2d word), as opposed to plain counting when empty records are not suppressed
00025                         for(unsigned short tbin=0, actual_tbin = (buf[7] >> 8) & 0x7; tbin<header_.nTBINs(); tbin++){
00026                                 bzero(&(record_[tbin]),sizeof(record_[tbin]));
00027                                 // Check if we ran into the trailer (happens once all the records were read out)
00028                                 if( (buf[0]&0xF000)==0xF000 && (buf[1]&0xF000)==0xF000 && (buf[2]&0xF000)==0xF000 && (buf[3]&0xF000)==0xF000 &&
00029                                         (buf[4]&0xF000)==0xE000 && (buf[5]&0xF000)==0xE000 && (buf[6]&0xF000)==0xE000 && (buf[7]&0xF000)==0xE000 ) break;
00030                                 // Skip supressed empty tbins in the format version >=5.3
00031                                 if( tbin+1 != actual_tbin ) continue;
00032                                 // Unpack the record
00033                                 unpackError |= record_[tbin].unpack(buf,header_.active(),header_.suppression(),tbin);
00034                                 actual_tbin = (buf[7] >> 8) & 0x7;
00035                         }
00036                 }
00037 
00038                 // Link initial LCTs to the tracks in each time bin
00039                 for(unsigned short tbin=0; tbin<header_.nTBINs(); tbin++){
00040                         for(unsigned short trk=0; trk<3; trk++){
00041                                 CSCSP_SPblock &track = record_[tbin].sp[trk];
00042                                 if( track.ME1_id()==0 && track.ME2_id()==0 && track.ME3_id()==0 && track.ME4_id()==0 && track.MB_id()==0 ) continue;
00043                                 // The key LCT identified by the BXA algorithm is the second earliest LCT
00044                                 int second_earliest_lct_delay = -1; // this is going to be a # tbins the key LCT was delayed to allign with the latest LCT
00045                                 if( track.mode() != 15 && track.mode() != 11 ){ // BXA works only on non halo tracks and non-singles
00046                                         // BXA algorithm is not trivial: first let's order all the delays (MEx_tbin), which are aligning LCTs to the tbin of the latest LCT
00047                                         std::map< int, std::list<int> > timeline;
00048                                         if( track.ME1_id() ) timeline[track.ME1_tbin()].push_back(1);
00049                                         if( track.ME2_id() ) timeline[track.ME2_tbin()].push_back(2);
00050                                         if( track.ME3_id() ) timeline[track.ME3_tbin()].push_back(3);
00051                                         if( track.ME4_id() ) timeline[track.ME4_tbin()].push_back(4);
00052                                         if( track.MB_id()  ) timeline[track.MB_tbin() ].push_back(5);
00053                                         int earliest_lct_delay = -1; //, second_earliest_lct_delay = -1;
00054                                         // Going from largest to smallest delay (earliest LCT pops up first in the loop)
00055                                         for(int delay=7; delay>=0 && second_earliest_lct_delay==-1; delay--){
00056                                                 std::list<int>::const_iterator iter = timeline[delay].begin();
00057                                                 while( iter != timeline[delay].end() && second_earliest_lct_delay==-1 ){
00058                                                         if( earliest_lct_delay==-1 ) earliest_lct_delay=delay;
00059                                                         else if( second_earliest_lct_delay==-1 ) second_earliest_lct_delay=delay;
00060                                                         iter++;
00061                                                 }
00062                                         }
00063                                 } else second_earliest_lct_delay = 0;
00064 
00065                                 // MEx_tbin are LCTs delays shifting all of them to the bx of last LCT used to build a track
00066                                 //  let's convert delays to TBINs keeping in mind that absolute_lct_tbin = track_tbin + (second_earliest_delay - lct_delay)
00067                                 if( track.ME1_id() ){ // if track contains LCT from the ME1
00068                                         unsigned int mpc = ( track.ME1_id()>3 ? 1 : 0 );
00069                                         int ME1_tbin = tbin + second_earliest_lct_delay - track.ME1_tbin();
00071                                         if( ME1_tbin>=0 && ME1_tbin<7 ) {
00072                                                 std::vector<CSCSP_MEblock> lcts = record_[ME1_tbin].LCTs(mpc);
00073                                                 for(std::vector<CSCSP_MEblock>::const_iterator lct=lcts.begin(); lct!=lcts.end(); lct++)
00074                                                         // Due to old MPC firmware link information was not accessible for some data:
00075                                                         //if( lct->link()==(mpc?track.ME1_id()-3:track.ME1_id()) ){
00076                                                         if( ((lct->spInput()-1)%3+1)==(mpc?track.ME1_id()-3:track.ME1_id()) ){
00077                                                                 track.lct_[0] = *lct;
00078                                                                 track.lctFilled[0] = true;
00079                                                         }
00080                                         }
00081                                 }
00082                                 if( track.ME2_id() ){ // ... ME2
00083                                         int ME2_tbin = tbin + second_earliest_lct_delay - track.ME2_tbin();
00085                                         if( ME2_tbin>=0 && ME2_tbin<7 ) {
00086                                                 std::vector<CSCSP_MEblock> lcts = record_[ME2_tbin].LCTs(2);
00087                                                 for(std::vector<CSCSP_MEblock>::const_iterator lct=lcts.begin(); lct!=lcts.end(); lct++)
00088                                                         // Due to old MPC firmware link information was not accessible for some data:
00089                                                         //if( lct->link()==track.ME2_id() ){
00090                                                         if( ((lct->spInput()-1)%3+1)==track.ME2_id() ){
00091                                                                 track.lct_[1] = *lct;
00092                                                                 track.lctFilled[1] = true;
00093                                                         }
00094                                         }
00095                                 }
00096                                 if( track.ME3_id() ){ // ... ME3
00097                                         int ME3_tbin = tbin + second_earliest_lct_delay - track.ME3_tbin();
00099                                         if( ME3_tbin>=0 && ME3_tbin<7 ) {
00100                                                 std::vector<CSCSP_MEblock> lcts = record_[ME3_tbin].LCTs(3);
00101                                                 for(std::vector<CSCSP_MEblock>::const_iterator lct=lcts.begin(); lct!=lcts.end(); lct++)
00102                                                         // Due to old MPC firmware link information was not accessible for some data:
00103                                                         //if( lct->link()==track.ME3_id() ){
00104                                                         if( ((lct->spInput()-1)%3+1)==track.ME3_id() ){
00105                                                                 track.lct_[2] = *lct;
00106                                                                 track.lctFilled[2] = true;
00107                                                         }
00108                                         }
00109                                 }
00110                                 if( track.ME4_id() ){ // ... fourth station
00111                                         int ME4_tbin = tbin + second_earliest_lct_delay - track.ME4_tbin();
00113                                         if( ME4_tbin>=0 && ME4_tbin<7 ) {
00114                                                 std::vector<CSCSP_MEblock> lcts = record_[ME4_tbin].LCTs(4);
00115                                                 for(std::vector<CSCSP_MEblock>::const_iterator lct=lcts.begin(); lct!=lcts.end(); lct++)
00116                                                         // Due to old MPC firmware link information was not accessible for some data:
00117                                                         //if( lct->link()==track.ME4_id() ){
00118                                                         if( ((lct->spInput()-1)%3+1)==track.ME4_id() ){
00119                                                                 track.lct_[3] = *lct;
00120                                                                 track.lctFilled[3] = true;
00121                                                         }
00122                                         }
00123                                 }
00124                                 if( track.MB_id() ){  // ... barrel
00125                                         int MB_tbin = tbin + second_earliest_lct_delay - track.MB_tbin();
00127                                         if( MB_tbin>=0 && MB_tbin<7 ) {
00128                                                 std::vector<CSCSP_MBblock> stubs = record_[MB_tbin].mbStubs();
00129                                                 for(std::vector<CSCSP_MBblock>::const_iterator stub=stubs.begin(); stub!=stubs.end(); stub++)
00130                                                         if( (stub->id()==1 && track.MB_id()%2==1) || (stub->id()==2 && track.MB_id()%2==0) ){
00131                                                                 track.dt_ = *stub;
00132                                                                 track.dtFilled = true;
00133                                                         }
00134                                         }
00135                                 }
00136                         }
00137                 }
00138         }
00139         unpackError |= trailer_.unpack(buf);
00140 
00141         return unpackError;
00142 }
00143