CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
List of all members | Public Types | Public Member Functions | Private Member Functions | Private Attributes
CSCSegAlgoST Class Reference

#include <CSCSegAlgoST.h>

Inheritance diagram for CSCSegAlgoST:
CSCSegmentAlgorithm

Public Types

typedef std::deque< bool > BoolContainer
 
typedef std::vector< const
CSCRecHit2D * > 
ChamberHitContainer
 Typedefs. More...
 
typedef std::vector
< std::vector< const
CSCRecHit2D * > > 
Segments
 
typedef ROOT::Math::SMatrix
< double, 12, 4 > 
SMatrix12by4
 
typedef ROOT::Math::SMatrix
< double, 4 > 
SMatrix4
 
typedef ROOT::Math::SMatrix
< double,
12, 12, ROOT::Math::MatRepSym
< double, 12 > > 
SMatrixSym12
 
typedef ROOT::Math::SMatrix
< double,
2, 2, ROOT::Math::MatRepSym
< double, 2 > > 
SMatrixSym2
 
typedef ROOT::Math::SMatrix
< double,
4, 4, ROOT::Math::MatRepSym
< double, 4 > > 
SMatrixSym4
 
typedef ROOT::Math::SVector
< double, 4 > 
SVector4
 

Public Member Functions

std::vector< CSCSegmentbuildSegments (const ChamberHitContainer &rechits)
 
std::vector< CSCSegmentbuildSegments2 (const ChamberHitContainer &rechits)
 
std::vector< std::vector
< const CSCRecHit2D * > > 
chainHits (const CSCChamber *aChamber, const ChamberHitContainer &rechits)
 
std::vector< std::vector
< const CSCRecHit2D * > > 
clusterHits (const CSCChamber *aChamber, const ChamberHitContainer &rechits)
 
 CSCSegAlgoST (const edm::ParameterSet &ps)
 Constructor. More...
 
std::vector< CSCSegmentprune_bad_hits (const CSCChamber *aChamber, std::vector< CSCSegment > &segments)
 
std::vector< CSCSegmentrun (const CSCChamber *aChamber, const ChamberHitContainer &rechits)
 
virtual ~CSCSegAlgoST ()
 Destructor. More...
 
- Public Member Functions inherited from CSCSegmentAlgorithm
 CSCSegmentAlgorithm (const edm::ParameterSet &)
 Constructor. More...
 
virtual std::vector< CSCSegmentrun (const CSCChamber *chamber, const std::vector< const CSCRecHit2D * > &rechits)=0
 
virtual ~CSCSegmentAlgorithm ()
 Destructor. More...
 

Private Member Functions

SMatrixSym4 calculateError (void) const
 
const CSCChamberchamber () const
 
void ChooseSegments (void)
 
void ChooseSegments2 (int best_seg)
 
void ChooseSegments2a (std::vector< ChamberHitContainer > &best_segments, int best_seg)
 
void ChooseSegments3 (int best_seg)
 
void ChooseSegments3 (std::vector< ChamberHitContainer > &best_segments, std::vector< float > &best_weight, int best_seg)
 
void correctTheCovMatrix (SMatrixSym2 &IC)
 
void correctTheCovX (void)
 
SMatrix12by4 derivativeMatrix (void) const
 
void doSlopesAndChi2 (void)
 
void dumpSegment (const CSCSegment &seg) const
 
void fillChiSquared (void)
 
void fillLocalDirection (void)
 
void findDuplicates (std::vector< CSCSegment > &segments)
 
void fitSlopes (void)
 
AlgebraicSymMatrix flipErrors (const SMatrixSym4 &) const
 
bool isGoodToMerge (bool isME11a, ChamberHitContainer &newChain, ChamberHitContainer &oldChain)
 
double theWeight (double coordinate_1, double coordinate_2, double coordinate_3, float layer_1, float layer_2, float layer_3)
 Utility functions. More...
 
SMatrixSym12 weightMatrix (void) const
 

Private Attributes

float a_yweightPenaltyThreshold [5][5]
 
double BPMinImprovement
 
bool BrutePruning
 
double chi2Norm_2D_
 
double chi2Norm_3D_
 Chi^2 normalization for the corrected fit. More...
 
std::vector< ChamberHitContainerchosen_Psegments
 
std::vector< float > chosen_weight_A
 
double condSeed1_
 The upper limit of protoChiUCorrection to apply prePrun. More...
 
double condSeed2_
 
bool correctCov_
 Correct the Error Matrix. More...
 
double covAnyNumber_
 Allow to use any number for covariance for all RecHits. More...
 
bool covToAnyNumber_
 The correction parameters. More...
 
bool covToAnyNumberAll_
 Allow to use any number for covariance (by hand) More...
 
std::vector< float > curv_A
 
std::vector< float > curv_noL1_A
 
std::vector< float > curv_noL2_A
 
std::vector< float > curv_noL3_A
 
std::vector< float > curv_noL4_A
 
std::vector< float > curv_noL5_A
 
std::vector< float > curv_noL6_A
 
double curvePenalty
 
double curvePenaltyThreshold
 
bool debug
 
double dXclusBoxMax
 
double dYclusBoxMax
 
std::vector< double > e_Cxx
 
Segments GoodSegments
 
double hitDropLimit4Hits
 
double hitDropLimit5Hits
 
double hitDropLimit6Hits
 
unsigned maxContrIndex
 Chi^2 normalization for the initial fit. More...
 
int maxRecHitsInCluster
 
int minHitsPerSegment
 
const std::string myName
 
bool onlyBestSegment
 
ChamberHitContainer PAhits_onLayer [6]
 
bool passCondNumber
 The number to force the Covariance. More...
 
bool passCondNumber_2
 Passage the condition number calculations. More...
 
bool preClustering
 
bool preClustering_useChaining
 
bool prePrun_
 The index of the worst x RecHit in Chi^2-X method. More...
 
double prePrunLimit_
 
double protoChi2
 
double protoChiUCorrection
 Allow to correct the error matrix. More...
 
LocalVector protoDirection
 
LocalPoint protoIntercept
 
double protoNDF
 
ChamberHitContainer protoSegment
 
float protoSlope_u
 
float protoSlope_v
 
bool Pruning
 
std::vector< ChamberHitContainerPsegments
 
ChamberHitContainer Psegments_hits
 
std::vector< ChamberHitContainerPsegments_noL1
 
std::vector< ChamberHitContainerPsegments_noL2
 
std::vector< ChamberHitContainerPsegments_noL3
 
std::vector< ChamberHitContainerPsegments_noL4
 
std::vector< ChamberHitContainerPsegments_noL5
 
std::vector< ChamberHitContainerPsegments_noL6
 
std::vector< ChamberHitContainerPsegments_noLx
 
CSCSegAlgoShoweringshowering_
 
const CSCChambertheChamber
 
bool useShowering
 
std::vector< float > weight_A
 
std::vector< float > weight_B
 
std::vector< float > weight_noL1_A
 
std::vector< float > weight_noL1_B
 
std::vector< float > weight_noL2_A
 
std::vector< float > weight_noL2_B
 
std::vector< float > weight_noL3_A
 
std::vector< float > weight_noL3_B
 
std::vector< float > weight_noL4_A
 
std::vector< float > weight_noL4_B
 
std::vector< float > weight_noL5_A
 
std::vector< float > weight_noL5_B
 
std::vector< float > weight_noL6_A
 
std::vector< float > weight_noL6_B
 
std::vector< float > weight_noLx_A
 
double yweightPenalty
 
double yweightPenaltyThreshold
 

Detailed Description

This algorithm is based on the Minimum Spanning Tree (ST) approach for building endcap muon track segments out of the rechit's in a CSCChamber.

A CSCSegment is a RecSegment4D, and is built from CSCRecHit2D objects, each of which is a RecHit2DLocalPos.

This builds segments consisting of at least 3 hits. It is allowed for segments to have a common (only one) rechit.

The program is under construction/testing, as it has been for many years?! As of Aug-2014 replace CLHEP matrices by ROOT::SMatrix in a minimal way.

Authors
S. Stoynev - NWU I. Bloch - FNAL E. James - FNAL A. Sakharov - WSU (extensive revision to handle weird segments) T. Cox - UC Davis (struggling to handle this monster)

Definition at line 38 of file CSCSegAlgoST.h.

Member Typedef Documentation

typedef std::deque<bool> CSCSegAlgoST::BoolContainer

Definition at line 47 of file CSCSegAlgoST.h.

typedef std::vector<const CSCRecHit2D*> CSCSegAlgoST::ChamberHitContainer

Typedefs.

Definition at line 45 of file CSCSegAlgoST.h.

typedef std::vector< std::vector<const CSCRecHit2D* > > CSCSegAlgoST::Segments

Definition at line 46 of file CSCSegAlgoST.h.

typedef ROOT::Math::SMatrix<double,12,4 > CSCSegAlgoST::SMatrix12by4

Definition at line 53 of file CSCSegAlgoST.h.

typedef ROOT::Math::SMatrix<double, 4 > CSCSegAlgoST::SMatrix4

Definition at line 56 of file CSCSegAlgoST.h.

typedef ROOT::Math::SMatrix<double,12,12,ROOT::Math::MatRepSym<double,12> > CSCSegAlgoST::SMatrixSym12

Definition at line 50 of file CSCSegAlgoST.h.

typedef ROOT::Math::SMatrix<double,2,2,ROOT::Math::MatRepSym<double,2> > CSCSegAlgoST::SMatrixSym2

Definition at line 60 of file CSCSegAlgoST.h.

typedef ROOT::Math::SMatrix<double,4,4,ROOT::Math::MatRepSym<double,4> > CSCSegAlgoST::SMatrixSym4

Definition at line 57 of file CSCSegAlgoST.h.

typedef ROOT::Math::SVector<double,4> CSCSegAlgoST::SVector4

Definition at line 63 of file CSCSegAlgoST.h.

Constructor & Destructor Documentation

CSCSegAlgoST::CSCSegAlgoST ( const edm::ParameterSet ps)
explicit

Constructor.

Correct the Error Matrix

Definition at line 31 of file CSCSegAlgoST.cc.

References BPMinImprovement, BrutePruning, chi2Norm_2D_, chi2Norm_3D_, condSeed1_, condSeed2_, correctCov_, covAnyNumber_, covToAnyNumber_, covToAnyNumberAll_, curvePenalty, curvePenaltyThreshold, debug, dXclusBoxMax, dYclusBoxMax, edm::ParameterSet::getParameter(), edm::ParameterSet::getUntrackedParameter(), hitDropLimit4Hits, hitDropLimit5Hits, hitDropLimit6Hits, maxContrIndex, maxRecHitsInCluster, minHitsPerSegment, onlyBestSegment, passCondNumber, passCondNumber_2, preClustering, preClustering_useChaining, prePrun_, prePrunLimit_, protoChiUCorrection, protoNDF, Pruning, showering_, useShowering, yweightPenalty, and yweightPenaltyThreshold.

31  :
32  CSCSegmentAlgorithm(ps), myName("CSCSegAlgoST"), showering_(0) {
33 
34  debug = ps.getUntrackedParameter<bool>("CSCDebug");
35  // minLayersApart = ps.getParameter<int>("minLayersApart");
36  // nSigmaFromSegment = ps.getParameter<double>("nSigmaFromSegment");
37  minHitsPerSegment = ps.getParameter<int>("minHitsPerSegment");
38  // muonsPerChamberMax = ps.getParameter<int>("CSCSegmentPerChamberMax");
39  // chi2Max = ps.getParameter<double>("chi2Max");
40  dXclusBoxMax = ps.getParameter<double>("dXclusBoxMax");
41  dYclusBoxMax = ps.getParameter<double>("dYclusBoxMax");
42  preClustering = ps.getParameter<bool>("preClustering");
43  preClustering_useChaining = ps.getParameter<bool>("preClusteringUseChaining");
44  Pruning = ps.getParameter<bool>("Pruning");
45  BrutePruning = ps.getParameter<bool>("BrutePruning");
46  BPMinImprovement = ps.getParameter<double>("BPMinImprovement");
47  // maxRecHitsInCluster is the maximal number of hits in a precluster that is being processed
48  // This cut is intended to remove messy events. Currently nothing is returned if there are
49  // more that maxRecHitsInCluster hits. It could be useful to return an estimate of the
50  // cluster position, which is available.
51  maxRecHitsInCluster = ps.getParameter<int>("maxRecHitsInCluster");
52  onlyBestSegment = ps.getParameter<bool>("onlyBestSegment");
53 
54  hitDropLimit4Hits = ps.getParameter<double>("hitDropLimit4Hits");
55  hitDropLimit5Hits = ps.getParameter<double>("hitDropLimit5Hits");
56  hitDropLimit6Hits = ps.getParameter<double>("hitDropLimit6Hits");
57 
58  yweightPenaltyThreshold = ps.getParameter<double>("yweightPenaltyThreshold");
59  yweightPenalty = ps.getParameter<double>("yweightPenalty");
60 
61  curvePenaltyThreshold = ps.getParameter<double>("curvePenaltyThreshold");
62  curvePenalty = ps.getParameter<double>("curvePenalty");
63 
64  useShowering = ps.getParameter<bool>("useShowering");
65  if (useShowering) showering_ = new CSCSegAlgoShowering( ps );
66 
68  correctCov_ = ps.getParameter<bool>("CorrectTheErrors");
69  chi2Norm_2D_ = ps.getParameter<double>("NormChi2Cut2D");
70  chi2Norm_3D_ = ps.getParameter<double>("NormChi2Cut3D");
71  prePrun_ = ps.getParameter<bool>("prePrun");
72  prePrunLimit_ = ps.getParameter<double>("prePrunLimit");
73 
74  condSeed1_ = ps.getParameter<double>("SeedSmall");
75  condSeed2_ = ps.getParameter<double>("SeedBig");
76  covToAnyNumber_ = ps.getParameter<bool>("ForceCovariance");
77  covToAnyNumberAll_ = ps.getParameter<bool>("ForceCovarianceAll");
78  covAnyNumber_ = ps.getParameter<double>("Covariance");
79  passCondNumber=false;
80  passCondNumber_2=false;
82  maxContrIndex=0;
83  protoNDF = 1.;
84 
85 }
double yweightPenaltyThreshold
Definition: CSCSegAlgoST.h:219
T getParameter(std::string const &) const
double protoChiUCorrection
Allow to correct the error matrix.
Definition: CSCSegAlgoST.h:228
T getUntrackedParameter(std::string const &, T const &) const
const std::string myName
Definition: CSCSegAlgoST.h:145
bool preClustering_useChaining
Definition: CSCSegAlgoST.h:206
bool passCondNumber
The number to force the Covariance.
Definition: CSCSegAlgoST.h:242
double dXclusBoxMax
Definition: CSCSegAlgoST.h:202
CSCSegmentAlgorithm(const edm::ParameterSet &)
Constructor.
double condSeed1_
The upper limit of protoChiUCorrection to apply prePrun.
Definition: CSCSegAlgoST.h:238
double hitDropLimit4Hits
Definition: CSCSegAlgoST.h:213
CSCSegAlgoShowering * showering_
Definition: CSCSegAlgoST.h:224
double BPMinImprovement
Definition: CSCSegAlgoST.h:209
double covAnyNumber_
Allow to use any number for covariance for all RecHits.
Definition: CSCSegAlgoST.h:241
double curvePenaltyThreshold
Definition: CSCSegAlgoST.h:222
double protoNDF
Definition: CSCSegAlgoST.h:192
double hitDropLimit6Hits
Definition: CSCSegAlgoST.h:215
double chi2Norm_2D_
Definition: CSCSegAlgoST.h:230
unsigned maxContrIndex
Chi^2 normalization for the initial fit.
Definition: CSCSegAlgoST.h:232
bool onlyBestSegment
Definition: CSCSegAlgoST.h:210
bool passCondNumber_2
Passage the condition number calculations.
Definition: CSCSegAlgoST.h:243
bool correctCov_
Correct the Error Matrix.
Definition: CSCSegAlgoST.h:227
int minHitsPerSegment
Definition: CSCSegAlgoST.h:199
double dYclusBoxMax
Definition: CSCSegAlgoST.h:203
bool covToAnyNumberAll_
Allow to use any number for covariance (by hand)
Definition: CSCSegAlgoST.h:240
double curvePenalty
Definition: CSCSegAlgoST.h:223
bool prePrun_
The index of the worst x RecHit in Chi^2-X method.
Definition: CSCSegAlgoST.h:233
bool preClustering
Definition: CSCSegAlgoST.h:205
double yweightPenalty
Definition: CSCSegAlgoST.h:220
int maxRecHitsInCluster
Definition: CSCSegAlgoST.h:204
bool covToAnyNumber_
The correction parameters.
Definition: CSCSegAlgoST.h:239
double hitDropLimit5Hits
Definition: CSCSegAlgoST.h:214
double condSeed2_
Definition: CSCSegAlgoST.h:238
double chi2Norm_3D_
Chi^2 normalization for the corrected fit.
Definition: CSCSegAlgoST.h:231
double prePrunLimit_
Definition: CSCSegAlgoST.h:235
CSCSegAlgoST::~CSCSegAlgoST ( )
virtual

Destructor.

Definition at line 90 of file CSCSegAlgoST.cc.

References showering_.

90  {
91  delete showering_;
92 }
CSCSegAlgoShowering * showering_
Definition: CSCSegAlgoST.h:224

Member Function Documentation

std::vector< CSCSegment > CSCSegAlgoST::buildSegments ( const ChamberHitContainer rechits)

Build track segments in this chamber (this is where the actual segment-building algorithm hides.)

Definition at line 671 of file CSCSegAlgoST.cc.

References a_yweightPenaltyThreshold, calculateError(), CSCSegment::chi2(), chi2Norm_3D_, ChooseSegments2a(), ChooseSegments3(), chosen_Psegments, chosen_weight_A, correctCov_, curv_A, curv_noL1_A, curv_noL2_A, curv_noL3_A, curv_noL4_A, curv_noL5_A, curv_noL6_A, curvePenalty, curvePenaltyThreshold, doSlopesAndChi2(), dumpSegment(), end, fillLocalDirection(), flipErrors(), GoodSegments, hitDropLimit4Hits, hitDropLimit5Hits, hitDropLimit6Hits, i, LogTrace, maxContrIndex, maxRecHitsInCluster, minHitsPerSegment, CSCSegment::nRecHits(), onlyBestSegment, PAhits_onLayer, passCondNumber, passCondNumber_2, prePrun_, prePrunLimit_, protoChi2, protoChiUCorrection, protoDirection, protoIntercept, protoNDF, protoSegment, Psegments, Psegments_hits, Psegments_noL1, Psegments_noL2, Psegments_noL3, Psegments_noL4, Psegments_noL5, Psegments_noL6, Psegments_noLx, showering_, CSCSegAlgoShowering::showerSeg(), findQualityFiles::size, mathSSE::sqrt(), groupFilesInBlocks::temp, theChamber, theWeight(), useShowering, weight_A, weight_B, weight_noL1_A, weight_noL1_B, weight_noL2_A, weight_noL2_B, weight_noL3_A, weight_noL3_B, weight_noL4_A, weight_noL4_B, weight_noL5_A, weight_noL5_B, weight_noL6_A, weight_noL6_B, weight_noLx_A, x, detailsBasic3DVector::y, and yweightPenalty.

Referenced by run().

