Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:27:39

0001 /****************************************************************************
0002 *
0003 * This is a part of TOTEM offline software.
0004 * Authors:
0005 *   Hubert Niewiadomski
0006 *   Jan Kašpar (jan.kaspar@gmail.com)
0007 *
0008 ****************************************************************************/
0009 
0010 #include "FWCore/Framework/interface/MakerMacros.h"
0011 
0012 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0013 #include "FWCore/Framework/interface/stream/EDProducer.h"
0014 #include "FWCore/Framework/interface/Event.h"
0015 #include "FWCore/Framework/interface/EventSetup.h"
0016 #include "FWCore/Framework/interface/ESHandle.h"
0017 #include "FWCore/Framework/interface/ESWatcher.h"
0018 #include "FWCore/Utilities/interface/ESGetToken.h"
0019 
0020 #include "DataFormats/Common/interface/DetSetVector.h"
0021 #include "DataFormats/CTPPSReco/interface/TotemRPRecHit.h"
0022 #include "DataFormats/CTPPSReco/interface/TotemRPUVPattern.h"
0023 #include "DataFormats/CTPPSReco/interface/TotemRPLocalTrack.h"
0024 
0025 #include "Geometry/Records/interface/VeryForwardRealGeometryRecord.h"
0026 #include "Geometry/VeryForwardGeometryBuilder/interface/CTPPSGeometry.h"
0027 
0028 #include "RecoPPS/Local/interface/TotemRPLocalTrackFitterAlgorithm.h"
0029 
0030 //----------------------------------------------------------------------------------------------------
0031 
0032 /**
0033  *\brief Fits tracks trough a single RP.
0034  **/
0035 class TotemRPLocalTrackFitter : public edm::stream::EDProducer<> {
0036 public:
0037   explicit TotemRPLocalTrackFitter(const edm::ParameterSet &conf);
0038 
0039   ~TotemRPLocalTrackFitter() override {}
0040 
0041   void produce(edm::Event &e, const edm::EventSetup &c) override;
0042   static void fillDescriptions(edm::ConfigurationDescriptions &);
0043 
0044 private:
0045   int verbosity_;
0046 
0047   /// Selection of the pattern-recognition module.
0048   edm::InputTag tagUVPattern;
0049 
0050   edm::EDGetTokenT<edm::DetSetVector<TotemRPUVPattern>> patternCollectionToken;
0051   edm::ESGetToken<CTPPSGeometry, VeryForwardRealGeometryRecord> geometryToken;
0052 
0053   /// A watcher to detect geometry changes.
0054   edm::ESWatcher<VeryForwardRealGeometryRecord> geometryWatcher;
0055 
0056   /// The instance of the fitter module
0057   TotemRPLocalTrackFitterAlgorithm fitter_;
0058 };
0059 
0060 //----------------------------------------------------------------------------------------------------
0061 //----------------------------------------------------------------------------------------------------
0062 
0063 using namespace std;
0064 using namespace edm;
0065 
0066 //----------------------------------------------------------------------------------------------------
0067 
0068 TotemRPLocalTrackFitter::TotemRPLocalTrackFitter(const edm::ParameterSet &conf)
0069     : verbosity_(conf.getParameter<int>("verbosity")), fitter_(conf) {
0070   tagUVPattern = conf.getParameter<edm::InputTag>("tagUVPattern");
0071   patternCollectionToken = consumes<DetSetVector<TotemRPUVPattern>>(tagUVPattern);
0072   geometryToken = esConsumes<CTPPSGeometry, VeryForwardRealGeometryRecord>();
0073 
0074   produces<DetSetVector<TotemRPLocalTrack>>();
0075 }
0076 
0077 //----------------------------------------------------------------------------------------------------
0078 
0079 void TotemRPLocalTrackFitter::produce(edm::Event &e, const edm::EventSetup &setup) {
0080   if (verbosity_ > 5)
0081     LogVerbatim("TotemRPLocalTrackFitter") << ">> TotemRPLocalTrackFitter::produce";
0082 
0083   // get geometry
0084   edm::ESHandle<CTPPSGeometry> geometry = setup.getHandle(geometryToken);
0085 
0086   if (geometryWatcher.check(setup))
0087     fitter_.reset();
0088 
0089   // get input
0090   edm::Handle<DetSetVector<TotemRPUVPattern>> input;
0091   e.getByToken(patternCollectionToken, input);
0092 
0093   // run fit for each RP
0094   DetSetVector<TotemRPLocalTrack> output;
0095 
0096   for (const auto &rpv : *input) {
0097     CTPPSDetId rpId(rpv.detId());
0098 
0099     // is U-V association unique?
0100     unsigned int n_U = 0, n_V = 0;
0101     unsigned int idx_U = 0, idx_V = 0;
0102     for (unsigned int pi = 0; pi < rpv.size(); pi++) {
0103       const TotemRPUVPattern &pattern = rpv[pi];
0104 
0105       // here it would make sense to skip non-fittable patterns, but to keep the logic
0106       // equivalent to version 7_0_4, nothing is skipped
0107       /*
0108       if (pattern.fittable() == false)
0109         continue;
0110       */
0111 
0112       switch (pattern.projection()) {
0113         case TotemRPUVPattern::projU:
0114           n_U++;
0115           idx_U = pi;
0116           break;
0117 
0118         case TotemRPUVPattern::projV:
0119           n_V++;
0120           idx_V = pi;
0121           break;
0122 
0123         default:
0124           break;
0125       }
0126     }
0127 
0128     if (n_U != 1 || n_V != 1) {
0129       if (verbosity_)
0130         LogVerbatim("TotemRPLocalTrackFitter")
0131             << ">> TotemRPLocalTrackFitter::produce > Impossible to combine U and V patterns in RP " << rpId
0132             << " (n_U=" << n_U << ", n_V=" << n_V << ").";
0133 
0134       continue;
0135     }
0136 
0137     // again, to follow the logic from version 7_0_4, skip the non-fittable patterns here
0138     if (!rpv[idx_U].fittable() || !rpv[idx_V].fittable())
0139       continue;
0140 
0141     // combine U and V hits
0142     DetSetVector<TotemRPRecHit> hits;
0143     for (auto &ids : rpv[idx_U].hits()) {
0144       auto &ods = hits.find_or_insert(ids.detId());
0145       for (auto &h : ids)
0146         ods.push_back(h);
0147     }
0148 
0149     for (auto &ids : rpv[idx_V].hits()) {
0150       auto &ods = hits.find_or_insert(ids.detId());
0151       for (auto &h : ids)
0152         ods.push_back(h);
0153     }
0154 
0155     // run fit
0156     double z0 = geometry->rpTranslation(rpId).z();
0157 
0158     TotemRPLocalTrack track;
0159     fitter_.fitTrack(hits, z0, *geometry, track);
0160 
0161     DetSet<TotemRPLocalTrack> &ds = output.find_or_insert(rpId);
0162     ds.push_back(track);
0163 
0164     if (verbosity_ > 5) {
0165       unsigned int n_hits = 0;
0166       for (auto &hds : track.hits())
0167         n_hits += hds.size();
0168 
0169       LogVerbatim("TotemRPLocalTrackFitter")
0170           << "    track in RP " << rpId << ": valid = " << track.isValid() << ", hits = " << n_hits;
0171     }
0172   }
0173 
0174   // save results
0175   e.put(make_unique<DetSetVector<TotemRPLocalTrack>>(output));
0176 }
0177 
0178 //----------------------------------------------------------------------------------------------------
0179 
0180 void TotemRPLocalTrackFitter::fillDescriptions(edm::ConfigurationDescriptions &descr) {
0181   edm::ParameterSetDescription desc;
0182 
0183   desc.add<edm::InputTag>("tagUVPattern", edm::InputTag("totemRPUVPatternFinder"))
0184       ->setComment("input U-V patterns collection to retrieve");
0185   desc.add<int>("verbosity", 0);
0186 
0187   descr.add("totemRPLocalTrackFitter", desc);
0188 }
0189 
0190 //----------------------------------------------------------------------------------------------------
0191 
0192 DEFINE_FWK_MODULE(TotemRPLocalTrackFitter);