Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:13:48

0001 #include "FWCore/Framework/interface/stream/EDProducer.h"
0002 #include "FWCore/Framework/interface/Run.h"
0003 #include "FWCore/Framework/interface/EventSetup.h"
0004 #include "FWCore/Framework/interface/Event.h"
0005 #include "FWCore/Framework/interface/MakerMacros.h"
0006 #include "FWCore/Utilities/interface/EDGetToken.h"
0007 #include "FWCore/Utilities/interface/EDPutToken.h"
0008 #include "FWCore/Utilities/interface/ESGetToken.h"
0009 #include "FWCore/Utilities/interface/InputTag.h"
0010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0011 #include "DataFormats/Common/interface/Handle.h"
0012 
0013 #include "L1Trigger/TrackTrigger/interface/Setup.h"
0014 #include "L1Trigger/TrackerTFP/interface/DataFormats.h"
0015 #include "L1Trigger/TrackerTFP/interface/DistServer.h"
0016 
0017 #include <string>
0018 #include <numeric>
0019 
0020 using namespace std;
0021 using namespace edm;
0022 using namespace trackerTFP;
0023 using namespace tt;
0024 
0025 namespace trklet {
0026 
0027   /*! \class  trklet::ProducerKFout
0028    *  \brief  Converts KF output into TFP output
0029    *  \author Christopher Brown
0030    *  \date   2021, Aug
0031    */
0032   class ProducerKFout : public stream::EDProducer<> {
0033   public:
0034     explicit ProducerKFout(const ParameterSet&);
0035     ~ProducerKFout() override {}
0036     template <typename T>
0037     int digitise(const vector<T> Bins, T Value, T factor = 1);
0038 
0039   private:
0040     void beginRun(const Run&, const EventSetup&) override;
0041     void produce(Event&, const EventSetup&) override;
0042     void endJob() {}
0043 
0044     // ED input token of kf stubs
0045     EDGetTokenT<StreamsStub> edGetTokenStubs_;
0046     // ED input token of kf tracks
0047     EDGetTokenT<StreamsTrack> edGetTokenTracks_;
0048     // ED input token of kf input to kf output TTTrack map
0049     EDGetTokenT<TTTrackRefMap> edGetTokenTTTrackRefMap_;
0050     // ED output token for accepted kfout tracks
0051     EDPutTokenT<StreamsTrack> edPutTokenAccepted_;
0052     // ED output token for truncated kfout tracks
0053     EDPutTokenT<StreamsTrack> edPutTokenLost_;
0054     // Setup token
0055     ESGetToken<Setup, SetupRcd> esGetTokenSetup_;
0056     // DataFormats token
0057     ESGetToken<DataFormats, DataFormatsRcd> esGetTokenDataFormats_;
0058     // configuration
0059     ParameterSet iConfig_;
0060     // helper class to store configurations
0061     const Setup* setup_ = nullptr;
0062     // helper class to extract structured data from tt::Frames
0063     const DataFormats* dataFormats_ = nullptr;
0064     // Bins for dPhi/dZ use to create weight LUT
0065     vector<double> dPhiBins_;
0066     vector<double> dZBins_;
0067 
0068     // Constant used throughout for partial ttrack words
0069     int partialTrackWordBits_;
0070 
0071     // For convenience and keeping readable code, accessed many times
0072     int numWorkers_;
0073   };
0074 
0075   ProducerKFout::ProducerKFout(const ParameterSet& iConfig) : iConfig_(iConfig) {
0076     const string& labelKF = iConfig.getParameter<string>("LabelKF");
0077     const string& labelAS = iConfig.getParameter<string>("LabelAS");
0078     const string& branchStubs = iConfig.getParameter<string>("BranchAcceptedStubs");
0079     const string& branchTracks = iConfig.getParameter<string>("BranchAcceptedTracks");
0080     const string& branchLost = iConfig.getParameter<string>("BranchLostTracks");
0081     // book in- and output ED products
0082     edGetTokenStubs_ = consumes<StreamsStub>(InputTag(labelKF, branchStubs));
0083     edGetTokenTracks_ = consumes<StreamsTrack>(InputTag(labelKF, branchTracks));
0084     edGetTokenTTTrackRefMap_ = consumes<TTTrackRefMap>(InputTag(labelAS, branchTracks));
0085     edPutTokenAccepted_ = produces<StreamsTrack>(branchTracks);
0086     edPutTokenLost_ = produces<StreamsTrack>(branchLost);
0087     // book ES products
0088     esGetTokenSetup_ = esConsumes<Setup, SetupRcd, Transition::BeginRun>();
0089     esGetTokenDataFormats_ = esConsumes<DataFormats, DataFormatsRcd, Transition::BeginRun>();
0090   }
0091 
0092   void ProducerKFout::beginRun(const Run& iRun, const EventSetup& iSetup) {
0093     // helper class to store configurations
0094     setup_ = &iSetup.getData(esGetTokenSetup_);
0095     if (!setup_->configurationSupported())
0096       return;
0097     // check process history if desired
0098     if (iConfig_.getParameter<bool>("CheckHistory"))
0099       setup_->checkHistory(iRun.processHistory());
0100     // helper class to extract structured data from tt::Frames
0101     dataFormats_ = &iSetup.getData(esGetTokenDataFormats_);
0102 
0103     // Calculate 1/dz**2 and 1/dphi**2 bins for v0 and v1 weightings
0104     for (int i = 0;
0105          i < pow(2, dataFormats_->width(Variable::dPhi, Process::kfin)) / pow(2, setup_->weightBinFraction());
0106          i++)
0107       dPhiBins_.push_back(
0108           pow(dataFormats_->base(Variable::dPhi, Process::kfin) * (i + 1) * pow(2, setup_->weightBinFraction()), -2));
0109 
0110     for (int i = 0; i < pow(2, dataFormats_->width(Variable::dZ, Process::kfin)) / pow(2, setup_->weightBinFraction());
0111          i++)
0112       dZBins_.push_back(
0113           pow(dataFormats_->base(Variable::dZ, Process::kfin) * (i + 1) * pow(2, setup_->weightBinFraction()), -2));
0114 
0115     partialTrackWordBits_ = TTBV::S_ / 2;
0116     numWorkers_ = setup_->kfNumWorker();
0117   }
0118 
0119   // Helper function to convert floating chi2 to chi2 bin
0120   template <typename T>
0121   int ProducerKFout::digitise(const vector<T> Bins, T Value, T factor) {
0122     for (int i = 0; i < (int)Bins.size(); i++) {
0123       if (Value * factor > Bins[i] && Value * factor <= Bins[i + 1]) {
0124         return i;
0125       }
0126     }
0127     return -1;
0128   }
0129 
0130   void ProducerKFout::produce(Event& iEvent, const EventSetup& iSetup) {
0131     // empty KFout product
0132     StreamsTrack accepted(setup_->numRegions() * setup_->tfpNumChannel());
0133     StreamsTrack lost(setup_->numRegions() * setup_->tfpNumChannel());
0134     // read in KF Product and produce KFout product
0135     if (setup_->configurationSupported()) {
0136       Handle<StreamsStub> handleStubs;
0137       iEvent.getByToken<StreamsStub>(edGetTokenStubs_, handleStubs);
0138       const StreamsStub& streamsStubs = *handleStubs.product();
0139       Handle<StreamsTrack> handleTracks;
0140       iEvent.getByToken<StreamsTrack>(edGetTokenTracks_, handleTracks);
0141       const StreamsTrack& streamsTracks = *handleTracks.product();
0142       Handle<TTTrackRefMap> handleTTTrackRefMap;
0143       iEvent.getByToken<TTTrackRefMap>(edGetTokenTTTrackRefMap_, handleTTTrackRefMap);
0144       const TTTrackRefMap& ttTrackRefMap = *handleTTTrackRefMap.product();
0145       // 18 Output Links (First Vector) each has a vector of tracks per event (second vector) each track is 3 32 bit TTBV partial tracks
0146       vector<vector<TTBV>> SortedPartialTracks(setup_->numRegions() * setup_->tfpNumChannel(), vector<TTBV>(0));
0147 
0148       TrackKFOutSAPtrCollectionss InTrackStreams;
0149       TrackKFOutSAPtrCollectionss OutTrackStreams;
0150 
0151       // Setup empty collections for input tracks to distribution server
0152       for (int iRegion = 0; iRegion < setup_->numRegions(); iRegion++) {
0153         TrackKFOutSAPtrCollections temp_collection;
0154         for (int iLink = 0; iLink < setup_->tfpNumChannel(); iLink++) {
0155           TrackKFOutSAPtrCollection temp;
0156           for (int iTrack = 0; iTrack < setup_->numFramesIO(); iTrack++)
0157             temp.emplace_back(std::make_shared<TrackKFOut>());
0158           temp_collection.push_back(temp);
0159         }
0160         OutTrackStreams.push_back(temp_collection);
0161       }
0162 
0163       // Setup empty collections for oiutpu tracks from distribution server
0164       for (int iRegion = 0; iRegion < setup_->numRegions(); iRegion++) {
0165         TrackKFOutSAPtrCollections temp_collection;
0166         for (int iLink = 0; iLink < numWorkers_; iLink++) {
0167           TrackKFOutSAPtrCollection temp;
0168           for (int iTrack = 0; iTrack < setup_->numFramesIO(); iTrack++)
0169             temp.emplace_back(std::make_shared<TrackKFOut>());
0170           temp_collection.push_back(temp);
0171         }
0172         InTrackStreams.push_back(temp_collection);
0173       }
0174 
0175       StreamsTrack OutputStreamsTracks(setup_->numRegions() * setup_->tfpNumChannel());
0176 
0177       for (int iLink = 0; iLink < (int)streamsTracks.size(); iLink++) {
0178         for (int iTrack = 0; iTrack < (int)streamsTracks[iLink].size(); iTrack++) {
0179           const auto& track = streamsTracks[iLink].at(iTrack);
0180           TrackKF InTrack(track, dataFormats_);
0181 
0182           double temp_z0 = InTrack.zT() - ((InTrack.cot() * setup_->chosenRofZ()));
0183 
0184           // Correction to Phi calcuation depending if +ve/-ve phi sector
0185           const double baseSectorCorr = InTrack.sectorPhi() ? -setup_->baseSector() : setup_->baseSector();
0186 
0187           double temp_phi0 = InTrack.phiT() - ((InTrack.inv2R()) * setup_->hybridChosenRofPhi()) + baseSectorCorr;
0188 
0189           double temp_tanL = InTrack.cotGlobal();
0190 
0191           TTBV HitPattern(0, setup_->numLayers());
0192 
0193           double tempchi2rphi = 0;
0194           double tempchi2rz = 0;
0195 
0196           for (int iStub = 0; iStub < setup_->numLayers() - 1; iStub++) {
0197             const auto& stub = streamsStubs[setup_->numLayers() * iLink + iStub].at(iTrack);
0198             StubKF InStub(stub, dataFormats_, iStub);
0199 
0200             if (!stub.first.isNonnull())
0201               continue;
0202 
0203             HitPattern.set(iStub);
0204             double phiSquared = pow(InStub.phi(), 2);
0205             double zSquared = pow(InStub.z(), 2);
0206 
0207             double tempv0 = dPhiBins_[(InStub.dPhi() / (dataFormats_->base(Variable::dPhi, Process::kfin) *
0208                                                         pow(2, setup_->weightBinFraction())))];
0209             double tempv1 = dZBins_[(
0210                 InStub.dZ() / (dataFormats_->base(Variable::dZ, Process::kfin) * pow(2, setup_->weightBinFraction())))];
0211 
0212             double tempRphi = phiSquared * tempv0;
0213             double tempRz = zSquared * tempv1;
0214 
0215             tempchi2rphi += tempRphi;
0216             tempchi2rz += tempRz;
0217           }  // Iterate over track stubs
0218 
0219           // TODO extract TTTrack bit widths from TTTrack word pending update to the TTTrack_word class
0220           TTBV TrackValid(1, 1, false);
0221           TTBV extraMVA(0, 6, false);
0222           TTBV TQMVA(0, 3, false);
0223           TTBV BendChi2(0, 3, false);
0224           TTBV Chi2rphi(
0225               digitise(setup_->kfoutchi2rphiBins(), tempchi2rphi, (double)setup_->kfoutchi2rphiConv()), 4, false);
0226           TTBV Chi2rz(digitise(setup_->kfoutchi2rzBins(), tempchi2rz, (double)setup_->kfoutchi2rzConv()), 4, false);
0227           TTBV D0(0, 13, false);
0228           TTBV z0(temp_z0, dataFormats_->base(Variable::zT, Process::kf), 12, true);
0229           TTBV TanL(temp_tanL, dataFormats_->base(Variable::cot, Process::kf), 16, true);
0230           TTBV phi0(temp_phi0, dataFormats_->base(Variable::phiT, Process::kf), 12, true);
0231           TTBV InvR(-InTrack.inv2R(), dataFormats_->base(Variable::inv2R, Process::kf), 16, true);
0232           InvR.resize(15);
0233           // 13   +   3   +   7        +  3       + 3
0234           TTBV PartialTrack3((D0 + BendChi2 + HitPattern + TQMVA + extraMVA), partialTrackWordBits_, false);
0235           // 16   + 12    + 4
0236           TTBV PartialTrack2((TanL + z0 + Chi2rz), partialTrackWordBits_, false);
0237           // 1        + 15   +  12 +    4
0238           TTBV PartialTrack1((TrackValid + InvR + phi0 + Chi2rphi), partialTrackWordBits_, false);
0239 
0240           int sortKey = (InTrack.sectorEta() < (int)(setup_->numSectorsEta() / 2)) ? 0 : 1;
0241           // Set correct bit to valid for track valid
0242           TrackKFOut Temp_track(
0243               PartialTrack1.set(31), PartialTrack2, PartialTrack3, sortKey, track, iTrack, iLink, true);
0244 
0245           InTrackStreams[iLink / numWorkers_][iLink % numWorkers_][iTrack] = (std::make_shared<TrackKFOut>(Temp_track));
0246 
0247         }  // Iterate over Tracks
0248 
0249         //Pad out input streams to Dist server with extra null track if odd number of tracks on a stream
0250         int iFinTrack = (int)streamsTracks[iLink].size();
0251         if (iFinTrack % numWorkers_ != 0) {
0252           TrackKFOut null_track(0, 0, 0, iLink % numWorkers_, tt::FrameTrack(), iFinTrack + 1, iLink, true);
0253           InTrackStreams[iLink / numWorkers_][iLink % numWorkers_][iFinTrack] =
0254               (std::make_shared<TrackKFOut>(null_track));
0255         }
0256       }  // Iterate over Links
0257       // Fill products and match up tracks
0258 
0259       // One distribution server for every region, num inputs = num KF workers, num outputs = num output links
0260       vector<DistServer> distServers(
0261           setup_->numRegions(),
0262           DistServer(numWorkers_, setup_->tfpNumChannel(), 2));  //Magic number for interleaving in dist server
0263 
0264       for (int iRegion = 0; iRegion < setup_->numRegions(); iRegion++) {
0265         for (int iTrack = 0; iTrack < setup_->numFramesIO() * ((double)TTBV::S_ / setup_->tttrackBits()); iTrack++) {
0266           TrackKFOutSAPtrCollection DistIn;
0267           for (int iWorker = 0; iWorker < numWorkers_; iWorker++)
0268             DistIn.push_back(InTrackStreams[iRegion][iWorker][iTrack]);  // Reorganise input to distribution server
0269           TrackKFOutSAPtrCollection DistOut = distServers[iRegion].clock(DistIn);  // Run dist server
0270           for (int iLink = 0; iLink < setup_->tfpNumChannel(); iLink++)
0271             OutTrackStreams[iRegion][iLink][iTrack] =
0272                 DistOut[iLink];  // Reorganise output of distribution server in output streams
0273         }
0274       }
0275 
0276       // Pack output of distribution server onto each link, with correct partial tracks in correct places
0277       for (int iRegion = 0; iRegion < setup_->numRegions(); iRegion++) {
0278         for (int iLink = 0; iLink < setup_->tfpNumChannel(); iLink++) {
0279           for (int iTrack = 0; iTrack < (int)OutTrackStreams[iRegion][iLink].size(); iTrack++) {
0280             SortedPartialTracks[2 * iRegion + iLink].push_back(
0281                 OutTrackStreams[iRegion][iLink][iTrack]->PartialTrack1());
0282             SortedPartialTracks[2 * iRegion + iLink].push_back(
0283                 OutTrackStreams[iRegion][iLink][iTrack]->PartialTrack2());
0284             SortedPartialTracks[2 * iRegion + iLink].push_back(
0285                 OutTrackStreams[iRegion][iLink][iTrack]->PartialTrack3());
0286             OutputStreamsTracks[2 * iRegion + iLink].emplace_back(OutTrackStreams[iRegion][iLink][iTrack]->track());
0287           }
0288         }
0289       }
0290 
0291       const TTBV NullBitTrack(0, partialTrackWordBits_, false);
0292       for (int iLink = 0; iLink < (int)OutputStreamsTracks.size(); iLink++) {
0293         // Iterate through partial tracks
0294         int numLinkTracks = (int)OutputStreamsTracks[iLink].size();
0295         if (numLinkTracks == 0)
0296           continue;  // Don't fill links if no tracks
0297         if ((numLinkTracks % 2 != 0)) {
0298           SortedPartialTracks[iLink].push_back(NullBitTrack);  //Pad out final set of bits
0299           OutputStreamsTracks[iLink].emplace_back(
0300               OutputStreamsTracks[iLink][numLinkTracks++]);  //Pad out with final repeated track
0301         }                                                    //If there is an odd number of tracks
0302         for (int iTrack = 0; iTrack < (int)(SortedPartialTracks[iLink].size()); iTrack++) {
0303           if (iTrack % 2 != 1)  // Write to links every other partial track, 3 partial tracks per full TTTrack
0304             continue;
0305           TTTrackRef TrackRef;
0306           for (auto& it : ttTrackRefMap) {  //Iterate through ttTrackRefMap to find TTTrackRef Key by a TTTrack Value
0307             if (it.second == OutputStreamsTracks[iLink][(int)(iTrack - 1) / 3].first)
0308               TrackRef = it.first;
0309           }
0310           if ((int)iTrack / 3 <= setup_->numFramesIO() * ((double)TTBV::S_ / setup_->tttrackBits()))
0311             accepted[iLink].emplace_back(
0312                 std::make_pair(TrackRef,
0313                                (SortedPartialTracks[iLink][iTrack - 1].slice(partialTrackWordBits_) +
0314                                 SortedPartialTracks[iLink][iTrack].slice(partialTrackWordBits_))
0315                                    .bs()));
0316           else
0317             lost[iLink].emplace_back(
0318                 std::make_pair(TrackRef,
0319                                (SortedPartialTracks[iLink][iTrack - 1].slice(partialTrackWordBits_) +
0320                                 SortedPartialTracks[iLink][iTrack].slice(partialTrackWordBits_))
0321                                    .bs()));
0322         }  //Iterate through sorted partial tracks
0323       }    // Iterate through links
0324     }      // Config Supported
0325     // store products
0326     iEvent.emplace(edPutTokenAccepted_, move(accepted));
0327     iEvent.emplace(edPutTokenLost_, move(lost));
0328   }
0329 }  // namespace trklet
0330 
0331 DEFINE_FWK_MODULE(trklet::ProducerKFout);