Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-10 02:21:02

0001 /*
0002  * InputMakerPhase2.cpp
0003  *
0004  *  Created on: May 20, 2020
0005  *      Author: kbunkow
0006  */
0007 
0008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0009 #include "DataFormats/MuonDetId/interface/DTChamberId.h"
0010 #include "L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h"
0011 #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfName.h"
0012 
0013 #include <iostream>
0014 
0015 /////////////////////////////////////
0016 void DtPhase2DigiToStubsConverter::loadDigis(const edm::Event& event) {
0017   event.getByToken(inputTokenDtPh, dtPhDigis);
0018   event.getByToken(inputTokenDtTh, dtThDigis);
0019 }
0020 
0021 void DtPhase2DigiToStubsConverter::makeStubs(MuonStubPtrs2D& muonStubsInLayers,
0022                                              unsigned int iProcessor,
0023                                              l1t::tftype procTyp,
0024                                              int bxFrom,
0025                                              int bxTo,
0026                                              std::vector<std::unique_ptr<IOMTFEmulationObserver> >& observers) {
0027   if (!dtPhDigis)
0028     return;
0029 
0030   boost::property_tree::ptree procDataTree;
0031 
0032   for (const auto& digiIt : *dtPhDigis->getContainer()) {
0033     DTChamberId detid(digiIt.whNum(), digiIt.stNum(), digiIt.scNum() + 1);
0034 
0035     ///Check it the data fits into given processor input range
0036     if (!acceptDigi(detid, iProcessor, procTyp))
0037       continue;
0038 
0039     // HACK for Phase-2  (DT TPs are centered in bX=20)
0040     if (digiIt.bxNum() - 20 >= bxFrom && digiIt.bxNum() - 20 <= bxTo) {
0041       addDTphiDigi(muonStubsInLayers, digiIt, dtThDigis.product(), iProcessor, procTyp);
0042 
0043       auto& dtP2Digi = procDataTree.add_child("dtP2Digi", boost::property_tree::ptree());
0044       dtP2Digi.add("<xmlattr>.whNum", digiIt.whNum());
0045       dtP2Digi.add("<xmlattr>.scNum", digiIt.scNum());
0046       dtP2Digi.add("<xmlattr>.stNum", digiIt.stNum());
0047       dtP2Digi.add("<xmlattr>.slNum", digiIt.slNum());
0048       dtP2Digi.add("<xmlattr>.quality", digiIt.quality());
0049       dtP2Digi.add("<xmlattr>.rpcFlag", digiIt.rpcFlag());
0050       dtP2Digi.add("<xmlattr>.phi", digiIt.phi());
0051       dtP2Digi.add("<xmlattr>.phiBend", digiIt.phiBend());
0052     }
0053   }
0054 
0055   if (!mergePhiAndTheta) {
0056     for (auto& thetaDigi : (*(dtThDigis->getContainer()))) {
0057       if (thetaDigi.bxNum() >= bxFrom && thetaDigi.bxNum() <= bxTo) {
0058         addDTetaStubs(muonStubsInLayers, thetaDigi, iProcessor, procTyp);
0059       }
0060     }
0061   }
0062 
0063   for (auto& obs : observers)
0064     obs->addProcesorData("linkData", procDataTree);
0065 }
0066 
0067 //dtThDigis is provided as argument, because in the OMTF implementation the phi and eta digis are merged (even thought it is artificial)
0068 void DtPhase2DigiToStubsConverterOmtf::addDTphiDigi(MuonStubPtrs2D& muonStubsInLayers,
0069                                                     const L1Phase2MuDTPhDigi& digi,
0070                                                     const L1MuDTChambThContainer* dtThDigis,
0071                                                     unsigned int iProcessor,
0072                                                     l1t::tftype procTyp) {
0073   DTChamberId detid(digi.whNum(), digi.stNum(), digi.scNum() + 1);
0074 
0075   MuonStub stub;
0076 
0077   //converting the quality to the same encoding as in phase-1, as it is important for extrapolation
0078   if (digi.quality() >= 6)
0079     stub.qualityHw = digi.quality() - 2;
0080   else if (digi.quality() >= 3) {
0081     if (digi.slNum() == 3)
0082       stub.qualityHw = 3;
0083     else if (digi.slNum() == 1)
0084       stub.qualityHw = 2;
0085   } else {
0086     if (digi.slNum() == 3)
0087       stub.qualityHw = 1;
0088     else if (digi.slNum() == 1)
0089       stub.qualityHw = 0;
0090   }
0091 
0092   if (stub.qualityHw < config.getMinDtPhiQuality())
0093     return;
0094 
0095   unsigned int hwNumber = config.getLayerNumber(detid.rawId());
0096   if (config.getHwToLogicLayer().find(hwNumber) == config.getHwToLogicLayer().end())
0097     return;
0098 
0099   auto iter = config.getHwToLogicLayer().find(hwNumber);
0100   unsigned int iLayer = iter->second;
0101   unsigned int iInput = OMTFinputMaker::getInputNumber(&config, detid.rawId(), iProcessor, procTyp);
0102   //MuonStub& stub = muonStubsInLayers[iLayer][iInput];
0103 
0104   stub.type = MuonStub::DT_PHI_ETA;
0105 
0106   stub.phiHw = angleConverter.getProcessorPhi(
0107       OMTFinputMaker::getProcessorPhiZero(&config, iProcessor), procTyp, digi.scNum(), digi.phi());
0108 
0109   //TODO the dtThDigis are not good yet,so passing an empty container to the angleConverter
0110   //then it should return middle of chambers
0111   //remove when the dtThDigis are fixed on the DT side
0112   L1MuDTChambThContainer dtThDigisEmpty;
0113   stub.etaHw = angleConverter.getGlobalEta(detid, &dtThDigisEmpty, digi.bxNum() - 20);
0114   //in phase2, the phiB is 13 bits, and range is [-2, 2 rad] so 4 rad, 2^13 units/(4 rad) =  1^11/rad.
0115   //need to convert them to 512units==1rad (to use OLD PATTERNS...)
0116   stub.phiBHw = digi.phiBend() * config.dtPhiBUnitsRad() / 2048;
0117   //the cut if (stub.qualityHw >= config.getMinDtPhiBQuality()) is done in the ProcessorBase<GoldenPatternType>::restrictInput
0118   //as is is done like that in the firmware
0119 
0120   // need to shift 20-BX to roll-back the shift introduced by the DT TPs
0121   stub.bx = digi.bxNum() - 20;
0122   //stub.timing = digi.getTiming(); //TODO what about sub-bx timing, is is available?
0123 
0124   stub.logicLayer = iLayer;
0125   stub.detId = detid;
0126 
0127   OmtfName board(iProcessor, &config);
0128   LogTrace("l1tOmtfEventPrint") << board.name() << " L1Phase2MuDTPhDigi: detid " << detid << " digi "
0129                                 << " whNum " << digi.whNum() << " scNum " << digi.scNum() << " stNum " << digi.stNum()
0130                                 << " slNum " << digi.slNum() << " quality " << digi.quality() << " rpcFlag "
0131                                 << digi.rpcFlag() << " phi " << digi.phi() << " phiBend " << digi.phiBend()
0132                                 << std::endl;
0133   OMTFinputMaker::addStub(&config, muonStubsInLayers, iLayer, iInput, stub);
0134 }
0135 
0136 void DtPhase2DigiToStubsConverterOmtf::addDTetaStubs(MuonStubPtrs2D& muonStubsInLayers,
0137                                                      const L1MuDTChambThDigi& thetaDigi,
0138                                                      unsigned int iProcessor,
0139                                                      l1t::tftype procTyp) {
0140   //in the Phase1 omtf the theta stubs are merged with the phi in the addDTphiDigi
0141   //TODO implement if needed
0142 }
0143 
0144 bool DtPhase2DigiToStubsConverterOmtf::acceptDigi(const DTChamberId& dTChamberId,
0145                                                   unsigned int iProcessor,
0146                                                   l1t::tftype procType) {
0147   return OMTFinputMaker::acceptDtDigi(&config, dTChamberId, iProcessor, procType);
0148 }
0149 
0150 InputMakerPhase2::InputMakerPhase2(const edm::ParameterSet& edmParameterSet,
0151                                    MuStubsInputTokens& muStubsInputTokens,
0152                                    edm::EDGetTokenT<L1Phase2MuDTPhContainer> inputTokenDTPhPhase2,
0153                                    const OMTFConfiguration* config,
0154                                    std::unique_ptr<OmtfAngleConverter> angleConverter)
0155     : OMTFinputMaker(edmParameterSet, muStubsInputTokens, config, std::move(angleConverter)) {
0156   edm::LogImportant("OMTFReconstruction") << "constructing InputMakerPhase2" << std::endl;
0157 
0158   if (edmParameterSet.exists("usePhase2DTPrimitives") && edmParameterSet.getParameter<bool>("usePhase2DTPrimitives")) {
0159     if (edmParameterSet.getParameter<bool>("dropDTPrimitives") != true)
0160       throw cms::Exception(
0161           "L1TMuonOverlapPhase2 InputMakerPhase2::InputMakerPhase2 usePhase2DTPrimitives is true, but dropDTPrimitives "
0162           "is not true");
0163     //if the Phase2DTPrimitives are used, then the phase1 DT primitives should be dropped
0164     edm::LogImportant("OMTFReconstruction") << " using Phase2 DT trigger primitives" << std::endl;
0165     digiToStubsConverters.emplace_back(std::make_unique<DtPhase2DigiToStubsConverterOmtf>(
0166         config, this->angleConverter.get(), inputTokenDTPhPhase2, muStubsInputTokens.inputTokenDtTh));
0167   }
0168 }