ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/IPHCalignment2/Alignment/TwoBodyDecay/src/TwoBodyDecayEstimator.cc
Revision: 1.1
Committed: Fri Nov 25 17:10:52 2011 UTC (13 years, 5 months ago) by econte
Content type: text/plain
Branch: MAIN
CVS Tags: TBD2011, TBD_2011, HEAD
Error occurred while calculating annotation data.
Log Message:
TwoBodyDecay modif

File Contents

# Content
1
2 #include "FWCore/MessageLogger/interface/MessageLogger.h"
3 #include "MagneticField/Engine/interface/MagneticField.h"
4
5 #include "Alignment/TwoBodyDecay/interface/TwoBodyDecayEstimator.h"
6 #include "Alignment/TwoBodyDecay/interface/TwoBodyDecayModel.h"
7 #include "Alignment/TwoBodyDecay/interface/TwoBodyDecayDerivatives.h"
8 //#include "DataFormats/CLHEP/interface/Migration.h"
9
10 TwoBodyDecayEstimator::TwoBodyDecayEstimator( const edm::ParameterSet & config )
11 {
12 const edm::ParameterSet & estimatorConfig = config.getParameter< edm::ParameterSet >( "EstimatorParameters" );
13
14 theRobustificationConstant = estimatorConfig.getUntrackedParameter< double >( "RobustificationConstant", 1.0 );
15 theMaxIterDiff = estimatorConfig.getUntrackedParameter< double >( "MaxIterationDifference", 1e-2 );
16 theMaxIterations = estimatorConfig.getUntrackedParameter< int >( "MaxIterations", 100 );
17 theUseInvariantMass = estimatorConfig.getUntrackedParameter< bool >( "UseInvariantMass", true );
18 }
19
20
21 TwoBodyDecay TwoBodyDecayEstimator::estimate( const std::vector< RefCountedLinearizedTrackState > & linTracks,
22 const TwoBodyDecayParameters & linearizationPoint,
23 const TwoBodyDecayVirtualMeasurement & vm ) const
24 {
25 if ( linTracks.size() != 2 )
26 {
27 edm::LogInfo( "Alignment" ) << "@SUB=TwoBodyDecayEstimator::estimate"
28 << "Need 2 linearized tracks, got " << linTracks.size() << ".\n";
29 return TwoBodyDecay();
30 }
31
32 AlgebraicVector vecM;
33 AlgebraicSymMatrix matG;
34 AlgebraicMatrix matA;
35
36 bool check = constructMatrices( linTracks, linearizationPoint, vm, vecM, matG, matA );
37 if ( !check ) return TwoBodyDecay();
38
39 AlgebraicSymMatrix matGPrime;
40 AlgebraicSymMatrix invAtGPrimeA;
41 AlgebraicVector vecEstimate;
42 AlgebraicVector res;
43
44 int nIterations = 0;
45 bool stopIteration = false;
46
47 // initialization - values are never used
48 int checkInversion = 0;
49 double chi2 = 0.;
50 double oldChi2 = 0.;
51 bool isValid = true;
52
53 while( !stopIteration )
54 {
55 matGPrime = matG;
56
57 // compute weights
58 if ( nIterations > 0 )
59 {
60 for ( int i = 0; i < 10; i++ )
61 {
62 double sigma = 1./sqrt( matG[i][i] );
63 double sigmaTimesR = sigma*theRobustificationConstant;
64 double absRes = fabs( res[i] );
65 if ( absRes > sigmaTimesR ) matGPrime[i][i] *= sigmaTimesR/absRes;
66 }
67 }
68
69 // make LS-fit
70 invAtGPrimeA = ( matGPrime.similarityT(matA) ).inverse( checkInversion );
71 if ( checkInversion != 0 )
72 {
73 LogDebug( "Alignment" ) << "@SUB=TwoBodyDecayEstimator::estimate"
74 << "Matrix At*G'*A not invertible (in iteration " << nIterations
75 << ", ifail = " << checkInversion << ").\n";
76 isValid = false;
77 break;
78 }
79 vecEstimate = invAtGPrimeA*matA.T()*matGPrime*vecM;
80 res = matA*vecEstimate - vecM;
81 chi2 = dot( res, matGPrime*res );
82
83 if ( ( nIterations > 0 ) && ( fabs( chi2 - oldChi2 ) < theMaxIterDiff ) ) stopIteration = true;
84 if ( nIterations == theMaxIterations ) stopIteration = true;
85
86 oldChi2 = chi2;
87 nIterations++;
88 }
89
90 if ( isValid )
91 {
92 AlgebraicSymMatrix pullsCov = matGPrime.inverse( checkInversion ) - invAtGPrimeA.similarity( matA );
93 thePulls = AlgebraicVector( matG.num_col(), 0 );
94 for ( int i = 0; i < pullsCov.num_col(); i++ ) thePulls[i] = res[i]/sqrt( pullsCov[i][i] );
95 }
96
97 theNdf = matA.num_row() - matA.num_col();
98
99 return TwoBodyDecay( TwoBodyDecayParameters( vecEstimate, invAtGPrimeA ), chi2, isValid, vm );
100 }
101
102
103 bool TwoBodyDecayEstimator::constructMatrices( const std::vector< RefCountedLinearizedTrackState > & linTracks,
104 const TwoBodyDecayParameters & linearizationPoint,
105 const TwoBodyDecayVirtualMeasurement & vm,
106 AlgebraicVector & vecM, AlgebraicSymMatrix & matG, AlgebraicMatrix & matA ) const
107 {
108
109 PerigeeLinearizedTrackState* linTrack1 = dynamic_cast<PerigeeLinearizedTrackState*>( linTracks[0].get() );
110 PerigeeLinearizedTrackState* linTrack2 = dynamic_cast<PerigeeLinearizedTrackState*>( linTracks[1].get() );
111
112 AlgebraicVector trackParam1 = asHepVector( linTrack1->predictedStateParameters() );
113 AlgebraicVector trackParam2 = asHepVector( linTrack2->predictedStateParameters() );
114
115 if ( checkValues( trackParam1 ) || checkValues( trackParam2 ) || checkValues( linearizationPoint.parameters() ) ) return false;
116
117 AlgebraicVector vecLinParam = linearizationPoint.sub( TwoBodyDecayParameters::px,
118 TwoBodyDecayParameters::mass );
119
120 double zMagField = linTrack1->track().field()->inInverseGeV( linTrack1->linearizationPoint() ).z();
121
122 int checkInversion = 0;
123
124 TwoBodyDecayDerivatives tpeDerivatives( linearizationPoint[TwoBodyDecayParameters::mass], vm.secondaryMass() );
125 std::pair< AlgebraicMatrix, AlgebraicMatrix > derivatives = tpeDerivatives.derivatives( linearizationPoint );
126
127 TwoBodyDecayModel decayModel( linearizationPoint[TwoBodyDecayParameters::mass], vm.secondaryMass() );
128 std::pair< AlgebraicVector, AlgebraicVector > linCartMomenta = decayModel.cartesianSecondaryMomenta( linearizationPoint );
129
130 // first track
131 AlgebraicMatrix matA1 = asHepMatrix( linTrack1->positionJacobian() );
132 AlgebraicMatrix matB1 = asHepMatrix( linTrack1->momentumJacobian() );
133 AlgebraicVector vecC1 = asHepVector( linTrack1->constantTerm() );
134
135 AlgebraicVector curvMomentum1 = asHepVector( linTrack1->predictedStateMomentumParameters() );
136 AlgebraicMatrix curv2cart1 = decayModel.curvilinearToCartesianJacobian( curvMomentum1, zMagField );
137
138 AlgebraicVector cartMomentum1 = decayModel.convertCurvilinearToCartesian( curvMomentum1, zMagField );
139 vecC1 += matB1*( curvMomentum1 - curv2cart1*cartMomentum1 );
140 matB1 = matB1*curv2cart1;
141
142 AlgebraicMatrix matF1 = derivatives.first;
143 AlgebraicVector vecD1 = linCartMomenta.first - matF1*vecLinParam;
144 AlgebraicVector vecM1 = trackParam1 - vecC1 - matB1*vecD1;
145 AlgebraicSymMatrix covM1 = asHepMatrix( linTrack1->predictedStateError() );
146
147
148 AlgebraicSymMatrix matG1 = covM1.inverse( checkInversion );
149 if ( checkInversion != 0 )
150 {
151 LogDebug( "Alignment" ) << "@SUB=TwoBodyDecayEstimator::constructMatrices"
152 << "Matrix covM1 not invertible.";
153 return false;
154 }
155
156 // diagonalize for robustification
157 AlgebraicMatrix matU1 = diagonalize( &matG1 ).T();
158
159 // second track
160 AlgebraicMatrix matA2 = asHepMatrix( linTrack2->positionJacobian() );
161 AlgebraicMatrix matB2 = asHepMatrix( linTrack2->momentumJacobian() );
162 AlgebraicVector vecC2 = asHepVector( linTrack2->constantTerm() );
163
164 AlgebraicVector curvMomentum2 = asHepVector( linTrack2->predictedStateMomentumParameters() );
165 AlgebraicMatrix curv2cart2 = decayModel.curvilinearToCartesianJacobian( curvMomentum2, zMagField );
166
167 AlgebraicVector cartMomentum2 = decayModel.convertCurvilinearToCartesian( curvMomentum2, zMagField );
168 vecC2 += matB2*( curvMomentum2 - curv2cart2*cartMomentum2 );
169 matB2 = matB2*curv2cart2;
170
171 AlgebraicMatrix matF2 = derivatives.second;
172 AlgebraicVector vecD2 = linCartMomenta.second - matF2*vecLinParam;
173 AlgebraicVector vecM2 = trackParam2 - vecC2 - matB2*vecD2;
174 AlgebraicSymMatrix covM2 = asHepMatrix( linTrack2->predictedStateError() );
175
176 AlgebraicSymMatrix matG2 = covM2.inverse( checkInversion );
177 if ( checkInversion != 0 )
178 {
179 LogDebug( "Alignment" ) << "@SUB=TwoBodyDecayEstimator::constructMatrices"
180 << "Matrix covM2 not invertible.";
181 return false;
182 }
183
184 // diagonalize for robustification
185 AlgebraicMatrix matU2 = diagonalize( &matG2 ).T();
186
187 // combine first and second track
188 vecM = AlgebraicVector( 14, 0 );
189 vecM.sub( 1, matU1*vecM1 );
190 vecM.sub( 6, matU2*vecM2 );
191 // virtual measurement of the primary mass
192 vecM( 11 ) = vm.primaryMass();
193 // virtual measurement of the beam spot
194 vecM.sub( 12, vm.beamSpotPosition() );
195
196 // full weight matrix
197 matG = AlgebraicSymMatrix( 14, 0 );
198 matG.sub( 1, matG1 );
199 matG.sub( 6, matG2 );
200 // virtual measurement error of the primary mass
201 matG[10][10] = 1./( vm.primaryWidth()*vm.primaryWidth() );
202 // virtual measurement error of the beam spot
203 matG.sub( 12, vm.beamSpotError().inverse( checkInversion ) );
204
205 // full derivative matrix
206 matA = AlgebraicMatrix( 14, 9, 0 );
207 matA.sub( 1, 1, matU1*matA1 );
208 matA.sub( 6, 1, matU2*matA2 );
209 matA.sub( 1, 4, matU1*matB1*matF1 );
210 matA.sub( 6, 4, matU2*matB2*matF2 );
211 matA( 11, 9 ) = 1.;//mass
212 matA( 12, 1 ) = 1.;//vx
213 matA( 13, 2 ) = 1.;//vy
214 matA( 14, 3 ) = 1.;//vz
215
216 return true;
217 }
218
219
220 bool TwoBodyDecayEstimator::checkValues( const AlgebraicVector & vec ) const
221 {
222 bool isNan = false;
223 bool isInf = false;
224
225 for ( int i = 0; i < vec.num_col(); ++i )
226 {
227 isNan = isNan || std::isnan( vec[i] );
228 isInf = isInf || std::isinf( vec[i] );
229 }
230
231 return ( isNan || isInf );
232 }