Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:10:28

0001 #include "FWCore/Framework/interface/stream/EDProducer.h"
0002 #include "FWCore/Framework/interface/ConsumesCollector.h"
0003 #include <FWCore/ParameterSet/interface/ParameterSet.h>
0004 #include <FWCore/Utilities/interface/InputTag.h>
0005 
0006 //CSC Track Finder Raw Data Format
0007 #include "EventFilter/CSCTFRawToDigi/src/CSCTFEvent.h"
0008 
0009 //FEDRawData
0010 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
0011 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0012 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0013 
0014 #include <vector>
0015 #include <string>
0016 
0017 class CSCTriggerMapping;
0018 
0019 class CSCTFUnpacker : public edm::stream::EDProducer<> {
0020 private:
0021   int m_minBX, m_maxBX;
0022   bool swapME1strips;
0023 
0024   CSCTriggerMapping* mapping;  // redundant, but needed
0025 
0026   CSCTFEvent tfEvent;  // TF data container
0027 
0028   // geometry may not be properly set in CSC TF data
0029   // make an artificial assignment of each of 12 SPs (slots 6-11 and 16-21) to 12 sectors (1-12, 0-not assigned)
0030   std::vector<int> slot2sector;
0031 
0032   // label of the module which produced raw data
0033   edm::InputTag producer;
0034 
0035   edm::EDGetTokenT<FEDRawDataCollection> Raw_token;
0036 
0037 public:
0038   void produce(edm::Event& e, const edm::EventSetup& c) override;
0039 
0040   CSCTFUnpacker(const edm::ParameterSet& pset);
0041   ~CSCTFUnpacker(void) override;
0042 };
0043 
0044 //Framework stuff
0045 #include "DataFormats/Common/interface/Handle.h"
0046 #include "FWCore/Framework/interface/Event.h"
0047 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0048 
0049 //Digi
0050 #include "DataFormats/CSCDigi/interface/CSCCorrelatedLCTDigi.h"
0051 #include "DataFormats/L1CSCTrackFinder/interface/L1Track.h"
0052 #include "DataFormats/L1CSCTrackFinder/interface/L1CSCSPStatusDigi.h"
0053 #include "DataFormats/L1CSCTrackFinder/interface/TrackStub.h"
0054 
0055 //Digi collections
0056 #include "DataFormats/CSCDigi/interface/CSCCorrelatedLCTDigiCollection.h"
0057 #include "DataFormats/L1CSCTrackFinder/interface/L1CSCTrackCollection.h"
0058 #include "DataFormats/L1CSCTrackFinder/interface/L1CSCStatusDigiCollection.h"
0059 #include "DataFormats/L1CSCTrackFinder/interface/CSCTriggerContainer.h"
0060 
0061 //Unique key
0062 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
0063 #include "DataFormats/MuonDetId/interface/DTChamberId.h"
0064 
0065 //Don't know what
0066 #include <EventFilter/CSCTFRawToDigi/interface/CSCTFMonitorInterface.h>
0067 #include "FWCore/ServiceRegistry/interface/Service.h"
0068 
0069 #include "CondFormats/CSCObjects/interface/CSCTriggerMappingFromFile.h"
0070 //#include <DataFormats/MuonDetId/interface/CSCTriggerNumbering.h>
0071 
0072 //#include <iostream>
0073 #include <sstream>
0074 
0075 CSCTFUnpacker::CSCTFUnpacker(const edm::ParameterSet& pset) : edm::stream::EDProducer<>(), mapping(nullptr) {
0076   LogDebug("CSCTFUnpacker|ctor") << "Started ...";
0077 
0078   // Edges of the time window, which LCTs are put into (unlike tracks, which are always centred around 0):
0079   m_minBX = pset.getParameter<int>("MinBX");  //3
0080   m_maxBX = pset.getParameter<int>("MaxBX");  //9
0081 
0082   // Swap: if(swapME1strips && me1b && !zplus) strip = 65 - strip; // 1-64 -> 64-1 :
0083   swapME1strips = pset.getParameter<bool>("swapME1strips");
0084 
0085   // Initialize slot<->sector assignment
0086   slot2sector = pset.getParameter<std::vector<int>>("slot2sector");
0087   LogDebug("CSCTFUnpacker|ctor") << "Verifying slot<->sector map from 'vint32 slot2sector'";
0088   for (int slot = 0; slot < 22; slot++)
0089     if (slot2sector[slot] < 0 || slot2sector[slot] > 12)
0090       throw cms::Exception("Invalid configuration") << "CSCTFUnpacker: sector index is set out of range (slot2sector["
0091                                                     << slot << "]=" << slot2sector[slot] << ", should be [0-12])";
0092   // Just for safety (in case of bad data):
0093   slot2sector.resize(32);
0094 
0095   // As we use standard CSC digi containers, we have to initialize mapping:
0096   std::string mappingFile = pset.getParameter<std::string>("mappingFile");
0097   if (mappingFile.length()) {
0098     LogDebug("CSCTFUnpacker|ctor") << "Define ``mapping'' only if you want to screw up real geometry";
0099     mapping = new CSCTriggerMappingFromFile(mappingFile);
0100   } else {
0101     LogDebug("CSCTFUnpacker|ctor") << "Generating default hw<->geometry mapping";
0102     class M : public CSCTriggerSimpleMapping {
0103       void fill(void) override {}
0104     };
0105     mapping = new M();
0106     for (int endcap = 1; endcap <= 2; endcap++)
0107       for (int station = 1; station <= 4; station++)
0108         for (int sector = 1; sector <= 6; sector++)
0109           for (int csc = 1; csc <= 9; csc++) {
0110             if (station == 1) {
0111               mapping->addRecord(endcap, station, sector, 1, csc, endcap, station, sector, 1, csc);
0112               mapping->addRecord(endcap, station, sector, 2, csc, endcap, station, sector, 2, csc);
0113             } else
0114               mapping->addRecord(endcap, station, sector, 0, csc, endcap, station, sector, 0, csc);
0115           }
0116   }
0117 
0118   producer = pset.getParameter<edm::InputTag>("producer");
0119 
0120   produces<CSCCorrelatedLCTDigiCollection>();
0121   produces<L1CSCTrackCollection>();
0122   produces<L1CSCStatusDigiCollection>();
0123   produces<CSCTriggerContainer<csctf::TrackStub>>("DT");
0124 
0125   Raw_token = consumes<FEDRawDataCollection>(producer);
0126 }
0127 
0128 CSCTFUnpacker::~CSCTFUnpacker() {
0129   if (mapping)
0130     delete mapping;
0131 }
0132 
0133 void CSCTFUnpacker::produce(edm::Event& e, const edm::EventSetup& c) {
0134   // Get a handle to the FED data collection
0135   edm::Handle<FEDRawDataCollection> rawdata;
0136   e.getByToken(Raw_token, rawdata);
0137 
0138   // create the collection of CSC wire and strip digis as well as of DT stubs, which we receive from DTTF
0139   auto LCTProduct = std::make_unique<CSCCorrelatedLCTDigiCollection>();
0140   auto trackProduct = std::make_unique<L1CSCTrackCollection>();
0141   auto statusProduct = std::make_unique<L1CSCStatusDigiCollection>();
0142   auto dtProduct = std::make_unique<CSCTriggerContainer<csctf::TrackStub>>();
0143 
0144   for (int fedid = FEDNumbering::MINCSCTFFEDID; fedid <= FEDNumbering::MAXCSCTFFEDID; fedid++) {
0145     const FEDRawData& fedData = rawdata->FEDData(fedid);
0146     if (fedData.size() == 0)
0147       continue;
0148     //LogDebug("CSCTFUnpacker|produce");
0149     //if( monitor ) monitor->process((unsigned short*)fedData.data());
0150     unsigned int unpacking_status = tfEvent.unpack((unsigned short*)fedData.data(), fedData.size() / 2);
0151     if (unpacking_status == 0) {
0152       // There may be several SPs in event
0153       std::vector<const CSCSPEvent*> SPs = tfEvent.SPs_fast();
0154       // Cycle over all of them
0155       for (std::vector<const CSCSPEvent*>::const_iterator spItr = SPs.begin(); spItr != SPs.end(); spItr++) {
0156         const CSCSPEvent* sp = *spItr;
0157 
0158         L1CSCSPStatusDigi status;  ///
0159         status.sp_slot = sp->header().slot();
0160         status.l1a_bxn = sp->header().BXN();
0161         status.fmm_status = sp->header().status();
0162         status.track_cnt = sp->counters().track_counter();
0163         status.orbit_cnt = sp->counters().orbit_counter();
0164 
0165         // Finds central LCT BX
0166         // assumes window is odd number of bins
0167         int central_lct_bx = (m_maxBX + m_minBX) / 2;
0168 
0169         // Find central SP BX
0170         // assumes window is odd number of bins
0171         int central_sp_bx = int(sp->header().nTBINs() / 2);
0172 
0173         for (unsigned int tbin = 0; tbin < sp->header().nTBINs(); tbin++) {
0174           status.se |= sp->record(tbin).SEs();
0175           status.sm |= sp->record(tbin).SMs();
0176           status.bx |= sp->record(tbin).BXs();
0177           status.af |= sp->record(tbin).AFs();
0178           status.vp |= sp->record(tbin).VPs();
0179 
0180           for (unsigned int FPGA = 0; FPGA < 5; FPGA++)
0181             for (unsigned int MPClink = 0; MPClink < 3; ++MPClink) {
0182               std::vector<CSCSP_MEblock> lct = sp->record(tbin).LCT(FPGA, MPClink);
0183               if (lct.empty())
0184                 continue;
0185 
0186               status.link_status[lct[0].spInput() - 1] |= (1 << lct[0].receiver_status_frame1()) |
0187                                                           (1 << lct[0].receiver_status_frame2()) |
0188                                                           ((lct[0].aligment_fifo() ? 1 : 0) << 4);
0189               status.mpc_link_id |= (lct[0].link() << 2) | lct[0].mpc();
0190 
0191               int station = (FPGA ? FPGA : 1);
0192               int endcap = 0, sector = 0;
0193               if (slot2sector[sp->header().slot()]) {
0194                 endcap = slot2sector[sp->header().slot()] / 7 + 1;
0195                 sector = slot2sector[sp->header().slot()];
0196                 if (sector > 6)
0197                   sector -= 6;
0198               } else {
0199                 endcap = (sp->header().endcap() ? 1 : 2);
0200                 sector = sp->header().sector();
0201               }
0202               int subsector = (FPGA > 1 ? 0 : FPGA + 1);
0203               int cscid = lct[0].csc();
0204 
0205               try {
0206                 CSCDetId id = mapping->detId(endcap, station, sector, subsector, cscid, 0);
0207                 // corrlcts now have no layer associated with them
0208                 LCTProduct->insertDigi(id,
0209                                        CSCCorrelatedLCTDigi(0,
0210                                                             lct[0].vp(),
0211                                                             lct[0].quality(),
0212                                                             lct[0].wireGroup(),
0213                                                             (swapME1strips && cscid <= 3 && station == 1 &&
0214                                                                      endcap == 2 && lct[0].strip() < 65
0215                                                                  ? 65 - lct[0].strip()
0216                                                                  : lct[0].strip()),
0217                                                             lct[0].pattern(),
0218                                                             lct[0].l_r(),
0219                                                             (lct[0].tbin() + (central_lct_bx - central_sp_bx)),
0220                                                             lct[0].link(),
0221                                                             lct[0].BXN(),
0222                                                             0,
0223                                                             cscid));
0224               } catch (cms::Exception& e) {
0225                 edm::LogInfo("CSCTFUnpacker|produce")
0226                     << e.what() << "Not adding digi to collection in event " << sp->header().L1A()
0227                     << " (endcap=" << endcap << ",station=" << station << ",sector=" << sector
0228                     << ",subsector=" << subsector << ",cscid=" << cscid << ",spSlot=" << sp->header().slot() << ")";
0229               }
0230             }
0231 
0232           std::vector<CSCSP_MBblock> mbStubs = sp->record(tbin).mbStubs();
0233           for (std::vector<CSCSP_MBblock>::const_iterator iter = mbStubs.begin(); iter != mbStubs.end(); iter++) {
0234             int endcap, sector;
0235             if (slot2sector[sp->header().slot()]) {
0236               endcap = slot2sector[sp->header().slot()] / 7 + 1;
0237               sector = slot2sector[sp->header().slot()];
0238               if (sector > 6)
0239                 sector -= 6;
0240             } else {
0241               endcap = (sp->header().endcap() ? 1 : 2);
0242               sector = sp->header().sector();
0243             }
0244             const unsigned int csc2dt[6][2] = {{2, 3}, {4, 5}, {6, 7}, {8, 9}, {10, 11}, {12, 1}};
0245             DTChamberId id((endcap == 1 ? 2 : -2), 1, csc2dt[sector - 1][iter->id() - 1]);
0246             CSCCorrelatedLCTDigi base(0,
0247                                       iter->vq(),
0248                                       iter->quality(),
0249                                       iter->cal(),
0250                                       iter->flag(),
0251                                       iter->bc0(),
0252                                       iter->phi_bend(),
0253                                       tbin + (central_lct_bx - central_sp_bx),
0254                                       iter->id(),
0255                                       iter->bxn(),
0256                                       iter->timingError(),
0257                                       iter->BXN());
0258             csctf::TrackStub dtStub(base, id, iter->phi(), 0);
0259             dtProduct->push_back(dtStub);
0260           }
0261 
0262           std::vector<CSCSP_SPblock> tracks = sp->record(tbin).tracks();
0263           unsigned int trkNumber = 0;
0264           for (std::vector<CSCSP_SPblock>::const_iterator iter = tracks.begin(); iter != tracks.end();
0265                iter++, trkNumber++) {
0266             L1CSCTrack track;
0267             if (slot2sector[sp->header().slot()]) {
0268               track.first.m_endcap = slot2sector[sp->header().slot()] / 7 + 1;
0269               track.first.m_sector = slot2sector[sp->header().slot()];
0270               if (track.first.m_sector > 6)
0271                 track.first.m_sector -= 6;
0272             } else {
0273               track.first.m_endcap = (sp->header().endcap() ? 1 : 2);
0274               track.first.m_sector = sp->header().sector();
0275             }
0276 
0277             track.first.m_lphi = iter->phi();
0278             track.first.m_ptAddress = iter->ptLUTaddress();
0279             track.first.m_fr = iter->f_r();
0280             track.first.m_ptAddress |= (iter->f_r() << 21);
0281 
0282             track.first.setStationIds(iter->ME1_id(), iter->ME2_id(), iter->ME3_id(), iter->ME4_id(), iter->MB_id());
0283             track.first.setTbins(
0284                 iter->ME1_tbin(), iter->ME2_tbin(), iter->ME3_tbin(), iter->ME4_tbin(), iter->MB_tbin());
0285             track.first.setBx(iter->tbin() - central_sp_bx);
0286             track.first.setBits(iter->syncErr(), iter->bx0(), iter->bc0());
0287 
0288             track.first.setLocalPhi(iter->phi());
0289             track.first.setEtaPacked(iter->eta());
0290             track.first.setChargePacked(iter->charge());
0291 
0292             track.first.m_output_link = iter->id();
0293             if (track.first.m_output_link) {
0294               track.first.m_rank =
0295                   (iter->f_r() ? sp->record(tbin).ptSpy() & 0x7F : (sp->record(tbin).ptSpy() & 0x7F00) >> 8);
0296               track.first.setChargeValidPacked(
0297                   (iter->f_r() ? (sp->record(tbin).ptSpy() & 0x80) >> 8 : (sp->record(tbin).ptSpy() & 0x8000) >> 15));
0298             } else {
0299               track.first.m_rank = 0;
0300               track.first.setChargeValidPacked(0);
0301             }
0302             track.first.setFineHaloPacked(iter->halo());
0303 
0304             track.first.m_winner = iter->MS_id() & (1 << trkNumber);
0305 
0306             std::vector<CSCSP_MEblock> lcts = iter->LCTs();
0307             for (std::vector<CSCSP_MEblock>::const_iterator lct = lcts.begin(); lct != lcts.end(); lct++) {
0308               int station = (lct->spInput() > 6 ? (lct->spInput() - 1) / 3 : 1);
0309               int subsector = (lct->spInput() > 6 ? 0 : (lct->spInput() - 1) / 3 + 1);
0310               try {
0311                 CSCDetId id =
0312                     mapping->detId(track.first.m_endcap, station, track.first.m_sector, subsector, lct->csc(), 0);
0313                 track.second.insertDigi(id,
0314                                         CSCCorrelatedLCTDigi(0,
0315                                                              lct->vp(),
0316                                                              lct->quality(),
0317                                                              lct->wireGroup(),
0318                                                              (swapME1strips && lct->csc() <= 3 && station == 1 &&
0319                                                                       track.first.m_endcap == 2 && lct[0].strip() < 65
0320                                                                   ? 65 - lct[0].strip()
0321                                                                   : lct[0].strip()),
0322                                                              lct->pattern(),
0323                                                              lct->l_r(),
0324                                                              (lct->tbin() + (central_lct_bx - central_sp_bx)),
0325                                                              lct->link(),
0326                                                              lct->BXN(),
0327                                                              0,
0328                                                              lct->csc()));
0329               } catch (cms::Exception& e) {
0330                 edm::LogInfo("CSCTFUnpacker|produce")
0331                     << e.what() << "Not adding track digi to collection in event" << sp->header().L1A()
0332                     << " (endcap=" << track.first.m_endcap << ",station=" << station
0333                     << ",sector=" << track.first.m_sector << ",subsector=" << subsector << ",cscid=" << lct->csc()
0334                     << ",spSlot=" << sp->header().slot() << ")";
0335               }
0336             }
0337 
0338             std::vector<CSCSP_MBblock> mbStubs = iter->dtStub();
0339             for (std::vector<CSCSP_MBblock>::const_iterator iter = mbStubs.begin(); iter != mbStubs.end(); iter++) {
0340               CSCDetId id = mapping->detId(track.first.m_endcap, 1, track.first.m_sector, iter->id(), 1, 0);
0341               track.second.insertDigi(id,
0342                                       CSCCorrelatedLCTDigi(iter->phi(),
0343                                                            iter->vq(),
0344                                                            iter->quality() + 100,
0345                                                            iter->cal(),
0346                                                            iter->flag(),
0347                                                            iter->bc0(),
0348                                                            iter->phi_bend(),
0349                                                            tbin + (central_lct_bx - central_sp_bx),
0350                                                            iter->id(),
0351                                                            iter->bxn(),
0352                                                            iter->timingError(),
0353                                                            iter->BXN()));
0354             }
0355 
0356             trackProduct->push_back(track);
0357           }
0358         }
0359         statusProduct->second.push_back(status);
0360       }
0361     } else {
0362       edm::LogError("CSCTFUnpacker|produce")
0363           << " problem of unpacking TF event: 0x" << std::hex << unpacking_status << std::dec << " code";
0364     }
0365 
0366     statusProduct->first = unpacking_status;
0367 
0368   }  //end of fed cycle
0369   e.put(std::move(dtProduct), "DT");
0370   e.put(std::move(LCTProduct));  // put processed lcts into the event.
0371   e.put(std::move(trackProduct));
0372   e.put(std::move(statusProduct));
0373 }
0374 
0375 #include "FWCore/Framework/interface/MakerMacros.h"
0376 DEFINE_FWK_MODULE(CSCTFUnpacker);