GEMEfficiencyAnalyzer

GEMLayer

MatchingMetric

ScenarioOption

StartingStateType

Macros

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
#ifndef DQM_GEM_GEMEfficiencyAnalyzer_h
#define DQM_GEM_GEMEfficiencyAnalyzer_h

/** \class GEMEfficiencyAnalyzer
 *
 * DQM monitoring source for GEM efficiency and resolution
 * based on https://github.com/CPLUOS/MuonPerformance/blob/master/MuonAnalyser/plugins/SliceTestEfficiencyAnalysis.cc
 *
 * TODO muonEta{Min,Max}Cut{GE11,GE21,GE0} depending on a magnetic field for
 *      a cosmic scenario
 * TODO cscForGE21, cscForGE0
 * TODO use "StraightLinePropagator" if B=0 for a cosmic scenario
 *
 * \author Seungjin Yang <seungjin.yang@cern.ch>
 */

#include "DQM/GEM/interface/GEMDQMEfficiencySourceBase.h"
#include "FWCore/Utilities/interface/EDGetToken.h"
#include "FWCore/Framework/interface/ESHandle.h"
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
#include "DataFormats/GEMRecHit/interface/GEMRecHitCollection.h"
#include "DataFormats/PatCandidates/interface/Muon.h"
#include "DataFormats/MuonReco/interface/MuonSelectors.h"
#include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
#include "TrackingTools/TransientTrack/interface/TransientTrack.h"
#include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
#include "TrackingTools/Records/interface/TransientTrackRecord.h"
#include "Geometry/GEMGeometry/interface/GEMGeometry.h"
#include "Geometry/Records/interface/MuonGeometryRecord.h"

class GEMEfficiencyAnalyzer : public GEMDQMEfficiencySourceBase {
public:
  explicit GEMEfficiencyAnalyzer(const edm::ParameterSet &);
  ~GEMEfficiencyAnalyzer() override;
  static void fillDescriptions(edm::ConfigurationDescriptions &);

  // currently only for STA muons
  enum class StartingStateType {
    kOutermostMeasurementState = 0,
    kInnermostMeasurementState,
    kStateOnSurfaceWithCSCSegment,
    kAlignmentStyle,
  };

  // Define the metric as the smaller the absolute value, the better the matching.
  enum class MatchingMetric {
    kDeltaPhi = 0,  // computeDeltaPhi
    kRdPhi,         // computeRdPhi
  };

  // https://github.com/cms-sw/cmssw/blob/CMSSW_12_4_0_pre3/Configuration/Applications/python/ConfigBuilder.py#L35
  enum class ScenarioOption {
    kPP = 0,
    kCosmics,
    kHeavyIons,
  };

  struct GEMLayer {
    GEMLayer(Disk::DiskPointer disk, std::vector<const GEMChamber *> chambers, GEMDetId id)
        : disk(disk), chambers(chambers), id(id) {}
    Disk::DiskPointer disk;
    std::vector<const GEMChamber *> chambers;
    GEMDetId id;
  };

  using StartingState = std::tuple<bool, TrajectoryStateOnSurface, DetId>;

protected:
  void dqmBeginRun(edm::Run const &, edm::EventSetup const &) override;
  void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override;
  void analyze(const edm::Event &event, const edm::EventSetup &eventSetup) override;

private:
  StartingStateType getStartingStateType(const std::string);
  MatchingMetric getMatchingMetric(const std::string);
  reco::Muon::MuonTrackType getMuonTrackType(const std::string);
  ScenarioOption getScenarioOption(const std::string);

  void buildGEMLayers(const GEMGeometry *);

  bool checkPropagationDirection(const reco::Track *, const GEMLayer &);

  StartingState buildStartingState(const reco::Muon &, const reco::TransientTrack &, const GEMLayer &);
  StartingState getInnermostMeasurementState(const reco::TransientTrack &);
  StartingState getOutermostMeasurementState(const reco::TransientTrack &);
  StartingState buildStateOnSurfaceWithCSCSegment(const reco::Muon &, const reco::TransientTrack &, const GEMLayer &);
  StartingState buildStartingStateAlignmentStyle(const reco::Muon &, const reco::TransientTrack &, const GEMLayer &);

  // for kStateOnSurfaceWithCSCSegment and AlignmentStyle
  const CSCSegment *findCSCSegment(const reco::Muon &, const reco::TransientTrack &, const GEMLayer &);
  const CSCSegment *findCSCSegmentBeam(const reco::TransientTrack &, const GEMLayer &);
  const CSCSegment *findCSCSegmentCosmics(const reco::Muon &, const GEMLayer &);
  bool isMuonSubdetAllowed(const DetId &, const int);
  bool isCSCAllowed(const CSCDetId &, const int);