671  {
672 
673  // Clear buffer for segment vector
674  std::vector<CSCSegment> segmentInChamber;
675  segmentInChamber.clear(); // list of final segments
676 
677  // CSC Ring;
678  unsigned int thering = 999;
679  unsigned int thestation = 999;
680  //unsigned int thecham = 999;
681 
682  std::vector<int> hits_onLayerNumber(6);
683 
684  unsigned int UpperLimit = maxRecHitsInCluster;
685  if (int(rechits.size()) < minHitsPerSegment) return segmentInChamber;
686 
687  for(int iarray = 0; iarray <6; ++iarray) { // magic number 6: number of layers in CSC chamber - not gonna change :)
688  PAhits_onLayer[iarray].clear();
689  hits_onLayerNumber[iarray] = 0;
690  }
691 
692  chosen_Psegments.clear();
693  chosen_weight_A.clear();
694 
695  Psegments.clear();
696  Psegments_noLx.clear();
697  Psegments_noL1.clear();
698  Psegments_noL2.clear();
699  Psegments_noL3.clear();
700  Psegments_noL4.clear();
701  Psegments_noL5.clear();
702  Psegments_noL6.clear();
703 
704  Psegments_hits.clear();
705 
706  weight_A.clear();
707  weight_noLx_A.clear();
708  weight_noL1_A.clear();
709  weight_noL2_A.clear();
710  weight_noL3_A.clear();
711  weight_noL4_A.clear();
712  weight_noL5_A.clear();
713  weight_noL6_A.clear();
714 
715  weight_B.clear();
716  weight_noL1_B.clear();
717  weight_noL2_B.clear();
718  weight_noL3_B.clear();
719  weight_noL4_B.clear();
720  weight_noL5_B.clear();
721  weight_noL6_B.clear();
722 
723  curv_A.clear();
724  curv_noL1_A.clear();
725  curv_noL2_A.clear();
726  curv_noL3_A.clear();
727  curv_noL4_A.clear();
728  curv_noL5_A.clear();
729  curv_noL6_A.clear();
730 
731  // definition of middle layer for n-hit segment
732  int midlayer_pointer[6] = {0,0,2,3,3,4};
733 
734  // int n_layers_missed_tot = 0;
735  int n_layers_occupied_tot = 0;
736  int n_layers_processed = 0;
737 
738  float min_weight_A = 99999.9;
739  float min_weight_noLx_A = 99999.9;
740 
741  //float best_weight_B = -1.;
742  //float best_weight_noLx_B = -1.;
743 
744  //float best_curv_A = -1.;
745  //float best_curv_noLx_A = -1.;
746 
747  int best_pseg = -1;
748  int best_noLx_pseg = -1;
749  int best_Layer_noLx = -1;
750 
751  //************************************************************************;
752  //*** Start segment building *****************************************;
753  //************************************************************************;
754 
755  // Determine how many layers with hits we have
756  // Fill all hits into the layer hit container:
757 
758  // Have 2 standard arrays: one giving the number of hits per layer.
759  // The other the corresponding hits.
760 
761  // Loop all available hits, count hits per layer and fill the hits into array by layer
762  for(size_t M = 0; M < rechits.size(); ++M) {
763  // add hits to array per layer and count hits per layer:
764  hits_onLayerNumber[ rechits[M]->cscDetId().layer()-1 ] += 1;
765  if(hits_onLayerNumber[ rechits[M]->cscDetId().layer()-1 ] == 1 ) n_layers_occupied_tot += 1;
766  // add hits to vector in array
767  PAhits_onLayer[rechits[M]->cscDetId().layer()-1] .push_back(rechits[M]);
768  }
769 
770  // We have now counted the hits per layer and filled pointers to the hits into an array
771 
772  int tothits = 0;
773  int maxhits = 0;
774  int nexthits = 0;
775  int maxlayer = -1;
776  int nextlayer = -1;
777 
778  for(size_t i = 0; i< hits_onLayerNumber.size(); ++i){
779  //std::cout<<"We have "<<hits_onLayerNumber[i]<<" hits on layer "<<i+1<<std::endl;
780  tothits += hits_onLayerNumber[i];
781  if (hits_onLayerNumber[i] > maxhits) {
782  nextlayer = maxlayer;
783  nexthits = maxhits;
784  maxlayer = i;
785  maxhits = hits_onLayerNumber[i];
786  }
787  else if (hits_onLayerNumber[i] > nexthits) {
788  nextlayer = i;
789  nexthits = hits_onLayerNumber[i];
790  }
791  }
792 
793 
794  if (tothits > (int)UpperLimit) {
795  if (n_layers_occupied_tot > 4) {
796  tothits = tothits - hits_onLayerNumber[maxlayer];
797  n_layers_occupied_tot = n_layers_occupied_tot - 1;
798  PAhits_onLayer[maxlayer].clear();
799  hits_onLayerNumber[maxlayer] = 0;
800  }
801  }
802 
803  if (tothits > (int)UpperLimit) {
804  if (n_layers_occupied_tot > 4) {
805  tothits = tothits - hits_onLayerNumber[nextlayer];
806  n_layers_occupied_tot = n_layers_occupied_tot - 1;
807  PAhits_onLayer[nextlayer].clear();
808  hits_onLayerNumber[nextlayer] = 0;
809  }
810  }
811 
812  if (tothits > (int)UpperLimit){
813 
814  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
815  // Showering muon - returns nothing if chi2 == -1 (see comment in SegAlgoShowering)
816  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
817  if (useShowering) {
818  CSCSegment segShower = showering_->showerSeg(theChamber, rechits);
819 
820  // Make sure have at least 3 hits...
821  if ( segShower.nRecHits() < 3 ) return segmentInChamber;
822  if ( segShower.chi2() == -1 ) return segmentInChamber;
823 
824  segmentInChamber.push_back(segShower);
825  return segmentInChamber;
826 
827  } else{
828  LogTrace("CSCSegment|CSC") << "[CSCSegAlgoST::buildSegments] No. of rechits in the cluster/chamber > " << UpperLimit <<
829  " ... Segment finding in the cluster/chamber canceled!";
830  return segmentInChamber;
831  }
832  }
833 
834  // Find out which station, ring and chamber we are in
835  // Used to choose station/ring dependant y-weight cuts
836 
837  if( rechits.size() > 0 ) {
838  thering = rechits[0]->cscDetId().ring();
839  thestation = rechits[0]->cscDetId().station();
840  //thecham = rechits[0]->cscDetId().chamber();
841  }
842 
843  // std::cout<<"We are in Station/ring/chamber: "<<thestation <<" "<< thering<<" "<< thecham<<std::endl;
844 
845  // Cut-off parameter - don't reconstruct segments with less than X hits
846  if( n_layers_occupied_tot < minHitsPerSegment ) {
847  return segmentInChamber;
848  }
849 
850  // Start building all possible hit combinations:
851 
852  // loop over the six chamber layers and form segment candidates from the available hits:
853 
854  for(int layer = 0; layer < 6; ++layer) {
855 
856  // *****************************************************************
857  // *** Set missed layer counter here (not currently implemented) ***
858  // *****************************************************************
859  // if( PAhits_onLayer[layer].size() == 0 ) {
860  // n_layers_missed_tot += 1;
861  // }
862 
863  if( PAhits_onLayer[layer].size() > 0 ) {
864  n_layers_processed += 1;
865  }
866 
867  // Save the size of the protosegment before hits were added on the current layer
868  int orig_number_of_psegs = Psegments.size();
869  int orig_number_of_noL1_psegs = Psegments_noL1.size();
870  int orig_number_of_noL2_psegs = Psegments_noL2.size();
871  int orig_number_of_noL3_psegs = Psegments_noL3.size();
872  int orig_number_of_noL4_psegs = Psegments_noL4.size();
873  int orig_number_of_noL5_psegs = Psegments_noL5.size();
874  int orig_number_of_noL6_psegs = Psegments_noL6.size();
875 
876  // loop over the hits on the layer and initiate protosegments or add hits to protosegments
877  for(int hit = 0; hit < int(PAhits_onLayer[layer].size()); ++hit) { // loop all hits on the Layer number "layer"
878 
879  // create protosegments from all hits on the first layer with hits
880  if( orig_number_of_psegs == 0 ) { // would be faster to turn this around - ask for "orig_number_of_psegs != 0"
881 
882  Psegments_hits.push_back(PAhits_onLayer[layer][hit]);
883 
884  Psegments.push_back(Psegments_hits);
885  Psegments_noL6.push_back(Psegments_hits);
886  Psegments_noL5.push_back(Psegments_hits);
887  Psegments_noL4.push_back(Psegments_hits);
888  Psegments_noL3.push_back(Psegments_hits);
889  Psegments_noL2.push_back(Psegments_hits);
890 
891  // Initialize weights corresponding to this segment for first hit (with 0)
892 
893  curv_A.push_back(0.0);
894  curv_noL6_A.push_back(0.0);
895  curv_noL5_A.push_back(0.0);
896  curv_noL4_A.push_back(0.0);
897  curv_noL3_A.push_back(0.0);
898  curv_noL2_A.push_back(0.0);
899 
900  weight_A.push_back(0.0);
901  weight_noL6_A.push_back(0.0);
902  weight_noL5_A.push_back(0.0);
903  weight_noL4_A.push_back(0.0);
904  weight_noL3_A.push_back(0.0);
905  weight_noL2_A.push_back(0.0);
906 
907  weight_B.push_back(0.0);
908  weight_noL6_B.push_back(0.0);
909  weight_noL5_B.push_back(0.0);
910  weight_noL4_B.push_back(0.0);
911  weight_noL3_B.push_back(0.0);
912  weight_noL2_B.push_back(0.0);
913 
914  // reset array for next hit on next layer
915  Psegments_hits .clear();
916  }
917  else {
918  if( orig_number_of_noL1_psegs == 0 ) {
919 
920  Psegments_hits.push_back(PAhits_onLayer[layer][hit]);
921 
922  Psegments_noL1.push_back(Psegments_hits);
923 
924  // Initialize weight corresponding to this segment for first hit (with 0)
925 
926  curv_noL1_A.push_back(0.0);
927 
928  weight_noL1_A.push_back(0.0);
929 
930  weight_noL1_B.push_back(0.0);
931 
932  // reset array for next hit on next layer
933  Psegments_hits .clear();
934 
935  }
936 
937  // loop over the protosegments and create a new protosegments for each hit-1 on this layer
938 
939  for( int pseg = 0; pseg < orig_number_of_psegs; ++pseg ) {
940 
941  int pseg_pos = (pseg)+((hit)*orig_number_of_psegs);
942  int pseg_noL1_pos = (pseg)+((hit)*orig_number_of_noL1_psegs);
943  int pseg_noL2_pos = (pseg)+((hit)*orig_number_of_noL2_psegs);
944  int pseg_noL3_pos = (pseg)+((hit)*orig_number_of_noL3_psegs);
945  int pseg_noL4_pos = (pseg)+((hit)*orig_number_of_noL4_psegs);
946  int pseg_noL5_pos = (pseg)+((hit)*orig_number_of_noL5_psegs);
947  int pseg_noL6_pos = (pseg)+((hit)*orig_number_of_noL6_psegs);
948 
949  // - Loop all psegs.
950  // - If not last hit, clone existing protosegments (PAhits_onLayer[layer].size()-1) times
951  // - then add the new hits
952 
953  if( ! (hit == int(PAhits_onLayer[layer].size()-1)) ) { // not the last hit - prepare (copy) new protosegments for the following hits
954  // clone psegs (to add next hits or last hit on layer):
955 
956  Psegments.push_back(Psegments[ pseg_pos ]);
957  if (n_layers_processed != 2 && pseg < orig_number_of_noL1_psegs) Psegments_noL1.push_back(Psegments_noL1[ pseg_noL1_pos ]);
958  if (n_layers_processed != 2 && pseg < orig_number_of_noL2_psegs) Psegments_noL2.push_back(Psegments_noL2[ pseg_noL2_pos ]);
959  if (n_layers_processed != 3 && pseg < orig_number_of_noL3_psegs) Psegments_noL3.push_back(Psegments_noL3[ pseg_noL3_pos ]);
960  if (n_layers_processed != 4 && pseg < orig_number_of_noL4_psegs) Psegments_noL4.push_back(Psegments_noL4[ pseg_noL4_pos ]);
961  if (n_layers_processed != 5 && pseg < orig_number_of_noL5_psegs) Psegments_noL5.push_back(Psegments_noL5[ pseg_noL5_pos ]);
962  if (n_layers_processed != 6 && pseg < orig_number_of_noL6_psegs) Psegments_noL6.push_back(Psegments_noL6[ pseg_noL6_pos ]);
963  // clone weight corresponding to this segment too
964  weight_A.push_back(weight_A[ pseg_pos ]);
965  if (n_layers_processed != 2 && pseg < orig_number_of_noL1_psegs) weight_noL1_A.push_back(weight_noL1_A[ pseg_noL1_pos ]);
966  if (n_layers_processed != 2 && pseg < orig_number_of_noL2_psegs) weight_noL2_A.push_back(weight_noL2_A[ pseg_noL2_pos ]);
967  if (n_layers_processed != 3 && pseg < orig_number_of_noL3_psegs) weight_noL3_A.push_back(weight_noL3_A[ pseg_noL3_pos ]);
968  if (n_layers_processed != 4 && pseg < orig_number_of_noL4_psegs) weight_noL4_A.push_back(weight_noL4_A[ pseg_noL4_pos ]);
969  if (n_layers_processed != 5 && pseg < orig_number_of_noL5_psegs) weight_noL5_A.push_back(weight_noL5_A[ pseg_noL5_pos ]);
970  if (n_layers_processed != 6 && pseg < orig_number_of_noL6_psegs) weight_noL6_A.push_back(weight_noL6_A[ pseg_noL6_pos ]);
971  // clone curvature variable corresponding to this segment too
972  curv_A.push_back(curv_A[ pseg_pos ]);
973  if (n_layers_processed != 2 && pseg < orig_number_of_noL1_psegs) curv_noL1_A.push_back(curv_noL1_A[ pseg_noL1_pos ]);
974  if (n_layers_processed != 2 && pseg < orig_number_of_noL2_psegs) curv_noL2_A.push_back(curv_noL2_A[ pseg_noL2_pos ]);
975  if (n_layers_processed != 3 && pseg < orig_number_of_noL3_psegs) curv_noL3_A.push_back(curv_noL3_A[ pseg_noL3_pos ]);
976  if (n_layers_processed != 4 && pseg < orig_number_of_noL4_psegs) curv_noL4_A.push_back(curv_noL4_A[ pseg_noL4_pos ]);
977  if (n_layers_processed != 5 && pseg < orig_number_of_noL5_psegs) curv_noL5_A.push_back(curv_noL5_A[ pseg_noL5_pos ]);
978  if (n_layers_processed != 6 && pseg < orig_number_of_noL6_psegs) curv_noL6_A.push_back(curv_noL6_A[ pseg_noL6_pos ]);
979  // clone "y"-weight corresponding to this segment too
980  weight_B.push_back(weight_B[ pseg_pos ]);
981  if (n_layers_processed != 2 && pseg < orig_number_of_noL1_psegs) weight_noL1_B.push_back(weight_noL1_B[ pseg_noL1_pos ]);
982  if (n_layers_processed != 2 && pseg < orig_number_of_noL2_psegs) weight_noL2_B.push_back(weight_noL2_B[ pseg_noL2_pos ]);
983  if (n_layers_processed != 3 && pseg < orig_number_of_noL3_psegs) weight_noL3_B.push_back(weight_noL3_B[ pseg_noL3_pos ]);
984  if (n_layers_processed != 4 && pseg < orig_number_of_noL4_psegs) weight_noL4_B.push_back(weight_noL4_B[ pseg_noL4_pos ]);
985  if (n_layers_processed != 5 && pseg < orig_number_of_noL5_psegs) weight_noL5_B.push_back(weight_noL5_B[ pseg_noL5_pos ]);
986  if (n_layers_processed != 6 && pseg < orig_number_of_noL6_psegs) weight_noL6_B.push_back(weight_noL6_B[ pseg_noL6_pos ]);
987  }
988  // add hits to original pseg:
989  Psegments[ pseg_pos ].push_back(PAhits_onLayer[ layer ][ hit ]);
990  if (n_layers_processed != 2 && pseg < orig_number_of_noL1_psegs) Psegments_noL1[ pseg_noL1_pos ].push_back(PAhits_onLayer[ layer ][ hit ]);
991  if (n_layers_processed != 2 && pseg < orig_number_of_noL2_psegs) Psegments_noL2[ pseg_noL2_pos ].push_back(PAhits_onLayer[ layer ][ hit ]);
992  if (n_layers_processed != 3 && pseg < orig_number_of_noL3_psegs) Psegments_noL3[ pseg_noL3_pos ].push_back(PAhits_onLayer[ layer ][ hit ]);
993  if (n_layers_processed != 4 && pseg < orig_number_of_noL4_psegs) Psegments_noL4[ pseg_noL4_pos ].push_back(PAhits_onLayer[ layer ][ hit ]);
994  if (n_layers_processed != 5 && pseg < orig_number_of_noL5_psegs) Psegments_noL5[ pseg_noL5_pos ].push_back(PAhits_onLayer[ layer ][ hit ]);
995  if (n_layers_processed != 6 && pseg < orig_number_of_noL6_psegs) Psegments_noL6[ pseg_noL6_pos ].push_back(PAhits_onLayer[ layer ][ hit ]);
996 
997  // calculate/update the weight (only for >2 hits on psegment):
998 
999  if( Psegments[ pseg_pos ].size() > 2 ) {
1000 
1001  // looks more exciting than it is. Here the weight is calculated. It is the difference in x of the last two and one but the last two hits,
1002  // divided by the distance of the corresponding hits. Please refer to twiki page XXXX or CMS Note YYY (and use layer_distance)
1003 
1004  weight_A[ pseg_pos ] += theWeight(
1005  (*(Psegments[ pseg_pos ].end()-1 ))->localPosition().x(),
1006  (*(Psegments[ pseg_pos ].end()-2 ))->localPosition().x(),
1007  (*(Psegments[ pseg_pos ].end()-3 ))->localPosition().x(),
1008  float((*(Psegments[ pseg_pos ].end()-1))->cscDetId().layer()),
1009  float((*(Psegments[ pseg_pos ].end()-2))->cscDetId().layer()),
1010  float((*(Psegments[ pseg_pos ].end()-3))->cscDetId().layer())
1011  );
1012 
1013  weight_B[ pseg_pos ] += theWeight(
1014  (*(Psegments[ pseg_pos ].end()-1 ))->localPosition().y(),
1015  (*(Psegments[ pseg_pos ].end()-2 ))->localPosition().y(),
1016  (*(Psegments[ pseg_pos ].end()-3 ))->localPosition().y(),
1017  float((*(Psegments[ pseg_pos ].end()-1))->cscDetId().layer()),
1018  float((*(Psegments[ pseg_pos ].end()-2))->cscDetId().layer()),
1019  float((*(Psegments[ pseg_pos ].end()-3))->cscDetId().layer())
1020  );
1021 
1022  // if we have picked up the last hit go looking for pseg with the lowest (and second lowest?) weight
1023 
1024  if(int(Psegments[ pseg_pos ].size()) == n_layers_occupied_tot) {
1025 
1026  curv_A[ pseg_pos ] += theWeight(
1027  (*(Psegments[ pseg_pos ].end()-1 ))->localPosition().x(),
1028  (*(Psegments[ pseg_pos ].end()-midlayer_pointer[n_layers_occupied_tot-1] ))->localPosition().x(),
1029  (*(Psegments[ pseg_pos ].end()-n_layers_occupied_tot ))->localPosition().x(),
1030  float((*(Psegments[ pseg_pos ].end()-1))->cscDetId().layer()),
1031  float((*(Psegments[ pseg_pos ].end()-midlayer_pointer[n_layers_occupied_tot-1] ))->cscDetId().layer()),
1032  float((*(Psegments[ pseg_pos ].end()-n_layers_occupied_tot ))->cscDetId().layer())
1033  );
1034 
1035  if (curv_A[ pseg_pos ] > curvePenaltyThreshold) weight_A[ pseg_pos ] = weight_A[ pseg_pos ] * curvePenalty;
1036 
1037  if (weight_B[ pseg_pos ] > a_yweightPenaltyThreshold[thestation][thering]) weight_A[ pseg_pos ] = weight_A[ pseg_pos ] * yweightPenalty;
1038 
1039  if (weight_A[ pseg_pos ] < min_weight_A ) {
1040  min_weight_A = weight_A[ pseg_pos ];
1041  //best_weight_B = weight_B[ pseg_pos ];
1042  //best_curv_A = curv_A[ pseg_pos ];
1043  best_pseg = pseg_pos ;
1044  }
1045 
1046  }
1047 
1048  // alternative: fill map with weight and pseg (which is already ordered)? Seems a very good tool to go looking for segments from.
1049  // As I understand, the segments would be inserted according to their weight, so the list would "automatically" be sorted.
1050 
1051  }
1052 
1053  if ( n_layers_occupied_tot > 3 ) {
1054  if (pseg < orig_number_of_noL1_psegs && (n_layers_processed != 2)) {
1055  if(( Psegments_noL1[ pseg_noL1_pos ].size() > 2 ) ) {
1056 
1057  // looks more exciting than it is. Here the weight is calculated. It is the difference in x of the last two and one but the last two hits,
1058  // divided by the distance of the corresponding hits. Please refer to twiki page XXXX or CMS Note YYY (and use layer_distance)
1059 
1060  weight_noL1_A[ pseg_noL1_pos ] += theWeight(
1061  (*(Psegments_noL1[ pseg_noL1_pos ].end()-1 ))->localPosition().x(),
1062  (*(Psegments_noL1[ pseg_noL1_pos ].end()-2 ))->localPosition().x(),
1063  (*(Psegments_noL1[ pseg_noL1_pos ].end()-3 ))->localPosition().x(),
1064  float((*(Psegments_noL1[ pseg_noL1_pos ].end()-1))->cscDetId().layer()),
1065  float((*(Psegments_noL1[ pseg_noL1_pos ].end()-2))->cscDetId().layer()),
1066  float((*(Psegments_noL1[ pseg_noL1_pos ].end()-3))->cscDetId().layer())
1067  );
1068 
1069  weight_noL1_B[ pseg_noL1_pos ] += theWeight(
1070  (*(Psegments_noL1[ pseg_noL1_pos ].end()-1 ))->localPosition().y(),
1071  (*(Psegments_noL1[ pseg_noL1_pos ].end()-2 ))->localPosition().y(),
1072  (*(Psegments_noL1[ pseg_noL1_pos ].end()-3 ))->localPosition().y(),
1073  float((*(Psegments_noL1[ pseg_noL1_pos ].end()-1))->cscDetId().layer()),
1074  float((*(Psegments_noL1[ pseg_noL1_pos ].end()-2))->cscDetId().layer()),
1075  float((*(Psegments_noL1[ pseg_noL1_pos ].end()-3))->cscDetId().layer())
1076  );
1077 
1078  //if we have picked up the last hit go looking for pseg with the lowest (and second lowest?) weight
1079 
1080  if(int(Psegments_noL1[ pseg_noL1_pos ].size()) == n_layers_occupied_tot -1 ) {
1081 
1082  curv_noL1_A[ pseg_noL1_pos ] += theWeight(
1083  (*(Psegments_noL1[ pseg_noL1_pos ].end()-1 ))->localPosition().x(),
1084  (*(Psegments_noL1[ pseg_noL1_pos ].end()-midlayer_pointer[n_layers_occupied_tot-2] ))->localPosition().x(),
1085  (*(Psegments_noL1[ pseg_noL1_pos ].end()-(n_layers_occupied_tot-1) ))->localPosition().x(),
1086  float((*(Psegments_noL1[ pseg_noL1_pos ].end()-1 ))->cscDetId().layer()),
1087  float((*(Psegments_noL1[ pseg_noL1_pos ].end()-midlayer_pointer[n_layers_occupied_tot-2] ))->cscDetId().layer()),
1088  float((*(Psegments_noL1[ pseg_noL1_pos ].end()-(n_layers_occupied_tot-1) ))->cscDetId().layer())
1089  );
1090 
1091  if (curv_noL1_A[ pseg_noL1_pos ] > curvePenaltyThreshold) weight_noL1_A[ pseg_noL1_pos ] = weight_noL1_A[ pseg_noL1_pos ] * curvePenalty;
1092 
1093  if (weight_noL1_B[ pseg_noL1_pos ] > a_yweightPenaltyThreshold[thestation][thering])
1094  weight_noL1_A[ pseg_noL1_pos ] = weight_noL1_A[ pseg_noL1_pos ] * yweightPenalty;
1095 
1096  if (weight_noL1_A[ pseg_noL1_pos ] < min_weight_noLx_A ) {
1097  min_weight_noLx_A = weight_noL1_A[ pseg_noL1_pos ];
1098  //best_weight_noLx_B = weight_noL1_B[ pseg_noL1_pos ];
1099  //best_curv_noLx_A = curv_noL1_A[ pseg_noL1_pos ];
1100  best_noLx_pseg = pseg_noL1_pos;
1101  best_Layer_noLx = 1;
1102  }
1103 
1104  }
1105 
1106  // alternative: fill map with weight and pseg (which is already ordered)? Seems a very good tool to go looking for segments from.
1107  // As I understand, the segments would be inserted according to their weight, so the list would "automatically" be sorted.
1108 
1109  }
1110  }
1111  }
1112 
1113  if ( n_layers_occupied_tot > 3 ) {
1114  if (pseg < orig_number_of_noL2_psegs && ( n_layers_processed != 2 )) {
1115  if(( Psegments_noL2[ pseg_noL2_pos ].size() > 2 )) {
1116 
1117  // looks more exciting than it is. Here the weight is calculated. It is the difference in x of the last two and one but the last two hits,
1118  // divided by the distance of the corresponding hits. Please refer to twiki page XXXX or CMS Note YYY (and use layer_distance)
1119 
1120  weight_noL2_A[ pseg_noL2_pos ] += theWeight(
1121  (*(Psegments_noL2[ pseg_noL2_pos ].end()-1 ))->localPosition().x(),
1122  (*(Psegments_noL2[ pseg_noL2_pos ].end()-2 ))->localPosition().x(),
1123  (*(Psegments_noL2[ pseg_noL2_pos ].end()-3 ))->localPosition().x(),
1124  float((*(Psegments_noL2[ pseg_noL2_pos ].end()-1))->cscDetId().layer()),
1125  float((*(Psegments_noL2[ pseg_noL2_pos ].end()-2))->cscDetId().layer()),
1126  float((*(Psegments_noL2[ pseg_noL2_pos ].end()-3))->cscDetId().layer())
1127  );
1128 
1129  weight_noL2_B[ pseg_noL2_pos ] += theWeight(
1130  (*(Psegments_noL2[ pseg_noL2_pos ].end()-1 ))->localPosition().y(),
1131  (*(Psegments_noL2[ pseg_noL2_pos ].end()-2 ))->localPosition().y(),
1132  (*(Psegments_noL2[ pseg_noL2_pos ].end()-3 ))->localPosition().y(),
1133  float((*(Psegments_noL2[ pseg_noL2_pos ].end()-1))->cscDetId().layer()),
1134  float((*(Psegments_noL2[ pseg_noL2_pos ].end()-2))->cscDetId().layer()),
1135  float((*(Psegments_noL2[ pseg_noL2_pos ].end()-3))->cscDetId().layer())
1136  );
1137 
1138  //if we have picked up the last hit go looking for pseg with the lowest (and second lowest?) weight
1139 
1140  if(int(Psegments_noL2[ pseg_noL2_pos ].size()) == n_layers_occupied_tot -1 ) {
1141 
1142  curv_noL2_A[ pseg_noL2_pos ] += theWeight(
1143  (*(Psegments_noL2[ pseg_noL2_pos ].end()-1 ))->localPosition().x(),
1144  (*(Psegments_noL2[ pseg_noL2_pos ].end()-midlayer_pointer[n_layers_occupied_tot-2] ))->localPosition().x(),
1145  (*(Psegments_noL2[ pseg_noL2_pos ].end()-(n_layers_occupied_tot-1) ))->localPosition().x(),
1146  float((*(Psegments_noL2[ pseg_noL2_pos ].end()-1 ))->cscDetId().layer()),
1147  float((*(Psegments_noL2[ pseg_noL2_pos ].end()-midlayer_pointer[n_layers_occupied_tot-2] ))->cscDetId().layer()),
1148  float((*(Psegments_noL2[ pseg_noL2_pos ].end()-(n_layers_occupied_tot-1) ))->cscDetId().layer())
1149  );
1150 
1151  if (curv_noL2_A[ pseg_noL2_pos ] > curvePenaltyThreshold) weight_noL2_A[ pseg_noL2_pos ] = weight_noL2_A[ pseg_noL2_pos ] * curvePenalty;
1152 
1153  if (weight_noL2_B[ pseg_noL2_pos ] > a_yweightPenaltyThreshold[thestation][thering])
1154  weight_noL2_A[ pseg_noL2_pos ] = weight_noL2_A[ pseg_noL2_pos ] * yweightPenalty;
1155 
1156  if (weight_noL2_A[ pseg_noL2_pos ] < min_weight_noLx_A ) {
1157  min_weight_noLx_A = weight_noL2_A[ pseg_noL2_pos ];
1158  //best_weight_noLx_B = weight_noL2_B[ pseg_noL2_pos ];
1159  //best_curv_noLx_A = curv_noL2_A[ pseg_noL2_pos ];
1160  best_noLx_pseg = pseg_noL2_pos;
1161  best_Layer_noLx = 2;
1162  }
1163 
1164  }
1165 
1166  // alternative: fill map with weight and pseg (which is already ordered)? Seems a very good tool to go looking for segments from.
1167  // As I understand, the segments would be inserted according to their weight, so the list would "automatically" be sorted.
1168 
1169  }
1170  }
1171  }
1172 
1173  if ( n_layers_occupied_tot > 3 ) {
1174  if (pseg < orig_number_of_noL3_psegs && ( n_layers_processed != 3 )) {
1175  if(( Psegments_noL3[ pseg_noL3_pos ].size() > 2 )) {
1176 
1177  // looks more exciting than it is. Here the weight is calculated. It is the difference in x of the last two and one but the last two hits,
1178  // divided by the distance of the corresponding hits. Please refer to twiki page XXXX or CMS Note YYY (and use layer_distance)
1179 
1180  weight_noL3_A[ pseg_noL3_pos ] += theWeight(
1181  (*(Psegments_noL3[ pseg_noL3_pos ].end()-1 ))->localPosition().x(),
1182  (*(Psegments_noL3[ pseg_noL3_pos ].end()-2 ))->localPosition().x(),
1183  (*(Psegments_noL3[ pseg_noL3_pos ].end()-3 ))->localPosition().x(),
1184  float((*(Psegments_noL3[ pseg_noL3_pos ].end()-1))->cscDetId().layer()),
1185  float((*(Psegments_noL3[ pseg_noL3_pos ].end()-2))->cscDetId().layer()),
1186  float((*(Psegments_noL3[ pseg_noL3_pos ].end()-3))->cscDetId().layer())
1187  );
1188 
1189  weight_noL3_B[ pseg_noL3_pos ] += theWeight(
1190  (*(Psegments_noL3[ pseg_noL3_pos ].end()-1 ))->localPosition().y(),
1191  (*(Psegments_noL3[ pseg_noL3_pos ].end()-2 ))->localPosition().y(),
1192  (*(Psegments_noL3[ pseg_noL3_pos ].end()-3 ))->localPosition().y(),
1193  float((*(Psegments_noL3[ pseg_noL3_pos ].end()-1))->cscDetId().layer()),
1194  float((*(Psegments_noL3[ pseg_noL3_pos ].end()-2))->cscDetId().layer()),
1195  float((*(Psegments_noL3[ pseg_noL3_pos ].end()-3))->cscDetId().layer())
1196  );
1197 
1198  //if we have picked up the last hit go looking for pseg with the lowest (and second lowest?) weight
1199 
1200  if(int(Psegments_noL3[ pseg_noL3_pos ].size()) == n_layers_occupied_tot -1 ) {
1201 
1202  curv_noL3_A[ pseg_noL3_pos ] += theWeight(
1203  (*(Psegments_noL3[ pseg_noL3_pos ].end()-1 ))->localPosition().x(),
1204  (*(Psegments_noL3[ pseg_noL3_pos ].end()-midlayer_pointer[n_layers_occupied_tot-2] ))->localPosition().x(),
1205  (*(Psegments_noL3[ pseg_noL3_pos ].end()-(n_layers_occupied_tot-1) ))->localPosition().x(),
1206  float((*(Psegments_noL3[ pseg_noL3_pos ].end()-1 ))->cscDetId().layer()),
1207  float((*(Psegments_noL3[ pseg_noL3_pos ].end()-midlayer_pointer[n_layers_occupied_tot-2] ))->cscDetId().layer()),
1208  float((*(Psegments_noL3[ pseg_noL3_pos ].end()-(n_layers_occupied_tot-1) ))->cscDetId().layer())
1209  );
1210 
1211  if (curv_noL3_A[ pseg_noL3_pos ] > curvePenaltyThreshold) weight_noL3_A[ pseg_noL3_pos ] = weight_noL3_A[ pseg_noL3_pos ] * curvePenalty;
1212 
1213  if (weight_noL3_B[ pseg_noL3_pos ] > a_yweightPenaltyThreshold[thestation][thering])
1214  weight_noL3_A[ pseg_noL3_pos ] = weight_noL3_A[ pseg_noL3_pos ] * yweightPenalty;
1215 
1216  if (weight_noL3_A[ pseg_noL3_pos ] < min_weight_noLx_A ) {
1217  min_weight_noLx_A = weight_noL3_A[ pseg_noL3_pos ];
1218  //best_weight_noLx_B = weight_noL3_B[ pseg_noL3_pos ];
1219  //best_curv_noLx_A = curv_noL3_A[ pseg_noL3_pos ];
1220  best_noLx_pseg = pseg_noL3_pos;
1221  best_Layer_noLx = 3;
1222  }
1223 
1224  }
1225 
1226  // alternative: fill map with weight and pseg (which is already ordered)? Seems a very good tool to go looking for segments from.
1227  // As I understand, the segments would be inserted according to their weight, so the list would "automatically" be sorted.
1228 
1229  }
1230  }
1231  }
1232 
1233  if ( n_layers_occupied_tot > 3 ) {
1234  if (pseg < orig_number_of_noL4_psegs && ( n_layers_processed != 4 )) {
1235  if(( Psegments_noL4[ pseg_noL4_pos ].size() > 2 )) {
1236 
1237  // looks more exciting than it is. Here the weight is calculated. It is the difference in x of the last two and one but the last two hits,
1238  // divided by the distance of the corresponding hits. Please refer to twiki page XXXX or CMS Note YYY (and use layer_distance)
1239 
1240  weight_noL4_A[ pseg_noL4_pos ] += theWeight(
1241  (*(Psegments_noL4[ pseg_noL4_pos ].end()-1 ))->localPosition().x(),
1242  (*(Psegments_noL4[ pseg_noL4_pos ].end()-2 ))->localPosition().x(),
1243  (*(Psegments_noL4[ pseg_noL4_pos ].end()-3 ))->localPosition().x(),
1244  float((*(Psegments_noL4[ pseg_noL4_pos ].end()-1))->cscDetId().layer()),
1245  float((*(Psegments_noL4[ pseg_noL4_pos ].end()-2))->cscDetId().layer()),
1246  float((*(Psegments_noL4[ pseg_noL4_pos ].end()-3))->cscDetId().layer())
1247  );
1248 
1249  weight_noL4_B[ pseg_noL4_pos ] += theWeight(
1250  (*(Psegments_noL4[ pseg_noL4_pos ].end()-1 ))->localPosition().y(),
1251  (*(Psegments_noL4[ pseg_noL4_pos ].end()-2 ))->localPosition().y(),
1252  (*(Psegments_noL4[ pseg_noL4_pos ].end()-3 ))->localPosition().y(),
1253  float((*(Psegments_noL4[ pseg_noL4_pos ].end()-1))->cscDetId().layer()),
1254  float((*(Psegments_noL4[ pseg_noL4_pos ].end()-2))->cscDetId().layer()),
1255  float((*(Psegments_noL4[ pseg_noL4_pos ].end()-3))->cscDetId().layer())
1256  );
1257 
1258  //if we have picked up the last hit go looking for pseg with the lowest (and second lowest?) weight
1259 
1260  if(int(Psegments_noL4[ pseg_noL4_pos ].size()) == n_layers_occupied_tot -1 ) {
1261 
1262  curv_noL4_A[ pseg_noL4_pos ] += theWeight(
1263  (*(Psegments_noL4[ pseg_noL4_pos ].end()-1 ))->localPosition().x(),
1264  (*(Psegments_noL4[ pseg_noL4_pos ].end()-midlayer_pointer[n_layers_occupied_tot-2] ))->localPosition().x(),
1265  (*(Psegments_noL4[ pseg_noL4_pos ].end()-(n_layers_occupied_tot-1) ))->localPosition().x(),
1266  float((*(Psegments_noL4[ pseg_noL4_pos ].end()-1 ))->cscDetId().layer()),
1267  float((*(Psegments_noL4[ pseg_noL4_pos ].end()-midlayer_pointer[n_layers_occupied_tot-2] ))->cscDetId().layer()),
1268  float((*(Psegments_noL4[ pseg_noL4_pos ].end()-(n_layers_occupied_tot-1) ))->cscDetId().layer())
1269  );
1270 
1271  if (curv_noL4_A[ pseg_noL4_pos ] > curvePenaltyThreshold) weight_noL4_A[ pseg_noL4_pos ] = weight_noL4_A[ pseg_noL4_pos ] * curvePenalty;
1272 
1273  if (weight_noL4_B[ pseg_noL4_pos ] > a_yweightPenaltyThreshold[thestation][thering])
1274  weight_noL4_A[ pseg_noL4_pos ] = weight_noL4_A[ pseg_noL4_pos ] * yweightPenalty;
1275 
1276  if (weight_noL4_A[ pseg_noL4_pos ] < min_weight_noLx_A ) {
1277  min_weight_noLx_A = weight_noL4_A[ pseg_noL4_pos ];
1278  //best_weight_noLx_B = weight_noL4_B[ pseg_noL4_pos ];
1279  //best_curv_noLx_A = curv_noL4_A[ pseg_noL4_pos ];
1280  best_noLx_pseg = pseg_noL4_pos;
1281  best_Layer_noLx = 4;
1282  }
1283 
1284  }
1285 
1286  // alternative: fill map with weight and pseg (which is already ordered)? Seems a very good tool to go looking for segments from.
1287  // As I understand, the segments would be inserted according to their weight, so the list would "automatically" be sorted.
1288 
1289  }
1290  }
1291  }
1292 
1293  if ( n_layers_occupied_tot > 4 ) {
1294  if (pseg < orig_number_of_noL5_psegs && ( n_layers_processed != 5 )) {
1295  if(( Psegments_noL5[ pseg_noL5_pos ].size() > 2 )){
1296 
1297  // looks more exciting than it is. Here the weight is calculated. It is the difference in x of the last two and one but the last two hits,
1298  // divided by the distance of the corresponding hits. Please refer to twiki page XXXX or CMS Note YYY (and use layer_distance)
1299 
1300  weight_noL5_A[ pseg_noL5_pos ] += theWeight(
1301  (*(Psegments_noL5[ pseg_noL5_pos ].end()-1 ))->localPosition().x(),
1302  (*(Psegments_noL5[ pseg_noL5_pos ].end()-2 ))->localPosition().x(),
1303  (*(Psegments_noL5[ pseg_noL5_pos ].end()-3 ))->localPosition().x(),
1304  float((*(Psegments_noL5[ pseg_noL5_pos ].end()-1))->cscDetId().layer()),
1305  float((*(Psegments_noL5[ pseg_noL5_pos ].end()-2))->cscDetId().layer()),
1306  float((*(Psegments_noL5[ pseg_noL5_pos ].end()-3))->cscDetId().layer())
1307  );
1308 
1309  weight_noL5_B[ pseg_noL5_pos ] += theWeight(
1310  (*(Psegments_noL5[ pseg_noL5_pos ].end()-1 ))->localPosition().y(),
1311  (*(Psegments_noL5[ pseg_noL5_pos ].end()-2 ))->localPosition().y(),
1312  (*(Psegments_noL5[ pseg_noL5_pos ].end()-3 ))->localPosition().y(),
1313  float((*(Psegments_noL5[ pseg_noL5_pos ].end()-1))->cscDetId().layer()),
1314  float((*(Psegments_noL5[ pseg_noL5_pos ].end()-2))->cscDetId().layer()),
1315  float((*(Psegments_noL5[ pseg_noL5_pos ].end()-3))->cscDetId().layer())
1316  );
1317 
1318  //if we have picked up the last hit go looking for pseg with the lowest (and second lowest?) weight
1319 
1320  if(int(Psegments_noL5[ pseg_noL5_pos ].size()) == n_layers_occupied_tot -1 ) {
1321 
1322  curv_noL5_A[ pseg_noL5_pos ] += theWeight(
1323  (*(Psegments_noL5[ pseg_noL5_pos ].end()-1 ))->localPosition().x(),
1324  (*(Psegments_noL5[ pseg_noL5_pos ].end()-midlayer_pointer[n_layers_occupied_tot-2] ))->localPosition().x(),
1325  (*(Psegments_noL5[ pseg_noL5_pos ].end()-(n_layers_occupied_tot-1) ))->localPosition().x(),
1326  float((*(Psegments_noL5[ pseg_noL5_pos ].end()-1 ))->cscDetId().layer()),
1327  float((*(Psegments_noL5[ pseg_noL5_pos ].end()-midlayer_pointer[n_layers_occupied_tot-2] ))->cscDetId().layer()),
1328  float((*(Psegments_noL5[ pseg_noL5_pos ].end()-(n_layers_occupied_tot-1) ))->cscDetId().layer())
1329  );
1330 
1331  if (curv_noL5_A[ pseg_noL5_pos ] > curvePenaltyThreshold) weight_noL5_A[ pseg_noL5_pos ] = weight_noL5_A[ pseg_noL5_pos ] * curvePenalty;
1332 
1333  if (weight_noL5_B[ pseg_noL5_pos ] > a_yweightPenaltyThreshold[thestation][thering])
1334  weight_noL5_A[ pseg_noL5_pos ] = weight_noL5_A[ pseg_noL5_pos ] * yweightPenalty;
1335 
1336  if (weight_noL5_A[ pseg_noL5_pos ] < min_weight_noLx_A ) {
1337  min_weight_noLx_A = weight_noL5_A[ pseg_noL5_pos ];
1338  //best_weight_noLx_B = weight_noL5_B[ pseg_noL5_pos ];
1339  //best_curv_noLx_A = curv_noL5_A[ pseg_noL5_pos ];
1340  best_noLx_pseg = pseg_noL5_pos;
1341  best_Layer_noLx = 5;
1342  }
1343 
1344  }
1345 
1346  // alternative: fill map with weight and pseg (which is already ordered)? Seems a very good tool to go looking for segments from.
1347  // As I understand, the segments would be inserted according to their weight, so the list would "automatically" be sorted.
1348 
1349  }
1350  }
1351  }
1352 
1353  if ( n_layers_occupied_tot > 5 ) {
1354  if (pseg < orig_number_of_noL6_psegs && ( n_layers_processed != 6 )) {
1355  if(( Psegments_noL6[ pseg_noL6_pos ].size() > 2 )){
1356 
1357  // looks more exciting than it is. Here the weight is calculated. It is the difference in x of the last two and one but the last two hits,
1358  // divided by the distance of the corresponding hits. Please refer to twiki page XXXX or CMS Note YYY (and use layer_distance)
1359 
1360  weight_noL6_A[ pseg_noL6_pos ] += theWeight(
1361  (*(Psegments_noL6[ pseg_noL6_pos ].end()-1 ))->localPosition().x(),
1362  (*(Psegments_noL6[ pseg_noL6_pos ].end()-2 ))->localPosition().x(),
1363  (*(Psegments_noL6[ pseg_noL6_pos ].end()-3 ))->localPosition().x(),
1364  float((*(Psegments_noL6[ pseg_noL6_pos ].end()-1))->cscDetId().layer()),
1365  float((*(Psegments_noL6[ pseg_noL6_pos ].end()-2))->cscDetId().layer()),
1366  float((*(Psegments_noL6[ pseg_noL6_pos ].end()-3))->cscDetId().layer())
1367  );
1368 
1369  weight_noL6_B[ pseg_noL6_pos ] += theWeight(
1370  (*(Psegments_noL6[ pseg_noL6_pos ].end()-1 ))->localPosition().y(),
1371  (*(Psegments_noL6[ pseg_noL6_pos ].end()-2 ))->localPosition().y(),
1372  (*(Psegments_noL6[ pseg_noL6_pos ].end()-3 ))->localPosition().y(),
1373  float((*(Psegments_noL6[ pseg_noL6_pos ].end()-1))->cscDetId().layer()),
1374  float((*(Psegments_noL6[ pseg_noL6_pos ].end()-2))->cscDetId().layer()),
1375  float((*(Psegments_noL6[ pseg_noL6_pos ].end()-3))->cscDetId().layer())
1376  );
1377 
1378  //if we have picked up the last hit go looking for pseg with the lowest (and second lowest?) weight
1379 
1380  if(int(Psegments_noL6[ pseg_noL6_pos ].size()) == n_layers_occupied_tot -1 ) {
1381 
1382  curv_noL6_A[ pseg_noL6_pos ] += theWeight(
1383  (*(Psegments_noL6[ pseg_noL6_pos ].end()-1 ))->localPosition().x(),
1384  (*(Psegments_noL6[ pseg_noL6_pos ].end()-midlayer_pointer[n_layers_occupied_tot-2] ))->localPosition().x(),
1385  (*(Psegments_noL6[ pseg_noL6_pos ].end()-(n_layers_occupied_tot-1) ))->localPosition().x(),
1386  float((*(Psegments_noL6[ pseg_noL6_pos ].end()-1 ))->cscDetId().layer()),
1387  float((*(Psegments_noL6[ pseg_noL6_pos ].end()-midlayer_pointer[n_layers_occupied_tot-2] ))->cscDetId().layer()),
1388  float((*(Psegments_noL6[ pseg_noL6_pos ].end()-(n_layers_occupied_tot-1) ))->cscDetId().layer())
1389  );
1390 
1391  if (curv_noL6_A[ pseg_noL6_pos ] > curvePenaltyThreshold) weight_noL6_A[ pseg_noL6_pos ] = weight_noL6_A[ pseg_noL6_pos ] * curvePenalty;
1392 
1393  if (weight_noL6_B[ pseg_noL6_pos ] > a_yweightPenaltyThreshold[thestation][thering])
1394  weight_noL6_A[ pseg_noL6_pos ] = weight_noL6_A[ pseg_noL6_pos ] * yweightPenalty;
1395 
1396  if (weight_noL6_A[ pseg_noL6_pos ] < min_weight_noLx_A ) {
1397  min_weight_noLx_A = weight_noL6_A[ pseg_noL6_pos ];
1398  //best_weight_noLx_B = weight_noL6_B[ pseg_noL6_pos ];
1399  //best_curv_noLx_A = curv_noL6_A[ pseg_noL6_pos ];
1400  best_noLx_pseg = pseg_noL6_pos;
1401  best_Layer_noLx = 6;
1402  }
1403 
1404  }
1405 
1406  // alternative: fill map with weight and pseg (which is already ordered)? Seems a very good tool to go looking for segments from.
1407  // As I understand, the segments would be inserted according to their weight, so the list would "automatically" be sorted.
1408 
1409  }
1410  }
1411  }
1412 
1413  }
1414  }
1415  }
1416  }
1417 
1418  //************************************************************************;
1419  //*** End segment building *******************************************;
1420  //************************************************************************;
1421 
1422  // Important part! Here segment(s) are actually chosen. All the good segments
1423  // could be chosen or some (best) ones only (in order to save time).
1424 
1425  // Check if there is a segment with n-1 hits that has a signifcantly better
1426  // weight than the best n hit segment
1427 
1428  // IBL 070828: implicit assumption here is that there will always only be one segment per
1429  // cluster - if there are >1 we will need to find out which segment the alternative n-1 hit
1430  // protosegment belongs to!
1431 
1432 
1433  //float chosen_weight = min_weight_A;
1434  //float chosen_ywgt = best_weight_B;
1435  //float chosen_curv = best_curv_A;
1436  //int chosen_nlayers = n_layers_occupied_tot;
1437  int chosen_pseg = best_pseg;
1438  if (best_pseg<0) {
1439  return segmentInChamber;
1440  }
1443 
1444  float hit_drop_limit = -999999.999;
1445 
1446  // define different weight improvement requirements depending on how many layers are in the segment candidate
1447  switch ( n_layers_processed ) {
1448  case 1 :
1449  // do nothing;
1450  break;
1451  case 2 :
1452  // do nothing;
1453  break;
1454  case 3 :
1455  // do nothing;
1456  break;
1457  case 4 :
1458  hit_drop_limit = hitDropLimit6Hits * (1./2.) * hitDropLimit4Hits;
1459  if ((best_Layer_noLx < 1) || (best_Layer_noLx > 4)) {
1460  // std::cout<<"CSCSegAlgoST: For four layers, best_Layer_noLx = "<< best_Layer_noLx << std::endl;
1461  }
1462  if ((best_Layer_noLx == 2) || (best_Layer_noLx == 3)) hit_drop_limit = hit_drop_limit * (1./2.);
1463  break;
1464  case 5 :
1465  hit_drop_limit = hitDropLimit6Hits * (2./3.) * hitDropLimit5Hits;
1466  if ((best_Layer_noLx < 1) || (best_Layer_noLx > 5)) {
1467  // std::cout<<"CSCSegAlgoST: For five layers, best_Layer_noLx = "<< best_Layer_noLx << std::endl;
1468  }
1469  if ((best_Layer_noLx == 2) || (best_Layer_noLx == 4)) hit_drop_limit = hit_drop_limit * (1./2.);
1470  if (best_Layer_noLx == 3) hit_drop_limit = hit_drop_limit * (1./3.);
1471  break;
1472  case 6 :
1473  hit_drop_limit = hitDropLimit6Hits * (3./4.);
1474  if ((best_Layer_noLx < 1) || (best_Layer_noLx > 6)) {
1475  // std::cout<<"CSCSegAlgoST: For six layers, best_Layer_noLx = "<< best_Layer_noLx << std::endl;
1476  }
1477  if ((best_Layer_noLx == 2) || (best_Layer_noLx == 5)) hit_drop_limit = hit_drop_limit * (1./2.);
1478  if ((best_Layer_noLx == 3) || (best_Layer_noLx == 4)) hit_drop_limit = hit_drop_limit * (1./3.);
1479  break;
1480 
1481  default :
1482  // Fallback - should never occur.
1483  LogTrace("CSCSegment|CSC") << "[CSCSegAlgoST::buildSegments] Unexpected number of layers with hits - please inform CSC DPG.";
1484  hit_drop_limit = 0.1;
1485  }
1486 
1487  // choose the NoLx collection (the one that contains the best N-1 candidate)
1488  switch ( best_Layer_noLx ) {
1489  case 1 :
1490  Psegments_noLx.clear();
1492  weight_noLx_A.clear();
1494  break;
1495  case 2 :
1496  Psegments_noLx.clear();
1498  weight_noLx_A.clear();
1500  break;
1501  case 3 :
1502  Psegments_noLx.clear();
1504  weight_noLx_A.clear();
1506  break;
1507  case 4 :
1508  Psegments_noLx.clear();
1510  weight_noLx_A.clear();
1512  break;
1513  case 5 :
1514  Psegments_noLx.clear();
1516  weight_noLx_A.clear();
1518  break;
1519  case 6 :
1520  Psegments_noLx.clear();
1522  weight_noLx_A.clear();
1524  break;
1525 
1526  default :
1527  // Fallback - should occur only for preclusters with only 3 layers with hits.
1528  Psegments_noLx.clear();
1529  weight_noLx_A.clear();
1530  }
1531 
1532  if( min_weight_A > 0. ) {
1533  if ( min_weight_noLx_A/min_weight_A < hit_drop_limit ) {
1534  //chosen_weight = min_weight_noLx_A;
1535  //chosen_ywgt = best_weight_noLx_B;
1536  //chosen_curv = best_curv_noLx_A;
1537  //chosen_nlayers = n_layers_occupied_tot-1;
1538  chosen_pseg = best_noLx_pseg;
1539  chosen_Psegments.clear();
1540  chosen_weight_A.clear();
1543  }
1544  }
1545 
1546  if(onlyBestSegment) {
1547  ChooseSegments2a( chosen_Psegments, chosen_pseg );
1548  }
1549  else {
1551  }
1552 
1553  for(unsigned int iSegment=0; iSegment<GoodSegments.size();++iSegment){
1554  protoSegment = GoodSegments[iSegment];
1555  passCondNumber=false;
1556  passCondNumber_2 = false;
1557  protoChiUCorrection=1.0;
1558  doSlopesAndChi2();
1559  // Attempt to handle numerical instability of the fit;
1560  // Any segment with protoChi2/protoNDF>chi2Norm_3D_
1561  // considered as that one potentially suffering from
1562  // numerical instability in fit.
1563  if(correctCov_){
1564  // Call the fit with prefitting option;
1565  // First fit a straight line to X-Z coordinates
1566  // and calculate chi^2 (chiUZ in correctTheCovX(void)) for X-Z fit;
1567  // Scale up errors in X if chiUZ too big (default 20);
1568  // Refit XY-Z with the scaled up X errors
1570  passCondNumber = true;
1571  doSlopesAndChi2();
1572  }
1573  if(protoChiUCorrection<1.00005){
1574  LogTrace("CSCWeirdSegment") << "[CSCSegAlgoST::buildSegments] Segment ErrXX scaled and refit " << std::endl;
1576  // Call the fit with direct adjustment of condition number;
1577  // If the attempt to improve fit by scaling up X error fails
1578  // call the procedure to make the condition number of M compatible with
1579  // the precision of X and Y measurements;
1580  // Achieved by decreasing abs value of the Covariance
1581  LogTrace("CSCWeirdSegment") << "[CSCSegAlgoST::buildSegments] Segment ErrXY changed to match cond. number and refit " << std::endl;
1582  passCondNumber_2=true;
1583  doSlopesAndChi2();
1584  }
1585  }
1586  // Call the pre-pruning procedure;
1587  // If the attempt to improve fit by scaling up X error is successfull,
1588  // while scale factor for X errors is too big.
1589  // Prune the recHit inducing the biggest contribution into X-Z chi^2
1590  // and refit;
1592  (protoSegment.size()>3)){
1593  LogTrace("CSCWeirdSegment") << "[CSCSegAlgoST::buildSegments] Scale factor protoChiUCorrection too big, pre-Prune and refit " << std::endl;
1594  protoSegment.erase(protoSegment.begin()+(maxContrIndex),
1595  protoSegment.begin()+(maxContrIndex+1));
1596  doSlopesAndChi2();
1597  }
1598  }
1599 
1601  // calculate error matrix
1602  // AlgebraicSymMatrix protoErrors = calculateError();
1603  SMatrixSym4 protoErrors = calculateError();
1604  // but reorder components to match what's required by TrackingRecHit interface
1605  // i.e. slopes first, then positions
1606  AlgebraicSymMatrix temp2 = flipErrors( protoErrors ); //@@ TO SATISFY CSCSegment INTERFACE
1607 
1609 
1610  dumpSegment( temp );
1611 
1612  segmentInChamber.push_back(temp);
1613  }
1614  return segmentInChamber;
1615 }
double protoChiUCorrection
Allow to correct the error matrix.
Definition: CSCSegAlgoST.h:228
int i
Definition: DBlmapReader.cc:9
bool passCondNumber
The number to force the Covariance.
Definition: CSCSegAlgoST.h:242
void doSlopesAndChi2(void)
std::vector< ChamberHitContainer > Psegments_noL5
Definition: CSCSegAlgoST.h:158
std::vector< float > curv_noL2_A
Definition: CSCSegAlgoST.h:172
void dumpSegment(const CSCSegment &seg) const
CSCSegment showerSeg(const CSCChamber *aChamber, const ChamberHitContainer &rechits)
const CSCChamber * theChamber
Definition: CSCSegAlgoST.h:146
std::vector< float > weight_noL4_A
Definition: CSCSegAlgoST.h:166
std::vector< float > curv_noL6_A
Definition: CSCSegAlgoST.h:176
void ChooseSegments3(int best_seg)
std::vector< float > weight_noL3_B
Definition: CSCSegAlgoST.h:180
std::vector< ChamberHitContainer > Psegments_noL1
Definition: CSCSegAlgoST.h:154
std::vector< ChamberHitContainer > chosen_Psegments
Definition: CSCSegAlgoST.h:160
std::vector< ChamberHitContainer > Psegments
Definition: CSCSegAlgoST.h:152
ChamberHitContainer protoSegment
Definition: CSCSegAlgoST.h:187
LocalVector protoDirection
Definition: CSCSegAlgoST.h:193
std::vector< float > weight_noL3_A
Definition: CSCSegAlgoST.h:165
double hitDropLimit4Hits
Definition: CSCSegAlgoST.h:213
CSCSegAlgoShowering * showering_
Definition: CSCSegAlgoST.h:224
int nRecHits() const
Definition: CSCSegment.h:67
T sqrt(T t)
Definition: SSEVec.h:48
std::vector< ChamberHitContainer > Psegments_noLx
Definition: CSCSegAlgoST.h:153
double curvePenaltyThreshold
Definition: CSCSegAlgoST.h:222
std::vector< ChamberHitContainer > Psegments_noL4
Definition: CSCSegAlgoST.h:157
double protoNDF
Definition: CSCSegAlgoST.h:192
double hitDropLimit6Hits
Definition: CSCSegAlgoST.h:215
double protoChi2
Definition: CSCSegAlgoST.h:191
std::vector< float > weight_A
Definition: CSCSegAlgoST.h:161
std::vector< float > weight_noL1_B
Definition: CSCSegAlgoST.h:178
std::vector< float > curv_noL5_A
Definition: CSCSegAlgoST.h:175
std::vector< ChamberHitContainer > Psegments_noL6
Definition: CSCSegAlgoST.h:159
#define end
Definition: vmac.h:37
unsigned maxContrIndex
Chi^2 normalization for the initial fit.
Definition: CSCSegAlgoST.h:232
bool onlyBestSegment
Definition: CSCSegAlgoST.h:210
#define LogTrace(id)
std::vector< ChamberHitContainer > Psegments_noL2
Definition: CSCSegAlgoST.h:155
std::vector< float > weight_noL5_A
Definition: CSCSegAlgoST.h:167
bool passCondNumber_2
Passage the condition number calculations.
Definition: CSCSegAlgoST.h:243
std::vector< float > weight_noL1_A
Definition: CSCSegAlgoST.h:163
std::vector< float > curv_noL4_A
Definition: CSCSegAlgoST.h:174
std::vector< float > weight_noL2_A
Definition: CSCSegAlgoST.h:164
std::vector< float > chosen_weight_A
Definition: CSCSegAlgoST.h:169
Segments GoodSegments
Definition: CSCSegAlgoST.h:147
bool correctCov_
Correct the Error Matrix.
Definition: CSCSegAlgoST.h:227
int minHitsPerSegment
Definition: CSCSegAlgoST.h:199
ChamberHitContainer Psegments_hits
Definition: CSCSegAlgoST.h:150
std::vector< float > curv_noL1_A
Definition: CSCSegAlgoST.h:171
SMatrixSym4 calculateError(void) const
double theWeight(double coordinate_1, double coordinate_2, double coordinate_3, float layer_1, float layer_2, float layer_3)
Utility functions.
double curvePenalty
Definition: CSCSegAlgoST.h:223
std::vector< float > curv_A
Definition: CSCSegAlgoST.h:170
ROOT::Math::SMatrix< double, 4, 4, ROOT::Math::MatRepSym< double, 4 > > SMatrixSym4
Definition: CSCSegAlgoST.h:57
bool prePrun_
The index of the worst x RecHit in Chi^2-X method.
Definition: CSCSegAlgoST.h:233
double chi2() const
Chi2 of the segment fit.
Definition: CSCSegment.h:57
double yweightPenalty
Definition: CSCSegAlgoST.h:220
CLHEP::HepSymMatrix AlgebraicSymMatrix
std::vector< float > weight_noL5_B
Definition: CSCSegAlgoST.h:182
std::vector< float > weight_B
Definition: CSCSegAlgoST.h:177
float a_yweightPenaltyThreshold[5][5]
Definition: CSCSegAlgoST.h:217
void ChooseSegments2a(std::vector< ChamberHitContainer > &best_segments, int best_seg)
void fillLocalDirection(void)
int maxRecHitsInCluster
Definition: CSCSegAlgoST.h:204
Definition: DDAxes.h:10
std::vector< float > weight_noL6_A
Definition: CSCSegAlgoST.h:168
std::vector< float > weight_noL2_B
Definition: CSCSegAlgoST.h:179
double hitDropLimit5Hits
Definition: CSCSegAlgoST.h:214
std::vector< float > weight_noLx_A
Definition: CSCSegAlgoST.h:162
std::vector< float > curv_noL3_A
Definition: CSCSegAlgoST.h:173
std::vector< float > weight_noL6_B
Definition: CSCSegAlgoST.h:183
tuple size
Write out results.
AlgebraicSymMatrix flipErrors(const SMatrixSym4 &) const
ChamberHitContainer PAhits_onLayer[6]
Definition: CSCSegAlgoST.h:149
LocalPoint protoIntercept
Definition: CSCSegAlgoST.h:190
std::vector< float > weight_noL4_B
Definition: CSCSegAlgoST.h:181
std::vector< ChamberHitContainer > Psegments_noL3
Definition: CSCSegAlgoST.h:156
double chi2Norm_3D_
Chi^2 normalization for the corrected fit.
Definition: CSCSegAlgoST.h:231
double prePrunLimit_
Definition: CSCSegAlgoST.h:235
std::vector<CSCSegment> CSCSegAlgoST::buildSegments2 ( const ChamberHitContainer rechits)

