Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:24:56

0001 #ifndef RecoLocalMuon_GEMSegment_GE0SegAlgoRU_h
0002 #define RecoLocalMuon_GEMSegment_GE0SegAlgoRU_h
0003 
0004 /**
0005  * \class GE0SegAlgoRU
0006  * adapted from CSC to ME0 bt Marcello Maggi
0007  *  and ME0 to GE0 by Ian J. Watson
0008  *
0009  * This is the original algorithm for building endcap muon track segments
0010  * out of the rechit's in a GE0Chamber
0011  * 'RU' = 'RUssia' = Road Usage
0012  *
0013  * A GEMSegment is a RecSegment4D, and is built from
0014  * GEMRecHit2D objects, each of which is a RecHit2DLocalPos. <BR>
0015  *
0016  * This class is used by the GEMSegmentAlgorithm. <BR>
0017  * Alternative algorithms can be used for the segment building
0018  * by writing classes like this, and then selecting which one is actually
0019  * used via the GEMSegmentBuilder. <BR>
0020  *
0021  * developed and implemented by Vladimir Palichik <Vladimir.Paltchik@cern.ch>
0022  *                          and Nikolay Voytishin <nikolay.voytishin@cern.ch>
0023  */
0024 
0025 #include <RecoLocalMuon/GEMSegment/plugins/GEMSegmentAlgorithmBase.h>
0026 #include <DataFormats/GEMRecHit/interface/GEMRecHit.h>
0027 #include "MuonSegFit.h"
0028 
0029 #include <vector>
0030 
0031 class MuonSegFit;
0032 class GE0SegAlgoRU : public GEMSegmentAlgorithmBase {
0033 public:
0034   struct SegmentParameters {
0035     float maxETASeeds;
0036     float maxPhiSeeds;
0037     float maxPhiAdditional;
0038     float maxChi2Additional;
0039     float maxChi2Prune;
0040     float maxChi2GoodSeg;
0041     bool requireCentralBX;
0042     unsigned int minNumberOfHits;
0043     unsigned int maxNumberOfHits;
0044     unsigned int maxNumberOfHitsPerLayer;
0045     bool requireBeamConstr;
0046   };
0047 
0048   // originally from ME0SegmentAlgorithmBase
0049   struct HitAndPosition {
0050     HitAndPosition(const GEMRecHit* rh, const LocalPoint& lp, const GlobalPoint& gp, unsigned int idx)
0051         : rh(rh), lp(lp), gp(gp), layer(rh->gemId().layer()), idx(idx) {}
0052     const GEMRecHit* rh;
0053     LocalPoint lp;
0054     GlobalPoint gp;
0055     unsigned int layer;
0056     unsigned int idx;
0057   };
0058   typedef std::vector<HitAndPosition> HitAndPositionContainer;
0059   typedef std::vector<const HitAndPosition*> HitAndPositionPtrContainer;
0060 
0061   // We need to be able to flag a hit as 'used' and so need a container of bool's.
0062   typedef std::vector<bool> BoolContainer;
0063   typedef std::vector<std::pair<float, HitAndPositionPtrContainer> > SegmentByMetricContainer;
0064 
0065   /// Constructor
0066   explicit GE0SegAlgoRU(const edm::ParameterSet& ps);
0067   /// Destructor
0068   ~GE0SegAlgoRU() override{};
0069 
0070   /**
0071    * Here we must implement the algorithm
0072    */
0073   std::vector<GEMSegment> run(const GEMSuperChamber* chamber, const HitAndPositionContainer& rechits);
0074   // The original ME0SegAlgoRU used the run(..) function above, we
0075   // implement a small wrapper to use with GEMSegments fairly
0076   // transparently
0077   std::vector<GEMSegment> run(const GEMEnsemble& ensemble, const std::vector<const GEMRecHit*>& rechits) override;
0078 
0079 private:
0080   //Look for segments that have at least "n_seg_min" consituents and following the associated paramters
0081   void lookForSegments(const SegmentParameters& params,
0082                        const unsigned int n_seg_min,
0083                        const HitAndPositionContainer& rechits,
0084                        const std::vector<unsigned int>& recHits_per_layer,
0085                        BoolContainer& used,
0086                        std::vector<GEMSegment>& segments) const;
0087   //Look for any hits between the two seed hits consistent with a segment
0088   void tryAddingHitsToSegment(const float maxETA,
0089                               const float maxPhi,
0090                               const float maxChi2,
0091                               std::unique_ptr<MuonSegFit>& current_fit,
0092                               HitAndPositionPtrContainer& proto_segment,
0093                               const BoolContainer& used,
0094                               HitAndPositionContainer::const_iterator i1,
0095                               HitAndPositionContainer::const_iterator i2) const;
0096   //Remove extra hits until the segment passes "maxChi2"
0097   void pruneBadHits(const float maxChi2,
0098                     HitAndPositionPtrContainer& proto_segment,
0099                     std::unique_ptr<MuonSegFit>& fit,
0100                     const unsigned int n_seg_min) const;
0101   //Remove any overlapping segments by which has the lowset chi2
0102   void addUniqueSegments(SegmentByMetricContainer& proto_segments,
0103                          std::vector<GEMSegment>& segments,
0104                          BoolContainer& used) const;
0105 
0106   //Are the two seed hits consistent spatially?
0107   bool areHitsCloseInEta(const float maxETA, const bool beamConst, const GlobalPoint& h1, const GlobalPoint& h2) const;
0108   bool areHitsCloseInGlobalPhi(const float maxPHI,
0109                                const unsigned int nLayDisp,
0110                                const GlobalPoint& h1,
0111                                const GlobalPoint& h2) const;
0112 
0113   //Add a hit to a segment
0114   std::unique_ptr<MuonSegFit> addHit(HitAndPositionPtrContainer& proto_segment, const HitAndPosition& aHit) const;
0115   //Does the segment have any hits on this layer?
0116   bool hasHitOnLayer(const HitAndPositionPtrContainer& proto_segment, const unsigned int layer) const;
0117   //Produce a new fit
0118   std::unique_ptr<MuonSegFit> makeFit(const HitAndPositionPtrContainer& proto_segment) const;
0119 
0120   //Is this new hit btw the seeds near the segment fit?
0121   bool isHitNearSegment(const float maxETA,
0122                         const float maxPHI,
0123                         const std::unique_ptr<MuonSegFit>& fit,
0124                         const HitAndPositionPtrContainer& proto_segment,
0125                         const HitAndPosition& h) const;
0126   //Return a chi2 for a hit and a predicted segment extrapolation
0127   float getHitSegChi2(const std::unique_ptr<MuonSegFit>& fit, const GEMRecHit& hit) const;
0128   //Global point of a segment extrapolated to a Z value
0129   GlobalPoint globalAtZ(const std::unique_ptr<MuonSegFit>& fit, float z) const;
0130 
0131   //Try adding a hit instead of another and return new or old, depending on which has the smallest chi2
0132   void compareProtoSegment(std::unique_ptr<MuonSegFit>& current_fit,
0133                            HitAndPositionPtrContainer& current_proto_segment,
0134                            const HitAndPosition& new_hit) const;
0135   //Try adding this hit to the segment, dont if the new chi2 is too big
0136   void increaseProtoSegment(const float maxChi2,
0137                             std::unique_ptr<MuonSegFit>& current_fit,
0138                             HitAndPositionPtrContainer& current_proto_segment,
0139                             const HitAndPosition& new_hit) const;
0140 
0141   const std::string myName;
0142   bool doCollisions;
0143   bool allowWideSegments;
0144 
0145   SegmentParameters stdParameters;
0146   SegmentParameters displacedParameters;
0147   SegmentParameters wideParameters;
0148 
0149   //Objects used to produce the segments
0150   const GEMSuperChamber* theChamber;
0151 };
0152 
0153 #endif