  bool checkBounds(const Plane &, const GlobalPoint &);
  bool checkBounds(const Plane &, const GlobalPoint &, const GlobalError &, float);
  const GEMEtaPartition *findEtaPartition(const GlobalPoint &,
                                          const GlobalError &,
                                          const std::vector<const GEMChamber *> &);

  float computeRdPhi(const GlobalPoint &, const LocalPoint &, const GEMEtaPartition *);
  float computeDeltaPhi(const GlobalPoint &, const LocalPoint &, const GEMEtaPartition *);
  float computeMatchingMetric(const GlobalPoint &, const LocalPoint &, const GEMEtaPartition *);

  std::pair<const GEMRecHit *, float> findClosestHit(const GlobalPoint &,
                                                     const GEMRecHitCollection::range &,
                                                     const GEMEtaPartition *);

  // some helpers
  inline bool isInsideOut(const reco::Track &);

  //////////////////////////////////////////////////////////////////////////////
  // const data members initialized in the member initializer list
  // mainly retrieved from edm::ParameterSet
  //////////////////////////////////////////////////////////////////////////////
  // ES
  const edm::ESGetToken<GEMGeometry, MuonGeometryRecord> kGEMGeometryTokenBeginRun_;
  const edm::ESGetToken<TransientTrackBuilder, TransientTrackRecord> kTransientTrackBuilderToken_;
  // ED
  const edm::EDGetTokenT<GEMRecHitCollection> kGEMRecHitCollectionToken_;
  const edm::EDGetTokenT<edm::View<reco::Muon> > kMuonViewToken_;
  //
  const std::string kMuonTrackTypeName_;
  const reco::Muon::MuonTrackType kMuonTrackType_;
  const TString kMuonName_;
  const std::string kFolder_;
  const ScenarioOption kScenario_;
  // cuts
  const StartingStateType kStartingStateType_;
  const std::vector<std::vector<int> > kMuonSubdetForGEM_;
  const std::vector<std::vector<int> > kCSCForGEM_;  // when using StartingStateType::kStateOnSurfaceWithCSCSegment
  const float kMuonSegmentMatchDRCut_;               // for cosmics

  const std::vector<double> kMuonPtMinCuts_;   // station as index
  const std::vector<double> kMuonEtaMinCuts_;  // station as index
  const std::vector<double> kMuonEtaMaxCuts_;  // station as index
  const float kPropagationErrorRCut_;          // cm
  const float kPropagationErrorPhiCut_;        // degree
  const float kBoundsErrorScale_;              // TODO doc
  // matching
  const MatchingMetric kMatchingMetric_;
  const float kMatchingCut_;
  // for MinotorElement
  const std::vector<double> kMuonPtBins_;  // station as index
  const std::vector<int> kMuonEtaNbins_;   // station as index
  const std::vector<double> kMuonEtaLow_;  // station as index
  const std::vector<double> kMuonEtaUp_;   // station as index

  // const
  const bool kModeDev_;

  //////////////////////////////////////////////////////////////////////////////
  // const data members
  // FIXME static?
  //////////////////////////////////////////////////////////////////////////////
  // https://github.com/cms-sw/cmssw/blob/CMSSW_12_4_0_pre3/DataFormats/CSCRecHit/interface/CSCSegment.h#L60
  const int kCSCSegmentDimension_ = 4;

  //////////////////////////////////////////////////////////////////////////////
  // non-const data members
  //////////////////////////////////////////////////////////////////////////////
  std::unique_ptr<MuonServiceProxy> muon_service_;
  std::vector<GEMLayer> gem_layers_;

  // montitor elements
  // XXX how about introducing EffPair ?
  MEMap me_chamber_ieta_, me_chamber_ieta_matched_;
  MEMap me_muon_pt_, me_muon_pt_matched_;
  MEMap me_muon_eta_, me_muon_eta_matched_;
  MEMap me_muon_phi_, me_muon_phi_matched_;
  MEMap me_residual_phi_;  // in global
  // dev mode
  MEMap me_matching_metric_all_;
  MEMap me_matching_metric_;
  MEMap me_residual_phi_muon_;      // in global
  MEMap me_residual_phi_antimuon_;  // in global
  MEMap me_residual_x_;             // in local
  MEMap me_residual_y_;             // in global
  MEMap me_residual_strip_;
  MEMap me_prop_path_length_, me_prop_path_length_matched_;
  MEMap me_prop_err_r_, me_prop_err_r_matched_;
  MEMap me_prop_err_phi_, me_prop_err_phi_matched_;
  MEMap me_muon_pt_all_, me_muon_pt_all_matched_;
  MEMap me_muon_eta_all_, me_muon_eta_all_matched_;
  MEMap me_muon_charge_, me_muon_charge_matched_;
  MEMap me_cutflow_, me_cutflow_matched_;
};

#endif  // DQM_GEM_GEMEfficiencyAnalyzer_h