Build track segments in this chamber (this is where the actual segment-building algorithm hides.)

CSCSegAlgoST::SMatrixSym4 CSCSegAlgoST::calculateError ( void  ) const
private

Definition at line 1984 of file CSCSegAlgoST.cc.

References HLT_25ns14e33_v1_cff::A, derivativeMatrix(), LogTrace, convertSQLiteXML::ok, query::result, weightMatrix(), and create_public_pileup_plots::weights.

Referenced by buildSegments(), and prune_bad_hits().

1984  {
1985 
1988  // LogTrace("CSCSegAlgoST") << "[CSCSegAlgoST::calculateError] weights matrix W: \n" << weights;
1989  // LogTrace("CSCSegAlgoST") << "[CSCSegAlgoST::calculateError] derivatives matrix A: \n" << A;
1990 
1991  // (AT W A)^-1
1992  // from http://www.phys.ufl.edu/~avery/fitting.html, part I
1993 
1994  bool ok;
1995  SMatrixSym4 result = ROOT::Math::SimilarityT(A, weights);
1996  // LogTrace("CSCSegAlgoST") << "[CSCSegAlgoST::calculateError] (AT W A): \n" << result;
1997  ok = result.Invert(); // inverts in place
1998  if ( !ok ) {
1999  LogTrace("CSCSegment|CSC") << "[CSCSegAlgoST::calculateError] Failed to invert matrix: \n" << result;
2000  // return ok;
2001  }
2002  // LogTrace("CSCSegAlgoST") << "[CSCSegAlgoST::calculateError] (AT W A)^-1: \n" << result;
2003  // blithely assuming the inverting never fails...
2004  return result;
2005 }
tuple result
Definition: query.py:137
SMatrix12by4 derivativeMatrix(void) const
#define LogTrace(id)
ROOT::Math::SMatrix< double, 12, 12, ROOT::Math::MatRepSym< double, 12 > > SMatrixSym12
Definition: CSCSegAlgoST.h:50
ROOT::Math::SMatrix< double, 4, 4, ROOT::Math::MatRepSym< double, 4 > > SMatrixSym4
Definition: CSCSegAlgoST.h:57
ROOT::Math::SMatrix< double, 12, 4 > SMatrix12by4
Definition: CSCSegAlgoST.h:53
SMatrixSym12 weightMatrix(void) const
std::vector< std::vector< const CSCRecHit2D * > > CSCSegAlgoST::chainHits ( const CSCChamber aChamber,
const ChamberHitContainer rechits 
)

