Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:26:00

0001 #ifndef CSCSegment_CSCSegAlgoDF_h
0002 #define CSCSegment_CSCSegAlgoDF_h
0003 
0004 /**
0005  * \class CSCSegAlgoDF
0006  *
0007  * This is a modified version of the SK algorithm for building endcap 
0008  * muon track segments out of the rechit's in a CSCChamber.<BR>
0009  *
0010  * A CSCSegment is a RecSegment4D, and is built from
0011  * CSCRecHit2D objects, each of which is a RecHit2DLocalPos. <BR>
0012  *
0013  * This builds segments by first creating proto-segments from at least 3 hits.   
0014  * We intend to try all possible pairs of hits to start segment building. 'All possible'
0015  * means each hit lies on different layers in the chamber.  Once a hit has been assigned
0016  * to a segment, we don't consider it again, THAT IS, FOR THE FIRST PASS ONLY !
0017  * In fact, this is one of the possible flaw with the SK algorithms as it sometimes manages
0018  * to build segments with the wrong starting points.  In the DF algorithm, the endpoints
0019  * are tested as the best starting points in a 2nd and 3rd loop.<BR>
0020  *
0021  * Another difference with the from the SK algorithm is that rechits can be added to proto
0022  * segments if they fall within n sigmas of the projected track within a given layer.
0023  * Hence, a cylinder isn't used as in the SK algorimthm, which allows for pseudo 2D hits
0024  * built from wire or strip only hits to be used in segment reconstruction.<BR>
0025  *
0026  * Also, only a certain muonsPerChamberMax maximum number of segments can be produced in the 
0027  * chamber. [Seems to be hardwired rather than using this variable?] <BR>
0028  *
0029  * Alternative algorithms can be used for the segment building
0030  * by writing classes like this, and then selecting which one is actually
0031  * used via the CSCSegmentBuilder. <BR>
0032  *
0033  *
0034  *  \author Dominique Fortin - UCR
0035  *
0036  */
0037 
0038 #include <RecoLocalMuon/CSCSegment/src/CSCSegmentAlgorithm.h>
0039 #include <DataFormats/CSCRecHit/interface/CSCRecHit2D.h>
0040 
0041 #include <deque>
0042 #include <vector>
0043 
0044 class CSCSegAlgoPreClustering;
0045 class CSCSegAlgoShowering;
0046 class CSCSegFit;
0047 
0048 class CSCSegAlgoDF : public CSCSegmentAlgorithm {
0049 public:
0050   /// Typedefs
0051 
0052   typedef std::vector<int> LayerIndex;
0053   typedef std::vector<const CSCRecHit2D*> ChamberHitContainer;
0054   typedef std::vector<const CSCRecHit2D*>::const_iterator ChamberHitContainerCIt;
0055   typedef std::deque<bool> BoolContainer;
0056 
0057   /// Constructor
0058   explicit CSCSegAlgoDF(const edm::ParameterSet& ps);
0059 
0060   /// Destructor
0061   ~CSCSegAlgoDF() override;
0062 
0063   /**
0064    * Build track segments in this chamber (this is where the actual
0065    * segment-building algorithm hides.)
0066    */
0067   std::vector<CSCSegment> buildSegments(const ChamberHitContainer& rechits);
0068 
0069   /**
0070    * Here we must implement the algorithm
0071    */
0072   std::vector<CSCSegment> run(const CSCChamber* aChamber, const ChamberHitContainer& rechits) override;
0073 
0074 private:
0075   /// Utility functions
0076 
0077   /**
0078    * Try adding non-used hits to segment<BR>
0079    * Skip the layers containing the segment endpoints on first 2 passes, but then       <BR>
0080    * try hits on layer containing the segment starting points on 2nd and/or 3rd pass    <BR>
0081    * if segment has >2 hits.  Test each hit on the other layers to see if it is near    <BR>
0082    * the segment using rechit error matrix.                                             <BR>
0083    * If it is, see whether there is already a hit on the segment from the same layer    <BR>
0084    *    - if so, and there are more than 2 hits on the segment, copy the segment,       <BR>
0085    *      replace the old hit with the new hit. If the new segment chi2 is better       <BR>
0086    *      then replace the original segment with the new one                            <BR>
0087    *    - if not, copy the segment, add the hit if it's within a certain range.         <BR>
0088    */
0089   void tryAddingHitsToSegment(const ChamberHitContainer& rechitsInChamber,
0090                               const ChamberHitContainerCIt i1,
0091                               const ChamberHitContainerCIt i2,
0092                               const LayerIndex& layerIndex);
0093 
0094   /**
0095    * Flag hits on segment as used
0096    */
0097   void flagHitsAsUsed(const ChamberHitContainer& rechitsInChamber);
0098 
0099   /** 
0100    * Prune bad segment from the worse hit based on residuals
0101    */
0102   void pruneFromResidual(void);
0103 
0104   bool isHitNearSegment(const CSCRecHit2D* h) const;
0105   bool addHit(const CSCRecHit2D* hit, int layer);
0106   void updateParameters(void);
0107   bool hasHitOnLayer(int layer) const;
0108   void compareProtoSegment(const CSCRecHit2D* h, int layer);
0109   void dumpSegment(const CSCSegment& seg) const;
0110 
0111   // Member variables
0112   const std::string myName;
0113   const CSCChamber* theChamber;
0114   BoolContainer usedHits;
0115 
0116   ChamberHitContainer closeHits;
0117 
0118   ChamberHitContainer protoSegment;
0119   ChamberHitContainer secondSeedHits;
0120 
0121   // input from .cfi file
0122   bool debug;
0123   bool preClustering;
0124   int minHitsForPreClustering;
0125   //  bool   testSeg;
0126   bool Pruning;
0127   int minLayersApart;
0128   int nHitsPerClusterIsShower;
0129   //  float  nSigmaFromSegment;
0130   int minHitsPerSegment;
0131   //  int    muonsPerChamberMax;
0132   double dRPhiFineMax;
0133   double dPhiFineMax;
0134   float tanPhiMax;
0135   float tanThetaMax;
0136   float chi2Max;
0137   float maxRatioResidual;
0138 
0139   CSCSegAlgoPreClustering* preCluster_;
0140   CSCSegAlgoShowering* showering_;
0141   CSCSegFit* sfit_;
0142 };
0143 
0144 #endif