Definition at line 517 of file CSCSegAlgoST.cc.

References begin, CSCChamberSpecs::chamberTypeName(), end, CSCChamberSpecs::gangedStrips(), i, isGoodToMerge(), CSCChamber::specs(), and groupFilesInBlocks::temp.

Referenced by run().

517  {
518 
519  std::vector<ChamberHitContainer> rechits_chains; // this is a collection of groups of rechits
520 
521 
522  std::vector<const CSCRecHit2D*> temp;
523 
524  std::vector< ChamberHitContainer > seeds;
525 
526  std::vector <bool> usedCluster;
527 
528  // split rechits into subvectors and return vector of vectors:
529  // Loop over rechits
530  // Create one seed per hit
531  //std::cout<<" rechits.size() = "<<rechits.size()<<std::endl;
532  for(unsigned int i = 0; i < rechits.size(); ++i) {
533  temp.clear();
534  temp.push_back(rechits[i]);
535  seeds.push_back(temp);
536  usedCluster.push_back(false);
537  }
538  //@@ Only ME1/1A can have ganged strips so no need to test name
539  bool gangedME11a = false;
540  if ( ("ME1/a" == aChamber->specs()->chamberTypeName()) && aChamber->specs()->gangedStrips() ){
541  // if ( aChamber->specs()->gangedStrips() ){
542  gangedME11a = true;
543  }
544  // merge chains that are too close ("touch" each other)
545  for(size_t NNN = 0; NNN < seeds.size(); ++NNN) {
546  for(size_t MMM = NNN+1; MMM < seeds.size(); ++MMM) {
547  if(usedCluster[MMM] || usedCluster[NNN]){
548  continue;
549  }
550  // all is in the way we define "good";
551  // try not to "cluster" the hits but to "chain" them;
552  // it does the clustering but also does a better job
553  // for inclined tracks (not clustering them together;
554  // crossed tracks would be still clustered together)
555  // 22.12.09: In fact it is not much more different
556  // than the "clustering", we just introduce another
557  // variable in the game - Z. And it makes sense
558  // to re-introduce Y (or actually wire group mumber)
559  // in a similar way as for the strip number - see
560  // the code below.
561  bool goodToMerge = isGoodToMerge(gangedME11a, seeds[NNN], seeds[MMM]);
562  if(goodToMerge){
563  // merge chains!
564  // merge by adding seed NNN to seed MMM and erasing seed NNN
565 
566  // add seed NNN to MMM (lower to larger number)
567  seeds[MMM].insert(seeds[MMM].end(),seeds[NNN].begin(),seeds[NNN].end());
568 
569  // mark seed NNN as used
570  usedCluster[NNN] = true;
571  // we have merged a seed (NNN) to the highter seed (MMM) - need to contimue to
572  // next seed (NNN+1)
573  break;
574  }
575 
576  }
577  }
578 
579  // hand over the final seeds to the output
580  // would be more elegant if we could do the above step with
581  // erasing the merged ones, rather than the
582 
583  for(size_t NNN = 0; NNN < seeds.size(); ++NNN) {
584  if(usedCluster[NNN]) continue; //skip seeds that have been marked as used up in merging
585  rechits_chains.push_back(seeds[NNN]);
586  }
587 
588  //***************************************************************
589 
590  return rechits_chains;
591 }
int i
Definition: DBlmapReader.cc:9
bool isGoodToMerge(bool isME11a, ChamberHitContainer &newChain, ChamberHitContainer &oldChain)
std::string chamberTypeName() const
const CSCChamberSpecs * specs() const
Definition: CSCChamber.h:42
#define end
Definition: vmac.h:37
bool gangedStrips() const
#define begin
Definition: vmac.h:30
const CSCChamber* CSCSegAlgoST::chamber ( ) const
inlineprivate

Definition at line 142 of file CSCSegAlgoST.h.

References theChamber.

Referenced by dumpSegment(), and geometryXMLparser.CSCAlignable::index().

142 {return theChamber;}
const CSCChamber * theChamber
Definition: CSCSegAlgoST.h:146
void CSCSegAlgoST::ChooseSegments ( void  )
private
void CSCSegAlgoST::ChooseSegments2 ( int  best_seg)
private

Definition at line 1675 of file CSCSegAlgoST.cc.

References GoodSegments, LogTrace, Psegments, findQualityFiles::size, and weight_A.

1675  {
1676  // std::vector <int> CommonHits(6); // nice concept :)
1677  std::vector <unsigned int> BadCandidate;
1678  int SumCommonHits =0;
1679  GoodSegments.clear();
1680  BadCandidate.clear();
1681  for(unsigned int iCand=0;iCand<Psegments.size();++iCand) {
1682  // skip here if segment was marked bad
1683  for(unsigned int iiCand=iCand+1;iiCand<Psegments.size();++iiCand){
1684  // skip here too if segment was marked bad
1685  SumCommonHits =0;
1686  if( Psegments[iCand].size() != Psegments[iiCand].size() ) {
1687  LogTrace("CSCSegment|CSC") << "[CSCSegAlgoST::ChooseSegments2] ALARM!! Should not happen - please inform CSC DPG";
1688  }
1689  else {
1690  for( int ihits = 0; ihits < int(Psegments[iCand].size()); ++ihits ) { // iCand and iiCand NEED to have same nr of hits! (alsways have by construction)
1691  if( Psegments[iCand][ihits] == Psegments[iiCand][ihits]) {
1692  ++SumCommonHits;
1693  }
1694  }
1695  }
1696  if(SumCommonHits>1) {
1697  if( weight_A[iCand]>weight_A[iiCand] ) { // use weight_A here
1698  BadCandidate.push_back(iCand);
1699  // rather mark segment bad by an array which is in sync with protosegments!! e.g. set weight = weight*1000 or have an addidional array or set it to weight *= -1
1700  }
1701  else{
1702  BadCandidate.push_back(iiCand);
1703  // rather mark segment bad by an array which is in sync with protosegments!! e.g. set weight = weight*1000 or have an addidional array or set it to weight *= -1
1704  }
1705  }
1706  }
1707  }
1708  bool discard;
1709  for(unsigned int isegm=0;isegm<Psegments.size();++isegm) {
1710  // For best results another iteration/comparison over Psegments
1711  //should be applied here... It would make the program much slower.
1712  discard = false;
1713  for(unsigned int ibad=0;ibad<BadCandidate.size();++ibad) {
1714  // can save this loop if we used an array in sync with Psegments!!!!
1715  if(isegm == BadCandidate[ibad]) {
1716  discard = true;
1717  }
1718  }
1719  if(!discard) {
1720  GoodSegments.push_back( Psegments[isegm] );
1721  }
1722  }
1723 }
std::vector< ChamberHitContainer > Psegments
Definition: CSCSegAlgoST.h:152
std::vector< float > weight_A
Definition: CSCSegAlgoST.h:161
#define LogTrace(id)
Segments GoodSegments
Definition: CSCSegAlgoST.h:147
tuple size
Write out results.
void CSCSegAlgoST::ChooseSegments2a ( std::vector< ChamberHitContainer > &  best_segments,
int  best_seg 
)
private

Definition at line 1617 of file CSCSegAlgoST.cc.

References GoodSegments.

Referenced by buildSegments().

1617  {
1618  // just return best segment
1619  GoodSegments.clear();
1620  GoodSegments.push_back( chosen_segments[chosen_seg] );
1621 }
Segments GoodSegments
Definition: CSCSegAlgoST.h:147
void CSCSegAlgoST::ChooseSegments3 ( int  best_seg)
private

Referenced by buildSegments().

void CSCSegAlgoST::ChooseSegments3 ( std::vector< ChamberHitContainer > &  best_segments,
std::vector< float > &  best_weight,
int  best_seg 
)
private

Definition at line 1623 of file CSCSegAlgoST.cc.

References GoodSegments, and findQualityFiles::size.

1623  {
1624 
1625  int SumCommonHits = 0;
1626  GoodSegments.clear();
1627  int nr_remaining_candidates;
1628  unsigned int nr_of_segment_candidates;
1629 
1630  nr_remaining_candidates = nr_of_segment_candidates = chosen_segments.size();
1631 
1632  // always select and return best protosegment:
1633  GoodSegments.push_back( chosen_segments[ chosen_seg ] );
1634 
1635  float chosen_weight_temp = 999999.;
1636  int chosen_seg_temp = -1;
1637 
1638  // try to find further segment candidates:
1639  while( nr_remaining_candidates > 0 ) {
1640 
1641  for(unsigned int iCand=0; iCand < nr_of_segment_candidates; ++iCand) {
1642  //only compare current best to psegs that have not been marked bad:
1643  if( chosen_weight[iCand] < 0. ) continue;
1644  SumCommonHits = 0;
1645 
1646  for( int ihits = 0; ihits < int(chosen_segments[iCand].size()); ++ihits ) { // iCand and iiCand NEED to have same nr of hits! (always have by construction)
1647  if( chosen_segments[iCand][ihits] == chosen_segments[chosen_seg][ihits]) {
1648  ++SumCommonHits;
1649  }
1650  }
1651 
1652  //mark a pseg bad:
1653  if(SumCommonHits>1) { // needs to be a card; should be investigated first
1654  chosen_weight[iCand] = -1.;
1655  nr_remaining_candidates -= 1;
1656  }
1657  else {
1658  // save the protosegment with the smallest weight
1659  if( chosen_weight[ iCand ] < chosen_weight_temp ) {
1660  chosen_weight_temp = chosen_weight[ iCand ];
1661  chosen_seg_temp = iCand ;
1662  }
1663  }
1664  }
1665 
1666  if( chosen_seg_temp > -1 ) GoodSegments.push_back( chosen_segments[ chosen_seg_temp ] );
1667 
1668  chosen_seg = chosen_seg_temp;
1669  // re-initialze temporary best parameters
1670  chosen_weight_temp = 999999;
1671  chosen_seg_temp = -1;
1672  }
1673 }
Segments GoodSegments
Definition: CSCSegAlgoST.h:147
tuple size
Write out results.
std::vector< std::vector< const CSCRecHit2D * > > CSCSegAlgoST::clusterHits ( const CSCChamber aChamber,
const ChamberHitContainer rechits 
)

Build groups of rechits that are separated in x and y to save time on the segment finding

Definition at line 401 of file CSCSegAlgoST.cc.

References begin, dXclusBoxMax, dYclusBoxMax, end, i, LogTrace, findQualityFiles::size, groupFilesInBlocks::temp, theChamber, x, and detailsBasic3DVector::y.

Referenced by run().

401  {
402  theChamber = aChamber;
403 
404  std::vector<ChamberHitContainer> rechits_clusters; // this is a collection of groups of rechits
405  // const float dXclus_box_cut = 4.; // seems to work reasonably 070116
406  // const float dYclus_box_cut = 8.; // seems to work reasonably 070116
407 
408  //float dXclus = 0.0;
409  //float dYclus = 0.0;
410  float dXclus_box = 0.0;
411  float dYclus_box = 0.0;
412 
413  std::vector<const CSCRecHit2D*> temp;
414 
415  std::vector< ChamberHitContainer > seeds;
416 
417  std::vector<float> running_meanX;
418  std::vector<float> running_meanY;
419 
420  std::vector<float> seed_minX;
421  std::vector<float> seed_maxX;
422  std::vector<float> seed_minY;
423  std::vector<float> seed_maxY;
424 
425  //std::cout<<"*************************************************************"<<std::endl;
426  //std::cout<<"Called clusterHits in Chamber "<< theChamber->specs()->chamberTypeName()<<std::endl;
427  //std::cout<<"*************************************************************"<<std::endl;
428 
429  // split rechits into subvectors and return vector of vectors:
430  // Loop over rechits
431  // Create one seed per hit
432  for(unsigned int i = 0; i < rechits.size(); ++i) {
433 
434  temp.clear();
435 
436  temp.push_back(rechits[i]);
437 
438  seeds.push_back(temp);
439 
440  // First added hit in seed defines the mean to which the next hit is compared
441  // for this seed.
442 
443  running_meanX.push_back( rechits[i]->localPosition().x() );
444  running_meanY.push_back( rechits[i]->localPosition().y() );
445 
446  // set min/max X and Y for box containing the hits in the precluster:
447  seed_minX.push_back( rechits[i]->localPosition().x() );
448  seed_maxX.push_back( rechits[i]->localPosition().x() );
449  seed_minY.push_back( rechits[i]->localPosition().y() );
450  seed_maxY.push_back( rechits[i]->localPosition().y() );
451  }
452 
453  // merge clusters that are too close
454  // measure distance between final "running mean"
455  for(size_t NNN = 0; NNN < seeds.size(); ++NNN) {
456 
457  for(size_t MMM = NNN+1; MMM < seeds.size(); ++MMM) {
458  if(running_meanX[MMM] == 999999. || running_meanX[NNN] == 999999. ) {
459  LogTrace("CSCSegment|CSC") << "[CSCSegAlgoST::clusterHits] ALARM! Skipping used seeds, this should not happen - inform CSC DPG";
460  // std::cout<<"We should never see this line now!!!"<<std::endl;
461  continue; //skip seeds that have been used
462  }
463 
464  // calculate cut criteria for simple running mean distance cut:
465  //dXclus = fabs(running_meanX[NNN] - running_meanX[MMM]);
466  //dYclus = fabs(running_meanY[NNN] - running_meanY[MMM]);
467 
468  // calculate minmal distance between precluster boxes containing the hits:
469  if ( running_meanX[NNN] > running_meanX[MMM] ) dXclus_box = seed_minX[NNN] - seed_maxX[MMM];
470  else dXclus_box = seed_minX[MMM] - seed_maxX[NNN];
471  if ( running_meanY[NNN] > running_meanY[MMM] ) dYclus_box = seed_minY[NNN] - seed_maxY[MMM];
472  else dYclus_box = seed_minY[MMM] - seed_maxY[NNN];
473 
474 
475  if( dXclus_box < dXclusBoxMax && dYclus_box < dYclusBoxMax ) {
476  // merge clusters!
477  // merge by adding seed NNN to seed MMM and erasing seed NNN
478 
479  // calculate running mean for the merged seed:
480  running_meanX[MMM] = (running_meanX[NNN]*seeds[NNN].size() + running_meanX[MMM]*seeds[MMM].size()) / (seeds[NNN].size()+seeds[MMM].size());
481  running_meanY[MMM] = (running_meanY[NNN]*seeds[NNN].size() + running_meanY[MMM]*seeds[MMM].size()) / (seeds[NNN].size()+seeds[MMM].size());
482 
483  // update min/max X and Y for box containing the hits in the merged cluster:
484  if ( seed_minX[NNN] <= seed_minX[MMM] ) seed_minX[MMM] = seed_minX[NNN];
485  if ( seed_maxX[NNN] > seed_maxX[MMM] ) seed_maxX[MMM] = seed_maxX[NNN];
486  if ( seed_minY[NNN] <= seed_minY[MMM] ) seed_minY[MMM] = seed_minY[NNN];
487  if ( seed_maxY[NNN] > seed_maxY[MMM] ) seed_maxY[MMM] = seed_maxY[NNN];
488 
489  // add seed NNN to MMM (lower to larger number)
490  seeds[MMM].insert(seeds[MMM].end(),seeds[NNN].begin(),seeds[NNN].end());
491 
492  // mark seed NNN as used (at the moment just set running mean to 999999.)
493  running_meanX[NNN] = 999999.;
494  running_meanY[NNN] = 999999.;
495  // we have merged a seed (NNN) to the highter seed (MMM) - need to contimue to
496  // next seed (NNN+1)
497  break;
498  }
499 
500  }
501  }
502 
503  // hand over the final seeds to the output
504  // would be more elegant if we could do the above step with
505  // erasing the merged ones, rather than the
506  for(size_t NNN = 0; NNN < seeds.size(); ++NNN) {
507  if(running_meanX[NNN] == 999999.) continue; //skip seeds that have been marked as used up in merging
508  rechits_clusters.push_back(seeds[NNN]);
509  }
510 
511  //***************************************************************
512 
513  return rechits_clusters;
514 }
int i
Definition: DBlmapReader.cc:9
double dXclusBoxMax
Definition: CSCSegAlgoST.h:202
const CSCChamber * theChamber
Definition: CSCSegAlgoST.h:146
#define end
Definition: vmac.h:37
#define LogTrace(id)
double dYclusBoxMax
Definition: CSCSegAlgoST.h:203
#define begin
Definition: vmac.h:30
Definition: DDAxes.h:10
tuple size
Write out results.
void CSCSegAlgoST::correctTheCovMatrix ( SMatrixSym2 IC)
private

Definition at line 2131 of file CSCSegAlgoST.cc.

References condSeed1_, condSeed2_, covAnyNumber_, covToAnyNumber_, covToAnyNumberAll_, and mathSSE::sqrt().

Referenced by fillChiSquared(), and fitSlopes().

2131  {
2132  //double condNumberCorr1=0.0;
2133  double condNumberCorr2=0.0;
2134  double detCov=0.0;
2135  double diag1=0.0;
2136  double diag2=0.0;
2137  double IC_01_corr=0.0;
2138  double IC_00_corr=0.0;
2139  if(!covToAnyNumberAll_){
2140  //condNumberCorr1=condSeed1_*IC(1,1);
2141  condNumberCorr2=condSeed2_*IC(1,1);
2142  diag1=IC(0,0)*IC(1,1);
2143  diag2=IC(0,1)*IC(0,1);
2144  detCov=fabs(diag1-diag2);
2145  if((diag1<condNumberCorr2)&&(diag2<condNumberCorr2)){
2146  if(covToAnyNumber_)
2147  IC(0,1)=covAnyNumber_;
2148  else{
2149  IC_00_corr=condSeed1_+fabs(IC(0,1))/IC(1,1);
2150  IC(0,0)=IC_00_corr;
2151  }
2152  }
2153 
2154  if(((detCov<condNumberCorr2)&&(diag1>condNumberCorr2))||
2155  ((diag2>condNumberCorr2)&&(detCov<condNumberCorr2)
2156  )){
2157  if(covToAnyNumber_)
2158  IC(0,1)=covAnyNumber_;
2159  else{
2160  IC_01_corr=sqrt(fabs(diag1-condNumberCorr2));
2161  if(IC(0,1)<0)
2162  IC(0,1)=(-1)*IC_01_corr;
2163  else
2164  IC(0,1)=IC_01_corr;
2165  }
2166  }
2167  }
2168  else{
2169  IC(0,1)=covAnyNumber_;
2170  }
2171  IC(1,0) = IC(0,1); //@@ ADDED TO MAINTAIN SYMMETRIC
2172 }
double condSeed1_
The upper limit of protoChiUCorrection to apply prePrun.
Definition: CSCSegAlgoST.h:238
double covAnyNumber_
Allow to use any number for covariance for all RecHits.
Definition: CSCSegAlgoST.h:241
T sqrt(T t)
Definition: SSEVec.h:48
bool covToAnyNumberAll_
Allow to use any number for covariance (by hand)
Definition: CSCSegAlgoST.h:240
bool covToAnyNumber_
The correction parameters.
Definition: CSCSegAlgoST.h:239
double condSeed2_
Definition: CSCSegAlgoST.h:238
void CSCSegAlgoST::correctTheCovX ( void  )
private

Vectors of coordinates

Make a one dimensional fit in U-Z plane (i.e. chamber local x-z) U=U0+UZ*Z fit parameters

Calculate the fit line trace Calculate one dimentional chi^2 and normilize the errors if needed

Max contribution in case of big correction factor

Definition at line 2056 of file CSCSegAlgoST.cc.

References chi2Norm_2D_, CSCRecHit2D::cscDetId(), e_Cxx, i, CSCChamber::layer(), CSCDetId::layer(), CSCRecHit2D::localPosition(), CSCRecHit2D::localPositionError(), maxContrIndex, funct::pow(), prePrunLimit_, protoChiUCorrection, protoSegment, mathSSE::sqrt(), theChamber, GeomDet::toGlobal(), GeomDet::toLocal(), findQualityFiles::v, PV3DBase< T, PVType, FrameType >::x(), LocalError::xx(), PV3DBase< T, PVType, FrameType >::y(), detailsBasic3DVector::z, and PV3DBase< T, PVType, FrameType >::z().

Referenced by fitSlopes().

2056  {
2057  std::vector<double> uu, vv, zz;
2058  //std::vector<double> e_Cxx;
2059  e_Cxx.clear();
2060  double sum_U_err=0.0;
2061  double sum_Z_U_err=0.0;
2062  double sum_Z2_U_err=0.0;
2063  double sum_U_U_err=0.0;
2064  double sum_UZ_U_err=0.0;
2065  std::vector<double> chiUZind;
2066  std::vector<double>::iterator chiContribution;
2067  double chiUZ=0.0;
2068  ChamberHitContainer::const_iterator ih = protoSegment.begin();
2069  for (ih = protoSegment.begin(); ih != protoSegment.end(); ++ih) {
2070  const CSCRecHit2D& hit = (**ih);
2071  e_Cxx.push_back(hit.localPositionError().xx());
2072 
2073  const CSCLayer* layer = theChamber->layer(hit.cscDetId().layer());
2074  GlobalPoint gp = layer->toGlobal(hit.localPosition());
2075  LocalPoint lp = theChamber->toLocal(gp);
2076  // Local position of hit w.r.t. chamber
2077  double u = lp.x();
2078  double v = lp.y();
2079  double z = lp.z();
2080  uu.push_back(u);
2081  vv.push_back(v);
2082  zz.push_back(z);
2083  // Prepare the sums for the standard linear fit
2084  sum_U_err += 1./e_Cxx.back();
2085  sum_Z_U_err += z/e_Cxx.back();
2086  sum_Z2_U_err += (z*z)/e_Cxx.back();
2087  sum_U_U_err += u/e_Cxx.back();
2088  sum_UZ_U_err += (u*z)/e_Cxx.back();
2089  }
2090 
2093 
2094  double denom=sum_U_err*sum_Z2_U_err-pow(sum_Z_U_err,2);
2095  double U0=(sum_Z2_U_err*sum_U_U_err-sum_Z_U_err*sum_UZ_U_err)/denom;
2096  double UZ=(sum_U_err*sum_UZ_U_err-sum_Z_U_err*sum_U_U_err)/denom;
2097 
2100 
2101  for(unsigned i=0; i<uu.size(); ++i){
2102  double uMean = U0+UZ*zz[i];
2103  chiUZind.push_back((pow((uMean-uu[i]),2))/e_Cxx[i]);
2104  chiUZ += (pow((uMean-uu[i]),2))/e_Cxx[i];
2105  }
2106  chiUZ = chiUZ/(uu.size()-2);
2107 
2108  if(chiUZ>=chi2Norm_2D_){
2110  for(unsigned i=0; i<uu.size(); ++i)
2112  }
2113 
2115 
2117  chiContribution=max_element(chiUZind.begin(),chiUZind.end());
2118  maxContrIndex = chiContribution - chiUZind.begin();
2119  /*
2120  for(unsigned i=0; i<chiUZind.size();++i){
2121  if(*chiContribution==chiUZind[i]){
2122  maxContrIndex=i;
2123  }
2124  }
2125  */
2126  }
2127  //
2128  //return e_Cxx;
2129 }
double protoChiUCorrection
Allow to correct the error matrix.
Definition: CSCSegAlgoST.h:228
int i
Definition: DBlmapReader.cc:9
float xx() const
Definition: LocalError.h:24
CSCDetId cscDetId() const
Definition: CSCRecHit2D.h:52
const CSCChamber * theChamber
Definition: CSCSegAlgoST.h:146
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:52
T y() const
Definition: PV3DBase.h:63
LocalPoint toLocal(const GlobalPoint &gp) const
Conversion to the R.F. of the GeomDet.
Definition: GeomDet.h:67
ChamberHitContainer protoSegment
Definition: CSCSegAlgoST.h:187
int layer() const
Definition: CSCDetId.h:74
float float float z
LocalError localPositionError() const
Definition: CSCRecHit2D.h:51
T sqrt(T t)
Definition: SSEVec.h:48
T z() const
Definition: PV3DBase.h:64
const CSCLayer * layer(CSCDetId id) const
Return the layer corresponding to the given id.
Definition: CSCChamber.cc:39
double chi2Norm_2D_
Definition: CSCSegAlgoST.h:230
unsigned maxContrIndex
Chi^2 normalization for the initial fit.
Definition: CSCSegAlgoST.h:232
std::vector< double > e_Cxx
Definition: CSCSegAlgoST.h:229
LocalPoint localPosition() const
Definition: CSCRecHit2D.h:50
T x() const
Definition: PV3DBase.h:62
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
double prePrunLimit_
Definition: CSCSegAlgoST.h:235
CSCSegAlgoST::SMatrix12by4 CSCSegAlgoST::derivativeMatrix ( void  ) const
private

Definition at line 1954 of file CSCSegAlgoST.cc.

References CSCRecHit2D::cscDetId(), CSCChamber::layer(), CSCDetId::layer(), CSCRecHit2D::localPosition(), makeMuonMisalignmentScenario::matrix, protoSegment, theChamber, GeomDet::toGlobal(), GeomDet::toLocal(), detailsBasic3DVector::z, and PV3DBase< T, PVType, FrameType >::z().

Referenced by calculateError().

1954  {
1955 
1956  ChamberHitContainer::const_iterator it;
1957 
1958  SMatrix12by4 matrix; // 12x4, init to 0
1959  int row = 0;
1960 
1961  for(it = protoSegment.begin(); it != protoSegment.end(); ++it) {
1962 
1963  const CSCRecHit2D& hit = (**it);
1964  const CSCLayer* layer = theChamber->layer(hit.cscDetId().layer());
1965  GlobalPoint gp = layer->toGlobal(hit.localPosition());
1966  LocalPoint lp = theChamber->toLocal(gp);
1967  float z = lp.z();
1968 
1969  matrix(row, 0) = 1.;
1970  matrix(row, 2) = z;
1971  ++row;
1972  matrix(row, 1) = 1.;
1973  matrix(row, 3) = z;
1974  ++row;
1975  }
1976  return matrix;
1977 }
CSCDetId cscDetId() const
Definition: CSCRecHit2D.h:52
const CSCChamber * theChamber
Definition: CSCSegAlgoST.h:146
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:52
LocalPoint toLocal(const GlobalPoint &gp) const
Conversion to the R.F. of the GeomDet.
Definition: GeomDet.h:67
ChamberHitContainer protoSegment
Definition: CSCSegAlgoST.h:187
int layer() const
Definition: CSCDetId.h:74
float float float z
T z() const
Definition: PV3DBase.h:64
const CSCLayer * layer(CSCDetId id) const
Return the layer corresponding to the given id.
Definition: CSCChamber.cc:39
ROOT::Math::SMatrix< double, 12, 4 > SMatrix12by4
Definition: CSCSegAlgoST.h:53
LocalPoint localPosition() const
Definition: CSCRecHit2D.h:50
void CSCSegAlgoST::doSlopesAndChi2 ( void  )
private

Definition at line 1728 of file CSCSegAlgoST.cc.

References fillChiSquared(), and fitSlopes().

Referenced by buildSegments(), and prune_bad_hits().

1728  {
1729  fitSlopes();
1730  fillChiSquared();
1731 }
void fitSlopes(void)
void fillChiSquared(void)
void CSCSegAlgoST::dumpSegment ( const CSCSegment seg) const
private

Definition at line 2201 of file CSCSegAlgoST.cc.

References chamber(), CSCSegment::chi2(), CSCSegment::degreesOfFreedom(), CSCChamber::id(), CSCSegment::localDirection(), CSCSegment::localDirectionError(), CSCSegment::localPosition(), CSCSegment::localPositionError(), LogTrace, CSCSegment::parametersError(), and CSCSegment::specificRecHits().

Referenced by buildSegments().

2201  {
2202  LogTrace("CSCSegment") << "CSCSegment in " << chamber()->id()
2203  << "\nlocal position = " << seg.localPosition()
2204  << "\nerror = " << seg.localPositionError()
2205  << "\nlocal direction = " << seg.localDirection()
2206  << "\nerror =" << seg.localDirectionError()
2207  << "\ncovariance matrix"
2208  << seg.parametersError()
2209  << "chi2/ndf = " << seg.chi2() << "/" << seg.degreesOfFreedom()
2210  << "\n#rechits = " << seg.specificRecHits().size();
2211 }
const CSCChamber * chamber() const
Definition: CSCSegAlgoST.h:142
CSCDetId id() const
Get the (concrete) DetId.
Definition: CSCChamber.h:37
LocalError localPositionError() const
Definition: CSCSegment.cc:47
virtual int degreesOfFreedom() const
Degrees of freedom of the segment fit.
Definition: CSCSegment.h:61
LocalPoint localPosition() const
Definition: CSCSegment.h:38
LocalVector localDirection() const
Local direction.
Definition: CSCSegment.h:41
const std::vector< CSCRecHit2D > & specificRecHits() const
Definition: CSCSegment.h:65
#define LogTrace(id)
AlgebraicSymMatrix parametersError() const
Covariance matrix of parameters()
Definition: CSCSegment.h:48
double chi2() const
Chi2 of the segment fit.
Definition: CSCSegment.h:57
LocalError localDirectionError() const
Error on the local direction.
Definition: CSCSegment.cc:51
void CSCSegAlgoST::fillChiSquared ( void  )
private

Correct the cov matrix

Definition at line 1834 of file CSCSegAlgoST.cc.

References correctTheCovMatrix(), CSCRecHit2D::cscDetId(), e_Cxx, CSCChamber::layer(), CSCDetId::layer(), CSCRecHit2D::localPosition(), CSCRecHit2D::localPositionError(), LogTrace, convertSQLiteXML::ok, passCondNumber, passCondNumber_2, protoChi2, protoIntercept, protoNDF, protoSegment, protoSlope_u, protoSlope_v, theChamber, GeomDet::toGlobal(), GeomDet::toLocal(), findQualityFiles::v, PV3DBase< T, PVType, FrameType >::x(), LocalError::xx(), LocalError::xy(), PV3DBase< T, PVType, FrameType >::y(), LocalError::yy(), detailsBasic3DVector::z, and PV3DBase< T, PVType, FrameType >::z().

Referenced by doSlopesAndChi2().

1834  {
1835 
1836  double chsq = 0.;
1837 
1838  ChamberHitContainer::const_iterator ih;
1839  for (ih = protoSegment.begin(); ih != protoSegment.end(); ++ih) {
1840 
1841  const CSCRecHit2D& hit = (**ih);
1842  const CSCLayer* layer = theChamber->layer(hit.cscDetId().layer());
1843  GlobalPoint gp = layer->toGlobal(hit.localPosition());
1844  LocalPoint lp = theChamber->toLocal(gp);
1845 
1846  double u = lp.x();
1847  double v = lp.y();
1848  double z = lp.z();
1849 
1850  double du = protoIntercept.x() + protoSlope_u * z - u;
1851  double dv = protoIntercept.y() + protoSlope_v * z - v;
1852 
1853  // LogTrace("CSCSegAlgoST") << "[CSCSegAlgoST::fillChiSquared] u, v, z = " << u << ", " << v << ", " << z;
1854 
1855  SMatrixSym2 IC; // 2x2, init to 0
1856 
1858  IC(0,0) = e_Cxx.at(ih-protoSegment.begin());
1859  }
1860  else{
1861  IC(0,0) = hit.localPositionError().xx();
1862  }
1863  // IC(0,1) = hit.localPositionError().xy();
1864  IC(1,0) = hit.localPositionError().xy();
1865  IC(1,1) = hit.localPositionError().yy();
1866  // IC(1,0) = IC(0,1);
1867 
1868  // LogTrace("CSCSegAlgoST") << "[CSCSegAlgoST::fillChiSquared] IC before = \n" << IC;
1869 
1871  if(passCondNumber_2){
1872  correctTheCovMatrix(IC);
1873  }
1874 
1875  // Invert covariance matrix
1876  bool ok = IC.Invert();
1877  if (!ok ){
1878  LogTrace("CSCSegment|CSC") << "[CSCSegAlgoST::fillChiSquared] Failed to invert covariance matrix: \n" << IC;
1879  // return ok;
1880  }
1881  // LogTrace("CSCSegAlgoST") << "[CSCSegAlgoST::fillChiSquared] IC after = \n" << IC;
1882  chsq += du*du*IC(0,0) + 2.*du*dv*IC(0,1) + dv*dv*IC(1,1);
1883  }
1884  protoChi2 = chsq;
1885  protoNDF = 2.*protoSegment.size() - 4;
1886 
1887  // LogTrace("CSCSegAlgoST") << "[CSCSegAlgoST::fillChiSquared] chi2 = " << protoChi2 << "/" << protoNDF << " dof";
1888 
1889 }
float xx() const
Definition: LocalError.h:24
CSCDetId cscDetId() const
Definition: CSCRecHit2D.h:52
bool passCondNumber
The number to force the Covariance.
Definition: CSCSegAlgoST.h:242
const CSCChamber * theChamber
Definition: CSCSegAlgoST.h:146
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:52
T y() const
Definition: PV3DBase.h:63
float protoSlope_v
Definition: CSCSegAlgoST.h:189
LocalPoint toLocal(const GlobalPoint &gp) const
Conversion to the R.F. of the GeomDet.
Definition: GeomDet.h:67
void correctTheCovMatrix(SMatrixSym2 &IC)
ChamberHitContainer protoSegment
Definition: CSCSegAlgoST.h:187
int layer() const
Definition: CSCDetId.h:74
float protoSlope_u
Definition: CSCSegAlgoST.h:188
float float float z
float xy() const
Definition: LocalError.h:25
LocalError localPositionError() const
Definition: CSCRecHit2D.h:51
float yy() const
Definition: LocalError.h:26
T z() const
Definition: PV3DBase.h:64
double protoNDF
Definition: CSCSegAlgoST.h:192
double protoChi2
Definition: CSCSegAlgoST.h:191
const CSCLayer * layer(CSCDetId id) const
Return the layer corresponding to the given id.
Definition: CSCChamber.cc:39
#define LogTrace(id)
bool passCondNumber_2
Passage the condition number calculations.
Definition: CSCSegAlgoST.h:243
std::vector< double > e_Cxx
Definition: CSCSegAlgoST.h:229
ROOT::Math::SMatrix< double, 2, 2, ROOT::Math::MatRepSym< double, 2 > > SMatrixSym2
Definition: CSCSegAlgoST.h:60
LocalPoint localPosition() const
Definition: CSCRecHit2D.h:50
T x() const
Definition: PV3DBase.h:62
LocalPoint protoIntercept
Definition: CSCSegAlgoST.h:190
void CSCSegAlgoST::fillLocalDirection ( void  )
private

Definition at line 1894 of file CSCSegAlgoST.cc.

References protoDirection, protoIntercept, protoSlope_u, protoSlope_v, mathSSE::sqrt(), theChamber, GeomDet::toGlobal(), csvLumiCalc::unit, and detailsBasic3DVector::z.

Referenced by buildSegments(), and prune_bad_hits().

1894  {
1895  // Always enforce direction of segment to point from IP outwards
1896  // (Incorrect for particles not coming from IP, of course.)
1897 
1898  double dxdz = protoSlope_u;
1899  double dydz = protoSlope_v;
1900  double dz = 1./sqrt(1. + dxdz*dxdz + dydz*dydz);
1901  double dx = dz*dxdz;
1902  double dy = dz*dydz;
1903  LocalVector localDir(dx,dy,dz);
1904 
1905  // localDir may need sign flip to ensure it points outward from IP
1906  // Examine its direction and origin in global z: to point outward
1907  // the localDir should always have same sign as global z...
1908 
1909  double globalZpos = ( theChamber->toGlobal( protoIntercept ) ).z();
1910  double globalZdir = ( theChamber->toGlobal( localDir ) ).z();
1911  double directionSign = globalZpos * globalZdir;
1912  protoDirection = (directionSign * localDir).unit();
1913 }
const CSCChamber * theChamber
Definition: CSCSegAlgoST.h:146
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:52
float protoSlope_v
Definition: CSCSegAlgoST.h:189
float protoSlope_u
Definition: CSCSegAlgoST.h:188
float float float z
LocalVector protoDirection
Definition: CSCSegAlgoST.h:193
string unit
Definition: csvLumiCalc.py:46
T sqrt(T t)
Definition: SSEVec.h:48
LocalPoint protoIntercept
Definition: CSCSegAlgoST.h:190
void CSCSegAlgoST::findDuplicates ( std::vector< CSCSegment > &  segments)
private

Definition at line 2174 of file CSCSegAlgoST.cc.

Referenced by run().

2174  {
2175  // this is intended for ME1/1a only - we have ghost segments because of the strips ganging
2176  // this function finds them (first the rechits by sharesInput() )
2177  // if a segment shares all the rechits with another segment it is a duplicate (even if
2178  // it has less rechits)
2179 
2180  for(std::vector<CSCSegment>::iterator it=segments.begin(); it != segments.end(); ++it) {
2181  std::vector<CSCSegment*> duplicateSegments;
2182  for(std::vector<CSCSegment>::iterator it2=segments.begin(); it2 != segments.end(); ++it2) {
2183  //
2184  bool allShared = true;
2185  if(it!=it2){
2186  allShared = it->sharesRecHits(*it2);
2187  }
2188  else{
2189  allShared = false;
2190  }
2191  //
2192  if(allShared){
2193  duplicateSegments.push_back(&(*it2));
2194  }
2195  }
2196  it->setDuplicateSegments(duplicateSegments);
2197  }
2198 
2199 }
void CSCSegAlgoST::fitSlopes ( void  )
private

Vector of the error matrix (only xx)

Correct the cov matrix

Definition at line 1737 of file CSCSegAlgoST.cc.

References correctTheCovMatrix(), correctTheCovX(), CSCRecHit2D::cscDetId(), e_Cxx, CSCChamber::layer(), CSCDetId::layer(), CSCRecHit2D::localPosition(), CSCRecHit2D::localPositionError(), LogTrace, convertSQLiteXML::ok, AlCaHLTBitMon_ParallelJobs::p, passCondNumber, passCondNumber_2, protoIntercept, protoSegment, protoSlope_u, protoSlope_v, theChamber, GeomDet::toGlobal(), GeomDet::toLocal(), findQualityFiles::v, PV3DBase< T, PVType, FrameType >::x(), LocalError::xx(), LocalError::xy(), PV3DBase< T, PVType, FrameType >::y(), LocalError::yy(), detailsBasic3DVector::z, and PV3DBase< T, PVType, FrameType >::z().

Referenced by doSlopesAndChi2().

1737  {
1738  e_Cxx.clear();
1740  correctTheCovX();
1741  if(e_Cxx.size()!=protoSegment.size()){
1742  LogTrace("CSCSegment|CSC") << "[CSCSegAlgoST::fitSlopes] e_Cxx.size()!=protoSegment.size() ALARM! Please inform CSC DPG " << std::endl;
1743  }
1744  }
1745 
1746  SMatrix4 M; // 4x4, init to 0
1747  SVector4 B; // 4x1, init to 0; //@@ 4x1 OR 1x4 ??
1748 
1749  ChamberHitContainer::const_iterator ih = protoSegment.begin();
1750  for (ih = protoSegment.begin(); ih != protoSegment.end(); ++ih) {
1751  const CSCRecHit2D& hit = (**ih);
1752  const CSCLayer* layer = theChamber->layer(hit.cscDetId().layer());
1753  GlobalPoint gp = layer->toGlobal(hit.localPosition());
1754  LocalPoint lp = theChamber->toLocal(gp);
1755  // Local position of hit w.r.t. chamber
1756  double u = lp.x();
1757  double v = lp.y();
1758  double z = lp.z();
1759  // Covariance matrix of local errors
1760  SMatrixSym2 IC; // 2x2, init to 0
1762  IC(0,0) = e_Cxx.at(ih-protoSegment.begin());
1763  }
1764  else{
1765  IC(0,0) = hit.localPositionError().xx();
1766  }
1767  // IC(0,1) = hit.localPositionError().xy();
1768  IC(1,0) = hit.localPositionError().xy();
1769  IC(1,1) = hit.localPositionError().yy();
1770  // IC(1,0) = IC(0,1); // since Cov is symmetric
1772  if(passCondNumber_2){
1773  correctTheCovMatrix(IC);
1774  }
1775  // Invert covariance matrix (and trap if it fails!)
1776  bool ok = IC.Invert();
1777  if ( !ok ) {
1778  LogTrace("CSCSegment|CSC") << "[CSCSegAlgoST::fitSlopes] Failed to invert covariance matrix: \n" << IC;
1779  // return ok;
1780  }
1781 
1782  M(0,0) += IC(0,0);
1783  M(0,1) += IC(0,1);
1784  M(0,2) += IC(0,0) * z;
1785  M(0,3) += IC(0,1) * z;
1786  B(0) += u * IC(0,0) + v * IC(0,1);
1787 
1788  M(1,0) += IC(1,0);
1789  M(1,1) += IC(1,1);
1790  M(1,2) += IC(1,0) * z;
1791  M(1,3) += IC(1,1) * z;
1792  B(1) += u * IC(1,0) + v * IC(1,1);
1793 
1794  M(2,0) += IC(0,0) * z;
1795  M(2,1) += IC(0,1) * z;
1796  M(2,2) += IC(0,0) * z * z;
1797  M(2,3) += IC(0,1) * z * z;
1798  B(2) += ( u * IC(0,0) + v * IC(0,1) ) * z;
1799 
1800  M(3,0) += IC(1,0) * z;
1801  M(3,1) += IC(1,1) * z;
1802  M(3,2) += IC(1,0) * z * z;
1803  M(3,3) += IC(1,1) * z * z;
1804  B(3) += ( u * IC(1,0) + v * IC(1,1) ) * z;
1805 
1806  }
1807 
1808  SVector4 p;
1809  bool ok = M.Invert();
1810  if (!ok ){
1811  LogTrace("CSCSegment|CSC") << "[CSCSegAlgoST::fitSlopes[ Failed to invert matrix: \n" << M;
1812  // return ok;
1813  }
1814  else {
1815  p = M * B;
1816  }
1817 
1818  // Update member variables
1819  // Note that origin has local z = 0
1820 
1821  protoIntercept = LocalPoint(p(0), p(1), 0.);
1822  protoSlope_u = p(2);
1823  protoSlope_v = p(3);
1824 
1825  // LogTrace("CSCSegAlgoST") << "[CSCSegAlgoST::fillSlopes] p = "
1826  // << p(0) << ", " << p(1) << ", " << p(2) << ", " << p(3);
1827 
1828 }
float xx() const
Definition: LocalError.h:24
CSCDetId cscDetId() const
Definition: CSCRecHit2D.h:52
bool passCondNumber
The number to force the Covariance.
Definition: CSCSegAlgoST.h:242
double_binary B
Definition: DDStreamer.cc:234
const CSCChamber * theChamber
Definition: CSCSegAlgoST.h:146
void correctTheCovX(void)
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:52
T y() const
Definition: PV3DBase.h:63
float protoSlope_v
Definition: CSCSegAlgoST.h:189
LocalPoint toLocal(const GlobalPoint &gp) const
Conversion to the R.F. of the GeomDet.
Definition: GeomDet.h:67
void correctTheCovMatrix(SMatrixSym2 &IC)
ChamberHitContainer protoSegment
Definition: CSCSegAlgoST.h:187
int layer() const
Definition: CSCDetId.h:74
ROOT::Math::SVector< double, 4 > SVector4
Definition: CSCSegAlgoST.h:63
float protoSlope_u
Definition: CSCSegAlgoST.h:188
float float float z
float xy() const
Definition: LocalError.h:25
LocalError localPositionError() const
Definition: CSCRecHit2D.h:51
float yy() const
Definition: LocalError.h:26
T z() const
Definition: PV3DBase.h:64
const CSCLayer * layer(CSCDetId id) const
Return the layer corresponding to the given id.
Definition: CSCChamber.cc:39
#define LogTrace(id)
ROOT::Math::SMatrix< double, 4 > SMatrix4
Definition: CSCSegAlgoST.h:56
bool passCondNumber_2
Passage the condition number calculations.
Definition: CSCSegAlgoST.h:243
Local3DPoint LocalPoint
Definition: LocalPoint.h:11
std::vector< double > e_Cxx
Definition: CSCSegAlgoST.h:229
ROOT::Math::SMatrix< double, 2, 2, ROOT::Math::MatRepSym< double, 2 > > SMatrixSym2
Definition: CSCSegAlgoST.h:60
LocalPoint localPosition() const
Definition: CSCRecHit2D.h:50
T x() const
Definition: PV3DBase.h:62
LocalPoint protoIntercept
Definition: CSCSegAlgoST.h:190
AlgebraicSymMatrix CSCSegAlgoST::flipErrors ( const SMatrixSym4 a) const
private

Definition at line 2008 of file CSCSegAlgoST.cc.

References a, i, and j.

Referenced by buildSegments(), and prune_bad_hits().

2008  {
2009 
2010  // The CSCSegment needs the error matrix re-arranged to match
2011  // parameters in order (uz, vz, u0, v0) where uz, vz = slopes, u0, v0 = intercepts
2012 
2013  // LogTrace("CSCSegAlgoST") << "[CSCSegAlgoST::flipErrors] input: \n" << a;
2014 
2015  AlgebraicSymMatrix hold(4, 0. );
2016 
2017  for ( short j=0; j!=4; ++j) {
2018  for (short i=0; i!=4; ++i) {
2019  hold(i+1,j+1) = a(i,j); // SMatrix counts from 0, AlgebraicMatrix from 1
2020  }
2021  }
2022 
2023  // LogTrace("CSCSegAlgoST") << "[CSCSegAlgoST::flipErrors] after copy:";
2024  // LogTrace("CSCSegAlgoST") << "(" << hold(1,1) << " " << hold(1,2) << " " << hold(1,3) << " " << hold(1,4);
2025  // LogTrace("CSCSegAlgoST") << " " << hold(2,1) << " " << hold(2,2) << " " << hold(2,3) << " " << hold(2,4);
2026  // LogTrace("CSCSegAlgoST") << " " << hold(3,1) << " " << hold(3,2) << " " << hold(3,3) << " " << hold(3,4);
2027  // LogTrace("CSCSegAlgoST") << " " << hold(4,1) << " " << hold(4,2) << " " << hold(4,3) << " " << hold(4,4) << ")";
2028 
2029  // errors on slopes into upper left
2030  hold(1,1) = a(2,2);
2031  hold(1,2) = a(2,3);
2032  hold(2,1) = a(3,2);
2033  hold(2,2) = a(3,3);
2034 
2035  // errors on positions into lower right
2036  hold(3,3) = a(0,0);
2037  hold(3,4) = a(0,1);
2038  hold(4,3) = a(1,0);
2039  hold(4,4) = a(1,1);
2040 
2041  // must also interchange off-diagonal elements of off-diagonal 2x2 submatrices
2042  hold(4,1) = a(1,2);
2043  hold(3,2) = a(0,3);
2044  hold(2,3) = a(3,0); // = a(0,3)
2045  hold(1,4) = a(2,1); // = a(1,2)
2046 
2047  // LogTrace("CSCSegAlgoST") << "[CSCSegAlgoST::flipErrors] after flip:";
2048  // LogTrace("CSCSegAlgoST") << "(" << hold(1,1) << " " << hold(1,2) << " " << hold(1,3) << " " << hold(1,4);
2049  // LogTrace("CSCSegAlgoST") << " " << hold(2,1) << " " << hold(2,2) << " " << hold(2,3) << " " << hold(2,4);
2050  // LogTrace("CSCSegAlgoST") << " " << hold(3,1) << " " << hold(3,2) << " " << hold(3,3) << " " << hold(3,4);
2051  // LogTrace("CSCSegAlgoST") << " " << hold(4,1) << " " << hold(4,2) << " " << hold(4,3) << " " << hold(4,4) << ")";
2052 
2053  return hold;
2054 }
int i
Definition: DBlmapReader.cc:9
int j
Definition: DBlmapReader.cc:9
double a
Definition: hdecay.h:121
CLHEP::HepSymMatrix AlgebraicSymMatrix
bool CSCSegAlgoST::isGoodToMerge ( bool  isME11a,
ChamberHitContainer newChain,
ChamberHitContainer oldChain 
)
private

Definition at line 593 of file CSCSegAlgoST.cc.

Referenced by chainHits().

593  {
594  for(size_t iRH_new = 0;iRH_new<newChain.size();++iRH_new){
595  int layer_new = newChain[iRH_new]->cscDetId().layer()-1;
596  int middleStrip_new = newChain[iRH_new]->nStrips()/2;
597  int centralStrip_new = newChain[iRH_new]->channels(middleStrip_new);
598  int centralWire_new = newChain[iRH_new]->hitWire();
599  bool layerRequirementOK = false;
600  bool stripRequirementOK = false;
601  bool wireRequirementOK = false;
602  bool goodToMerge = false;
603  for(size_t iRH_old = 0;iRH_old<oldChain.size();++iRH_old){
604  int layer_old = oldChain[iRH_old]->cscDetId().layer()-1;
605  int middleStrip_old = oldChain[iRH_old]->nStrips()/2;
606  int centralStrip_old = oldChain[iRH_old]->channels(middleStrip_old);
607  int centralWire_old = oldChain[iRH_old]->hitWire();
608 
609  // to be chained, two hits need to be in neighbouring layers...
610  // or better allow few missing layers (upto 3 to avoid inefficiencies);
611  // however we'll not make an angle correction because it
612  // worsen the situation in some of the "regular" cases
613  // (not making the correction means that the conditions for
614  // forming a cluster are different if we have missing layers -
615  // this could affect events at the boundaries )
616  if(layer_new==layer_old+1 || layer_new==layer_old-1 ||
617  layer_new==layer_old+2 || layer_new==layer_old-2 ||
618  layer_new==layer_old+3 || layer_new==layer_old-3 ||
619  layer_new==layer_old+4 || layer_new==layer_old-4 ){
620  layerRequirementOK = true;
621  }
622  int allStrips = 48;
623  //to be chained, two hits need to be "close" in strip number (can do it in phi
624  // but it doesn't really matter); let "close" means upto 2 strips (3?) -
625  // this is more compared to what CLCT readout patterns allow
626  if(centralStrip_new==centralStrip_old ||
627  centralStrip_new==centralStrip_old+1 || centralStrip_new==centralStrip_old-1 ||
628  centralStrip_new==centralStrip_old+2 || centralStrip_new==centralStrip_old-2){
629  stripRequirementOK = true;
630  }
631  // same for wires (and ALCT patterns)
632  if(centralWire_new==centralWire_old ||
633  centralWire_new==centralWire_old+1 || centralWire_new==centralWire_old-1 ||
634  centralWire_new==centralWire_old+2 || centralWire_new==centralWire_old-2){
635  wireRequirementOK = true;
636  }
637 
638  if(gangedME11a){
639  if(centralStrip_new==centralStrip_old+1-allStrips || centralStrip_new==centralStrip_old-1-allStrips ||
640  centralStrip_new==centralStrip_old+2-allStrips || centralStrip_new==centralStrip_old-2-allStrips ||
641  centralStrip_new==centralStrip_old+1+allStrips || centralStrip_new==centralStrip_old-1+allStrips ||
642  centralStrip_new==centralStrip_old+2+allStrips || centralStrip_new==centralStrip_old-2+allStrips){
643  stripRequirementOK = true;
644  }
645  }
646  if(layerRequirementOK && stripRequirementOK && wireRequirementOK){
647  goodToMerge = true;
648  return goodToMerge;
649  }
650  }
651  }
652  return false;
653 }
std::vector< CSCSegment > CSCSegAlgoST::prune_bad_hits ( const CSCChamber aChamber,
std::vector< CSCSegment > &  segments 
)

Remove bad hits from found segments based not only on chi2, but also on charge and further "low level" chamber information.

Definition at line 189 of file CSCSegAlgoST.cc.

References begin, BPMinImprovement, BrutePruning, calculateError(), CSCSegment::chi2(), chi2Norm_3D_, ChiSquaredProbability(), correctCov_, doSlopesAndChi2(), alignCSCRings::e, fillLocalDirection(), flipErrors(), CSCChamber::layer(), contentValuesFiles::m, minHitsPerSegment, CSCSegment::nRecHits(), passCondNumber, passCondNumber_2, protoChi2, protoChiUCorrection, protoDirection, protoIntercept, protoNDF, protoSegment, groupFilesInBlocks::temp, theChamber, GeomDet::toGlobal(), PV3DBase< T, PVType, FrameType >::x(), LocalError::xx(), and PV3DBase< T, PVType, FrameType >::z().

Referenced by run().

189  {
190 
191  // std::cout<<"*************************************************************"<<std::endl;
192  // std::cout<<"Called prune_bad_hits in Chamber "<< theChamber->specs()->chamberTypeName()<<std::endl;
193  // std::cout<<"*************************************************************"<<std::endl;
194 
195  std::vector<CSCSegment> segments_temp;
196  std::vector<ChamberHitContainer> rechits_clusters; // this is a collection of groups of rechits
197 
198  const float chi2ndfProbMin = 1.0e-4;
199  bool use_brute_force = BrutePruning;
200 
201  int hit_nr = 0;
202  int hit_nr_worst = -1;
203  //int hit_nr_2ndworst = -1;
204 
205  for(std::vector<CSCSegment>::iterator it=segments.begin(); it != segments.end(); ++it) {
206 
207  // do nothing for nhit <= minHitPerSegment
208  if( (*it).nRecHits() <= minHitsPerSegment ) continue;
209 
210  if( !use_brute_force ) {// find worst hit
211 
212  float chisq = (*it).chi2();
213  int nhits = (*it).nRecHits();
214  LocalPoint localPos = (*it).localPosition();
215  LocalVector segDir = (*it).localDirection();
216  const CSCChamber* cscchamber = theChamber;
217  float globZ ;
218 
219  GlobalPoint globalPosition = cscchamber->toGlobal(localPos);
220  globZ = globalPosition.z();
221 
222 
223  if( ChiSquaredProbability((double)chisq,(double)(2*nhits-4)) < chi2ndfProbMin ) {
224 
225  // find (rough) "residuals" (NOT excluding the hit from the fit - speed!) of hits on segment
226  std::vector<CSCRecHit2D> theseRecHits = (*it).specificRecHits();
227  std::vector<CSCRecHit2D>::const_iterator iRH_worst;
228  //float xdist_local = -99999.;
229 
230  float xdist_local_worst_sig = -99999.;
231  float xdist_local_2ndworst_sig = -99999.;
232  float xdist_local_sig = -99999.;
233 
234  hit_nr = 0;
235  hit_nr_worst = -1;
236  //hit_nr_2ndworst = -1;
237 
238  for ( std::vector<CSCRecHit2D>::const_iterator iRH = theseRecHits.begin(); iRH != theseRecHits.end(); ++iRH) {
239  //mark "worst" hit:
240 
241  //float z_at_target ;
242  //float radius ;
243  float loc_x_at_target ;
244  //float loc_y_at_target ;
245  //float loc_z_at_target ;
246 
247  //z_at_target = 0.;
248  loc_x_at_target = 0.;
249  //loc_y_at_target = 0.;
250  //loc_z_at_target = 0.;
251  //radius = 0.;
252 
253  // set the z target in CMS global coordinates:
254  const CSCLayer* csclayerRH = theChamber->layer((*iRH).cscDetId().layer());
255  LocalPoint localPositionRH = (*iRH).localPosition();
256  GlobalPoint globalPositionRH = csclayerRH->toGlobal(localPositionRH);
257 
258  LocalError rerrlocal = (*iRH).localPositionError();
259  float xxerr = rerrlocal.xx();
260 
261  float target_z = globalPositionRH.z(); // target z position in cm (z pos of the hit)
262 
263  if(target_z > 0.) {
264  loc_x_at_target = localPos.x() + (segDir.x()/fabs(segDir.z())*( target_z - globZ ));
265  //loc_y_at_target = localPos.y() + (segDir.y()/fabs(segDir.z())*( target_z - globZ ));
266  //loc_z_at_target = target_z;
267  }
268  else {
269  loc_x_at_target = localPos.x() + ((-1)*segDir.x()/fabs(segDir.z())*( target_z - globZ ));
270  //loc_y_at_target = localPos.y() + ((-1)*segDir.y()/fabs(segDir.z())*( target_z - globZ ));
271  //loc_z_at_target = target_z;
272  }
273  // have to transform the segments coordinates back to the local frame... how?!!!!!!!!!!!!
274 
275  //xdist_local = fabs(localPositionRH.x() - loc_x_at_target);
276  xdist_local_sig = fabs((localPositionRH.x() -loc_x_at_target)/(xxerr));
277 
278  if( xdist_local_sig > xdist_local_worst_sig ) {
279  xdist_local_2ndworst_sig = xdist_local_worst_sig;
280  xdist_local_worst_sig = xdist_local_sig;
281  iRH_worst = iRH;
282  //hit_nr_2ndworst = hit_nr_worst;
283  hit_nr_worst = hit_nr;
284  }
285  else if(xdist_local_sig > xdist_local_2ndworst_sig) {
286  xdist_local_2ndworst_sig = xdist_local_sig;
287  //hit_nr_2ndworst = hit_nr;
288  }
289  ++hit_nr;
290  }
291 
292  // reset worst hit number if certain criteria apply.
293  // Criteria: 2nd worst hit must be at least a factor of
294  // 1.5 better than the worst in terms of sigma:
295  if ( xdist_local_worst_sig / xdist_local_2ndworst_sig < 1.5 ) {
296  hit_nr_worst = -1;
297  //hit_nr_2ndworst = -1;
298  }
299  }
300  }
301 
302  // if worst hit was found, refit without worst hit and select if considerably better than original fit.
303  // Can also use brute force: refit all n-1 hit segments and choose one over the n hit if considerably "better"
304 
305  std::vector< CSCRecHit2D > buffer;
306  std::vector< std::vector< CSCRecHit2D > > reduced_segments;
307  std::vector< CSCRecHit2D > theseRecHits = (*it).specificRecHits();
308  float best_red_seg_prob = 0.0;
309  // usefor chi2 1 diff float best_red_seg_prob = 99999.;
310  buffer.clear();
311 
312  if( ChiSquaredProbability((double)(*it).chi2(),(double)((2*(*it).nRecHits())-4)) < chi2ndfProbMin ) {
313 
314  buffer = theseRecHits;
315 
316  // Dirty switch: here one can select to refit all possible subsets or just the one without the
317  // tagged worst hit:
318  if( use_brute_force ) { // Brute force method: loop over all possible segments:
319  for(size_t bi = 0; bi < buffer.size(); ++bi) {
320  reduced_segments.push_back(buffer);
321  reduced_segments[bi].erase(reduced_segments[bi].begin()+(bi),reduced_segments[bi].begin()+(bi+1));
322  }
323  }
324  else { // More elegant but still biased: erase only worst hit
325  // Comment: There is not a very strong correlation of the worst hit with the one that one should remove...
326  if( hit_nr_worst >= 0 && hit_nr_worst <= int(buffer.size()) ) {
327  // fill segment in buffer, delete worst hit
328  buffer.erase(buffer.begin()+(hit_nr_worst),buffer.begin()+(hit_nr_worst+1));
329  reduced_segments.push_back(buffer);
330  }
331  else {
332  // only fill segment in array, do not delete anything
333  reduced_segments.push_back(buffer);
334  }
335  }
336  }
337 
338  // Loop over the subsegments and fit (only one segment if "use_brute_force" is false):
339  for(size_t iSegment=0; iSegment<reduced_segments.size(); ++iSegment) {
340  // loop over hits on given segment and push pointers to hits into protosegment
341  protoSegment.clear();
342  for(size_t m = 0; m<reduced_segments[iSegment].size(); ++m ) {
343  protoSegment.push_back(&reduced_segments[iSegment][m]);
344  }
345  passCondNumber=false;
346  passCondNumber_2 = false;
348  doSlopesAndChi2();
349  // Attempt to handle numerical instability of the fit;
350  // The same as in the build method;
351  // Preprune is not applied;
352  if(correctCov_){
354  passCondNumber = true;
355  doSlopesAndChi2();
356  }
358  passCondNumber_2=true;
359  doSlopesAndChi2();
360  }
361  }
363  // calculate error matrix
364  // AlgebraicSymMatrix protoErrors = calculateError();
365  SMatrixSym4 protoErrors = calculateError();
366  // but reorder components to match what's required by TrackingRecHit interface
367  // i.e. slopes first, then positions
368  AlgebraicSymMatrix temp2 = flipErrors( protoErrors ); //@@ TO SATISFY CSCSegment INTERFACE
369 
371 
372  // replace n hit segment with n-1 hit segment, if segment probability is BPMinImprovement better:
373  if( ( ChiSquaredProbability((double)(*it).chi2(),(double)((2*(*it).nRecHits())-4))
374  <
375  (1./BPMinImprovement)*(ChiSquaredProbability((double)temp.chi2(),(double)(2*temp.nRecHits()-4))) ) // was (1.e-3) 081202
376 
377  &&
378  ( (ChiSquaredProbability((double)temp.chi2(),(double)(2*temp.nRecHits()-4)))
379  > best_red_seg_prob
380  )
381  &&
382  ( (ChiSquaredProbability((double)temp.chi2(),(double)(2*temp.nRecHits()-4))) > 1e-10 )
383  ) {
384  best_red_seg_prob = ChiSquaredProbability((double)temp.chi2(),(double)(2*temp.nRecHits()-4));
385  // The alternative n-1 segment is much cleaner. If this segment
386  // has >= minHitsPerSegment hits exchange current n hit segment (*it)
387  // with better n-1 hit segment:
388  if( temp.nRecHits() >= minHitsPerSegment ) {
389  (*it) = temp;
390  }
391  }
392  }
393  }
394 
395  return segments;
396 
397 }
double protoChiUCorrection
Allow to correct the error matrix.
Definition: CSCSegAlgoST.h:228
float xx() const
Definition: LocalError.h:24
bool passCondNumber
The number to force the Covariance.
Definition: CSCSegAlgoST.h:242
void doSlopesAndChi2(void)
const CSCChamber * theChamber
Definition: CSCSegAlgoST.h:146
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:52
ChamberHitContainer protoSegment
Definition: CSCSegAlgoST.h:187
LocalVector protoDirection
Definition: CSCSegAlgoST.h:193
double BPMinImprovement
Definition: CSCSegAlgoST.h:209
T z() const
Definition: PV3DBase.h:64
double protoNDF
Definition: CSCSegAlgoST.h:192
double protoChi2
Definition: CSCSegAlgoST.h:191
const CSCLayer * layer(CSCDetId id) const
Return the layer corresponding to the given id.
Definition: CSCChamber.cc:39
float ChiSquaredProbability(double chiSquared, double nrDOF)
bool passCondNumber_2
Passage the condition number calculations.
Definition: CSCSegAlgoST.h:243
bool correctCov_
Correct the Error Matrix.
Definition: CSCSegAlgoST.h:227
int minHitsPerSegment
Definition: CSCSegAlgoST.h:199
SMatrixSym4 calculateError(void) const
ROOT::Math::SMatrix< double, 4, 4, ROOT::Math::MatRepSym< double, 4 > > SMatrixSym4
Definition: CSCSegAlgoST.h:57
#define begin
Definition: vmac.h:30
CLHEP::HepSymMatrix AlgebraicSymMatrix
void fillLocalDirection(void)
T x() const
Definition: PV3DBase.h:62
AlgebraicSymMatrix flipErrors(const SMatrixSym4 &) const
LocalPoint protoIntercept
Definition: CSCSegAlgoST.h:190
double chi2Norm_3D_
Chi^2 normalization for the corrected fit.
Definition: CSCSegAlgoST.h:231
std::vector< CSCSegment > CSCSegAlgoST::run ( const CSCChamber aChamber,
const ChamberHitContainer rechits 
)

Build segments for all desired groups of hits

Definition at line 95 of file CSCSegAlgoST.cc.

References a, a_yweightPenaltyThreshold, b, buildSegments(), chainHits(), CSCChamberSpecs::chamberTypeName(), clusterHits(), findDuplicates(), CSCChamberSpecs::gangedStrips(), CSCChamber::id(), LogTrace, preClustering, preClustering_useChaining, prune_bad_hits(), Pruning, CSCChamber::specs(), theChamber, and yweightPenaltyThreshold.

95  {
96 
97  // Set member variable
98  theChamber = aChamber;
99 
100  LogTrace("CSCSegAlgoST") << "[CSCSegAlgoST::run] Start building segments in chamber " << theChamber->id();
101 
102  // pre-cluster rechits and loop over all sub clusters seperately
103  std::vector<CSCSegment> segments_temp;
104  std::vector<CSCSegment> segments;
105  std::vector<ChamberHitContainer> rechits_clusters; // a collection of clusters of rechits
106 
107  // Define yweight penalty depending on chamber.
108  // We fixed the relative ratios, but they can be scaled by parameters:
109 
110  for(int a = 0; a<5; ++a) {
111  for(int b = 0; b<5; ++b) {
112  a_yweightPenaltyThreshold[a][b] = 0.0;
113  }
114  }
115 
125  a_yweightPenaltyThreshold[4][2] = yweightPenaltyThreshold * 20.40; //@@ ADD ME4/2 WITH RING 2 VALUE
126 
127  if(preClustering) {
128  // run a pre-clusterer on the given rechits to split clearly-separated segment seeds:
130  // it uses X,Y,Z information; there are no configurable parameters used;
131  // the X, Y, Z "cuts" are just (much) wider than the LCT readout ones
132  // (which are actually not step functions); this new code could accomodate
133  // the clusterHits one below but we leave it for security and backward
134  // comparison reasons
135  rechits_clusters = chainHits( theChamber, rechits );
136  }
137  else{
138  // it uses X,Y information + configurable parameters
139  rechits_clusters = clusterHits( theChamber, rechits );
140  }
141  // loop over the found clusters:
142  for(std::vector<ChamberHitContainer>::iterator sub_rechits = rechits_clusters.begin(); sub_rechits != rechits_clusters.end(); ++sub_rechits ) {
143  // clear the buffer for the subset of segments:
144  segments_temp.clear();
145  // build the subset of segments:
146  segments_temp = buildSegments( (*sub_rechits) );
147  // add the found subset of segments to the collection of all segments in this chamber:
148  segments.insert( segments.end(), segments_temp.begin(), segments_temp.end() );
149  }
150  // Any pruning of hits?
151  if( Pruning ) {
152  segments_temp.clear(); // segments_temp needed?!?!
153  segments_temp = prune_bad_hits( theChamber, segments );
154  segments.clear(); // segments_temp needed?!?!
155  segments.swap(segments_temp); // segments_temp needed?!?!
156  }
157 
158  //@@ Ganged strips in ME1/1A?
159  if ( ("ME1/a" == aChamber->specs()->chamberTypeName()) && aChamber->specs()->gangedStrips() ){
160  // if ( aChamber->specs()->gangedStrips() ){
161  findDuplicates(segments);
162  }
163  return segments;
164  }
165  else {
166  segments = buildSegments(rechits);
167  if( Pruning ) {
168  segments_temp.clear(); // segments_temp needed?!?!
169  segments_temp = prune_bad_hits( theChamber, segments );
170  segments.clear(); // segments_temp needed?!?!
171  segments.swap(segments_temp); // segments_temp needed?!?!
172  }
173 
174  //@@ Ganged strips in ME1/1A?
175  if ( ("ME1/a" == aChamber->specs()->chamberTypeName()) && aChamber->specs()->gangedStrips() ){
176  // if ( aChamber->specs()->gangedStrips() ){
177  findDuplicates(segments);
178  }
179  return segments;
180  //return buildSegments(rechits);
181  }
182 }
double yweightPenaltyThreshold
Definition: CSCSegAlgoST.h:219
bool preClustering_useChaining
Definition: CSCSegAlgoST.h:206
CSCDetId id() const
Get the (concrete) DetId.
Definition: CSCChamber.h:37
const CSCChamber * theChamber
Definition: CSCSegAlgoST.h:146
std::vector< std::vector< const CSCRecHit2D * > > clusterHits(const CSCChamber *aChamber, const ChamberHitContainer &rechits)
std::string chamberTypeName() const
const CSCChamberSpecs * specs() const
Definition: CSCChamber.h:42
std::vector< std::vector< const CSCRecHit2D * > > chainHits(const CSCChamber *aChamber, const ChamberHitContainer &rechits)
std::vector< CSCSegment > buildSegments(const ChamberHitContainer &rechits)
std::vector< CSCSegment > prune_bad_hits(const CSCChamber *aChamber, std::vector< CSCSegment > &segments)
bool gangedStrips() const
#define LogTrace(id)
void findDuplicates(std::vector< CSCSegment > &segments)
double b
Definition: hdecay.h:120
double a
Definition: hdecay.h:121
bool preClustering
Definition: CSCSegAlgoST.h:205
float a_yweightPenaltyThreshold[5][5]
Definition: CSCSegAlgoST.h:217
double CSCSegAlgoST::theWeight ( double  coordinate_1,
double  coordinate_2,
double  coordinate_3,
float  layer_1,
float  layer_2,
float  layer_3 
)
private

Utility functions.

Definition at line 658 of file CSCSegAlgoST.cc.

Referenced by buildSegments().

658  {
659  double sub_weight = 0;
660  sub_weight = fabs(
661  ( (coordinate_2 - coordinate_3) / (layer_2 - layer_3) ) -
662  ( (coordinate_1 - coordinate_2) / (layer_1 - layer_2) )
663  );
664  return sub_weight;
665 }
CSCSegAlgoST::SMatrixSym12 CSCSegAlgoST::weightMatrix ( void  ) const
private

Definition at line 1919 of file CSCSegAlgoST.cc.

References CSCRecHit2D::localPositionError(), LogTrace, makeMuonMisalignmentScenario::matrix, convertSQLiteXML::ok, protoChiUCorrection, protoSegment, LocalError::xx(), LocalError::xy(), and LocalError::yy().

Referenced by calculateError().

1919  {
1920 
1921  std::vector<const CSCRecHit2D*>::const_iterator it;
1922 
1923  bool ok = true;
1924 
1925  SMatrixSym12 matrix = ROOT::Math::SMatrixIdentity(); // 12x12, init to 1's on diag
1926 
1927  int row = 0;
1928 
1929  for (it = protoSegment.begin(); it != protoSegment.end(); ++it) {
1930 
1931  const CSCRecHit2D& hit = (**it);
1932 
1933  matrix(row, row) = protoChiUCorrection*hit.localPositionError().xx();
1934  matrix(row, row+1) = hit.localPositionError().xy();
1935  ++row;
1936  matrix(row, row-1) = hit.localPositionError().xy();
1937  matrix(row, row) = hit.localPositionError().yy();
1938  ++row;
1939  }
1940 
1941  ok = matrix.Invert(); // invert in place
1942  if ( !ok ) {
1943  LogTrace("CSCSegment|CSC") << "[CSCSegAlgoST::weightMatrix] Failed to invert matrix: \n" << matrix;
1944  // return ok;
1945  }
1946  return matrix;
1947 }
double protoChiUCorrection
Allow to correct the error matrix.
Definition: CSCSegAlgoST.h:228
float xx() const
Definition: LocalError.h:24
ChamberHitContainer protoSegment
Definition: CSCSegAlgoST.h:187
float xy() const
Definition: LocalError.h:25
LocalError localPositionError() const
Definition: CSCRecHit2D.h:51
float yy() const
Definition: LocalError.h:26
#define LogTrace(id)
ROOT::Math::SMatrix< double, 12, 12, ROOT::Math::MatRepSym< double, 12 > > SMatrixSym12
Definition: CSCSegAlgoST.h:50

Member Data Documentation

float CSCSegAlgoST::a_yweightPenaltyThreshold[5][5]
private

Definition at line 217 of file CSCSegAlgoST.h.

Referenced by buildSegments(), and run().

double CSCSegAlgoST::BPMinImprovement
private

Definition at line 209 of file CSCSegAlgoST.h.

Referenced by CSCSegAlgoST(), and prune_bad_hits().

bool CSCSegAlgoST::BrutePruning
private

Definition at line 208 of file CSCSegAlgoST.h.

Referenced by CSCSegAlgoST(), and prune_bad_hits().

double CSCSegAlgoST::chi2Norm_2D_
private

Definition at line 230 of file CSCSegAlgoST.h.

Referenced by correctTheCovX(), and CSCSegAlgoST().

double CSCSegAlgoST::chi2Norm_3D_
private

Chi^2 normalization for the corrected fit.

Definition at line 231 of file CSCSegAlgoST.h.

Referenced by buildSegments(), CSCSegAlgoST(), and prune_bad_hits().

std::vector< ChamberHitContainer > CSCSegAlgoST::chosen_Psegments
private

Definition at line 160 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::chosen_weight_A
private

Definition at line 169 of file CSCSegAlgoST.h.

Referenced by buildSegments().

double CSCSegAlgoST::condSeed1_
private

The upper limit of protoChiUCorrection to apply prePrun.

Correct the error matrix for the condition number

Definition at line 238 of file CSCSegAlgoST.h.

Referenced by correctTheCovMatrix(), and CSCSegAlgoST().

double CSCSegAlgoST::condSeed2_
private

Definition at line 238 of file CSCSegAlgoST.h.

Referenced by correctTheCovMatrix(), and CSCSegAlgoST().

bool CSCSegAlgoST::correctCov_
private

Correct the Error Matrix.

Definition at line 227 of file CSCSegAlgoST.h.

Referenced by buildSegments(), CSCSegAlgoST(), and prune_bad_hits().

double CSCSegAlgoST::covAnyNumber_
private

Allow to use any number for covariance for all RecHits.

Definition at line 241 of file CSCSegAlgoST.h.

Referenced by correctTheCovMatrix(), and CSCSegAlgoST().

bool CSCSegAlgoST::covToAnyNumber_
private

The correction parameters.

Definition at line 239 of file CSCSegAlgoST.h.

Referenced by correctTheCovMatrix(), and CSCSegAlgoST().

bool CSCSegAlgoST::covToAnyNumberAll_
private

Allow to use any number for covariance (by hand)

Definition at line 240 of file CSCSegAlgoST.h.

Referenced by correctTheCovMatrix(), and CSCSegAlgoST().

std::vector< float > CSCSegAlgoST::curv_A
private

Definition at line 170 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::curv_noL1_A
private

Definition at line 171 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::curv_noL2_A
private

Definition at line 172 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::curv_noL3_A
private

Definition at line 173 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::curv_noL4_A
private

Definition at line 174 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::curv_noL5_A
private

Definition at line 175 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::curv_noL6_A
private

Definition at line 176 of file CSCSegAlgoST.h.

Referenced by buildSegments().

double CSCSegAlgoST::curvePenalty
private

Definition at line 223 of file CSCSegAlgoST.h.

Referenced by buildSegments(), and CSCSegAlgoST().

double CSCSegAlgoST::curvePenaltyThreshold
private

Definition at line 222 of file CSCSegAlgoST.h.

Referenced by buildSegments(), and CSCSegAlgoST().

bool CSCSegAlgoST::debug
private

Definition at line 196 of file CSCSegAlgoST.h.

Referenced by CSCSegAlgoST().

double CSCSegAlgoST::dXclusBoxMax
private

Definition at line 202 of file CSCSegAlgoST.h.

Referenced by clusterHits(), and CSCSegAlgoST().

double CSCSegAlgoST::dYclusBoxMax
private

Definition at line 203 of file CSCSegAlgoST.h.

Referenced by clusterHits(), and CSCSegAlgoST().

std::vector<double> CSCSegAlgoST::e_Cxx
private

Definition at line 229 of file CSCSegAlgoST.h.

Referenced by correctTheCovX(), fillChiSquared(), and fitSlopes().

Segments CSCSegAlgoST::GoodSegments
private

Definition at line 147 of file CSCSegAlgoST.h.

Referenced by buildSegments(), ChooseSegments2(), ChooseSegments2a(), and ChooseSegments3().

double CSCSegAlgoST::hitDropLimit4Hits
private

Definition at line 213 of file CSCSegAlgoST.h.

Referenced by buildSegments(), and CSCSegAlgoST().

double CSCSegAlgoST::hitDropLimit5Hits
private

Definition at line 214 of file CSCSegAlgoST.h.

Referenced by buildSegments(), and CSCSegAlgoST().

double CSCSegAlgoST::hitDropLimit6Hits
private

Definition at line 215 of file CSCSegAlgoST.h.

Referenced by buildSegments(), and CSCSegAlgoST().

unsigned CSCSegAlgoST::maxContrIndex
private

Chi^2 normalization for the initial fit.

Definition at line 232 of file CSCSegAlgoST.h.

Referenced by buildSegments(), correctTheCovX(), and CSCSegAlgoST().

int CSCSegAlgoST::maxRecHitsInCluster
private

Definition at line 204 of file CSCSegAlgoST.h.

Referenced by buildSegments(), and CSCSegAlgoST().

int CSCSegAlgoST::minHitsPerSegment
private

Definition at line 199 of file CSCSegAlgoST.h.

Referenced by buildSegments(), CSCSegAlgoST(), and prune_bad_hits().

const std::string CSCSegAlgoST::myName
private

Definition at line 145 of file CSCSegAlgoST.h.

bool CSCSegAlgoST::onlyBestSegment
private

Definition at line 210 of file CSCSegAlgoST.h.

Referenced by buildSegments(), and CSCSegAlgoST().

ChamberHitContainer CSCSegAlgoST::PAhits_onLayer[6]
private

Definition at line 149 of file CSCSegAlgoST.h.

Referenced by buildSegments().

bool CSCSegAlgoST::passCondNumber
private

The number to force the Covariance.

Definition at line 242 of file CSCSegAlgoST.h.

Referenced by buildSegments(), CSCSegAlgoST(), fillChiSquared(), fitSlopes(), and prune_bad_hits().

bool CSCSegAlgoST::passCondNumber_2
private

Passage the condition number calculations.

Definition at line 243 of file CSCSegAlgoST.h.

Referenced by buildSegments(), CSCSegAlgoST(), fillChiSquared(), fitSlopes(), and prune_bad_hits().

bool CSCSegAlgoST::preClustering
private

Definition at line 205 of file CSCSegAlgoST.h.

Referenced by CSCSegAlgoST(), and run().

bool CSCSegAlgoST::preClustering_useChaining
private

Definition at line 206 of file CSCSegAlgoST.h.

Referenced by CSCSegAlgoST(), and run().

bool CSCSegAlgoST::prePrun_
private

The index of the worst x RecHit in Chi^2-X method.

Definition at line 233 of file CSCSegAlgoST.h.

Referenced by buildSegments(), and CSCSegAlgoST().

double CSCSegAlgoST::prePrunLimit_
private

Allow to prune a (rechit in a) segment in segment buld method once it passed through Chi^2-X and protoChiUCorrection is big.

Definition at line 235 of file CSCSegAlgoST.h.

Referenced by buildSegments(), correctTheCovX(), and CSCSegAlgoST().

double CSCSegAlgoST::protoChi2
private

Definition at line 191 of file CSCSegAlgoST.h.

Referenced by buildSegments(), fillChiSquared(), and prune_bad_hits().

double CSCSegAlgoST::protoChiUCorrection
private

Allow to correct the error matrix.

Definition at line 228 of file CSCSegAlgoST.h.

Referenced by buildSegments(), correctTheCovX(), CSCSegAlgoST(), prune_bad_hits(), and weightMatrix().

LocalVector CSCSegAlgoST::protoDirection
private

Definition at line 193 of file CSCSegAlgoST.h.

Referenced by buildSegments(), fillLocalDirection(), and prune_bad_hits().

LocalPoint CSCSegAlgoST::protoIntercept
private
double CSCSegAlgoST::protoNDF
private

Definition at line 192 of file CSCSegAlgoST.h.

Referenced by buildSegments(), CSCSegAlgoST(), fillChiSquared(), and prune_bad_hits().

ChamberHitContainer CSCSegAlgoST::protoSegment
private
float CSCSegAlgoST::protoSlope_u
private

Definition at line 188 of file CSCSegAlgoST.h.

Referenced by fillChiSquared(), fillLocalDirection(), and fitSlopes().

float CSCSegAlgoST::protoSlope_v
private

Definition at line 189 of file CSCSegAlgoST.h.

Referenced by fillChiSquared(), fillLocalDirection(), and fitSlopes().

bool CSCSegAlgoST::Pruning
private

Definition at line 207 of file CSCSegAlgoST.h.

Referenced by CSCSegAlgoST(), and run().

std::vector< ChamberHitContainer > CSCSegAlgoST::Psegments
private

Definition at line 152 of file CSCSegAlgoST.h.

Referenced by buildSegments(), and ChooseSegments2().

ChamberHitContainer CSCSegAlgoST::Psegments_hits
private

Definition at line 150 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< ChamberHitContainer > CSCSegAlgoST::Psegments_noL1
private

Definition at line 154 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< ChamberHitContainer > CSCSegAlgoST::Psegments_noL2
private

Definition at line 155 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< ChamberHitContainer > CSCSegAlgoST::Psegments_noL3
private

Definition at line 156 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< ChamberHitContainer > CSCSegAlgoST::Psegments_noL4
private

Definition at line 157 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< ChamberHitContainer > CSCSegAlgoST::Psegments_noL5
private

Definition at line 158 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< ChamberHitContainer > CSCSegAlgoST::Psegments_noL6
private

Definition at line 159 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< ChamberHitContainer > CSCSegAlgoST::Psegments_noLx
private

Definition at line 153 of file CSCSegAlgoST.h.

Referenced by buildSegments().

CSCSegAlgoShowering* CSCSegAlgoST::showering_
private

Definition at line 224 of file CSCSegAlgoST.h.

Referenced by buildSegments(), CSCSegAlgoST(), and ~CSCSegAlgoST().

const CSCChamber* CSCSegAlgoST::theChamber
private
bool CSCSegAlgoST::useShowering
private

Definition at line 211 of file CSCSegAlgoST.h.

Referenced by buildSegments(), and CSCSegAlgoST().

std::vector< float > CSCSegAlgoST::weight_A
private

Definition at line 161 of file CSCSegAlgoST.h.

Referenced by buildSegments(), and ChooseSegments2().

std::vector< float > CSCSegAlgoST::weight_B
private

Definition at line 177 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::weight_noL1_A
private

Definition at line 163 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::weight_noL1_B
private

Definition at line 178 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::weight_noL2_A
private

Definition at line 164 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::weight_noL2_B
private

Definition at line 179 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::weight_noL3_A
private

Definition at line 165 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::weight_noL3_B
private

Definition at line 180 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::weight_noL4_A
private

Definition at line 166 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::weight_noL4_B
private

Definition at line 181 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::weight_noL5_A
private

Definition at line 167 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::weight_noL5_B
private

Definition at line 182 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::weight_noL6_A
private

Definition at line 168 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::weight_noL6_B
private

Definition at line 183 of file CSCSegAlgoST.h.

Referenced by buildSegments().

std::vector< float > CSCSegAlgoST::weight_noLx_A
private

Definition at line 162 of file CSCSegAlgoST.h.

Referenced by buildSegments().

double CSCSegAlgoST::yweightPenalty
private

Definition at line 220 of file CSCSegAlgoST.h.

Referenced by buildSegments(), and CSCSegAlgoST().

double CSCSegAlgoST::yweightPenaltyThreshold
private

Definition at line 219 of file CSCSegAlgoST.h.

Referenced by CSCSegAlgoST(), and run().