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

File Contents

# Content
1
2 #include "Alignment/TwoBodyDecay/interface/TwoBodyDecayDerivatives.h"
3 #include "Alignment/TwoBodyDecay/interface/TwoBodyDecayModel.h"
4
5 #include "FWCore/Utilities/interface/Exception.h"
6
7 #include <algorithm>
8
9 TwoBodyDecayDerivatives::TwoBodyDecayDerivatives( double mPrimary, double mSecondary ) :
10 thePrimaryMass( mPrimary ), theSecondaryMass( mSecondary ) {}
11
12
13 TwoBodyDecayDerivatives::~TwoBodyDecayDerivatives() {}
14
15
16 const std::pair< AlgebraicMatrix, AlgebraicMatrix >
17 TwoBodyDecayDerivatives::derivatives( const TwoBodyDecay & tbd ) const
18 {
19 return derivatives( tbd.decayParameters() );
20 }
21
22 const std::pair< AlgebraicMatrix, AlgebraicMatrix >
23 TwoBodyDecayDerivatives::derivatives( const TwoBodyDecayParameters & param ) const
24 {
25 // get the derivatives with respect to all parameters
26 std::pair< AlgebraicMatrix, AlgebraicMatrix > dqsdpx = this->dqsdpx( param );
27 std::pair< AlgebraicMatrix, AlgebraicMatrix > dqsdpy = this->dqsdpy( param );
28 std::pair< AlgebraicMatrix, AlgebraicMatrix > dqsdpz = this->dqsdpz( param );
29 std::pair< AlgebraicMatrix, AlgebraicMatrix > dqsdtheta = this->dqsdtheta( param );
30 std::pair< AlgebraicMatrix, AlgebraicMatrix > dqsdphi = this->dqsdphi( param );
31 std::pair< AlgebraicMatrix, AlgebraicMatrix > dqsdm = this->dqsdm( param );
32
33 AlgebraicMatrix dqplusdz( 3, dimension );
34 dqplusdz.sub( 1, px, dqsdpx.first );
35 dqplusdz.sub( 1, py, dqsdpy.first );
36 dqplusdz.sub( 1, pz, dqsdpz.first );
37 dqplusdz.sub( 1, theta, dqsdtheta.first );
38 dqplusdz.sub( 1, phi, dqsdphi.first );
39 dqplusdz.sub( 1, mass, dqsdm.first );
40
41 AlgebraicMatrix dqminusdz( 3, dimension );
42 dqminusdz.sub( 1, px, dqsdpx.second );
43 dqminusdz.sub( 1, py, dqsdpy.second );
44 dqminusdz.sub( 1, pz, dqsdpz.second );
45 dqminusdz.sub( 1, theta, dqsdtheta.second );
46 dqminusdz.sub( 1, phi, dqsdphi.second );
47 dqminusdz.sub( 1, mass, dqsdm.second );
48
49 return std::make_pair( dqplusdz, dqminusdz );
50 }
51
52
53 const std::pair< AlgebraicMatrix, AlgebraicMatrix >
54 TwoBodyDecayDerivatives::selectedDerivatives( const TwoBodyDecay & tbd, const std::vector< bool > & selector ) const
55 {
56 return selectedDerivatives( tbd.decayParameters(), selector );
57 }
58
59
60 const std::pair< AlgebraicMatrix, AlgebraicMatrix >
61 TwoBodyDecayDerivatives::selectedDerivatives( const TwoBodyDecayParameters & param, const std::vector< bool > & selector ) const
62 {
63 if ( selector.size() != dimension )
64 {
65 throw cms::Exception( "BadConfig" ) << "@SUB=TwoBodyDecayDerivatives::selectedDerivatives"
66 << "selector has bad dimension (size=" << selector.size() << ").";
67 }
68
69 int nSelected = std::count( selector.begin(), selector.end(), true );
70 int iSelected = 1;
71
72 AlgebraicMatrix dqplusdz( 3, nSelected );
73 AlgebraicMatrix dqminusdz( 3, nSelected );
74 std::pair< AlgebraicMatrix, AlgebraicMatrix > dqsdzi;
75
76 for ( unsigned int i = 1; i <= dimension; i++ )
77 {
78 if ( selector[i] )
79 {
80 dqsdzi = this->dqsdzi( param, DerivativeParameterName(i) );
81 dqplusdz.sub( 1, iSelected, dqsdzi.first );
82 dqminusdz.sub( 1, iSelected, dqsdzi.second );
83 iSelected++;
84 }
85 }
86
87 return std::make_pair( dqplusdz, dqminusdz );
88 }
89
90
91 const std::pair< AlgebraicMatrix, AlgebraicMatrix > TwoBodyDecayDerivatives::dqsdpx( const TwoBodyDecayParameters & param ) const
92 {
93 double px = param[TwoBodyDecayParameters::px];
94 double py = param[TwoBodyDecayParameters::py];
95 double pz = param[TwoBodyDecayParameters::pz];
96 double theta = param[TwoBodyDecayParameters::theta];
97 double phi = param[TwoBodyDecayParameters::phi];
98
99 // compute transverse and absolute momentum
100 double pT2 = px*px + py*py;
101 double p2 = pT2 + pz*pz;
102 double pT = sqrt( pT2 );
103 double p = sqrt( p2 );
104
105 double sphi = sin( phi );
106 double cphi = cos( phi );
107 double stheta = sin( theta );
108 double ctheta = cos( theta );
109
110 // some constants from kinematics
111 double c1 = 0.5*thePrimaryMass/theSecondaryMass;
112 double c2 = sqrt( c1*c1 - 1. );
113 double c3 = 0.5*c2*ctheta/c1;
114 double c4 = sqrt( p2 + thePrimaryMass*thePrimaryMass );
115
116 // momentum of decay particle 1 in the primary's boosted frame
117 AlgebraicMatrix pplus( 3, 1 );
118 pplus[0][0] = theSecondaryMass*c2*stheta*cphi;
119 pplus[1][0] = theSecondaryMass*c2*stheta*sphi;
120 pplus[2][0] = 0.5*p + c3*c4;
121
122 // momentum of decay particle 2 in the primary's boosted frame
123 AlgebraicMatrix pminus( 3, 1 );
124 pminus[0][0] = -pplus[0][0];
125 pminus[1][0] = -pplus[1][0];
126 pminus[2][0] = 0.5*p - c3*c4;
127
128 // derivative of rotation matrix w.r.t. px
129 AlgebraicMatrix dRotMatdpx( 3, 3 );
130
131 dRotMatdpx[0][0] = pz/(pT*p)*(1.-px*px*(1./pT2+1./p2));
132 dRotMatdpx[0][1] = px*py/(pT*pT2);
133 dRotMatdpx[0][2] = (1.-px*px/p2)/p;
134
135 dRotMatdpx[1][0] = -px*py*pz/(pT*p)*(1./pT2+1./p2);
136 dRotMatdpx[1][1] = (1.-px*px/pT2)/pT;
137 dRotMatdpx[1][2] = -px*py/(p*p2);
138
139 dRotMatdpx[2][0] = -(1./pT-pT/p2)*px/p;
140 dRotMatdpx[2][1] = 0.;
141 dRotMatdpx[2][2] = -px*pz/(p*p2);
142
143 // derivative of the momentum of particle 1 in the lab frame w.r.t. px
144 double dpplusdpx = px*( 0.5/p + c3/c4 );
145
146 AlgebraicMatrix dqplusdpx = dRotMatdpx*pplus;
147 dqplusdpx[0][0] += px*dpplusdpx/p;
148 dqplusdpx[1][0] += py*dpplusdpx/p;
149 dqplusdpx[2][0] += pz*dpplusdpx/p;
150
151 // derivative of the momentum of particle 2 in the lab frame w.r.t. px
152 double dpminusdpx = px*( 0.5/p - c3/c4 );
153
154 AlgebraicMatrix dqminusdpx = dRotMatdpx*pminus;
155 dqminusdpx[0][0] += px*dpminusdpx/p;
156 dqminusdpx[1][0] += py*dpminusdpx/p;
157 dqminusdpx[2][0] += pz*dpminusdpx/p;
158
159 // return result
160 return std::make_pair( dqplusdpx, dqminusdpx );
161 }
162
163
164 const std::pair< AlgebraicMatrix, AlgebraicMatrix > TwoBodyDecayDerivatives::dqsdpy( const TwoBodyDecayParameters & param ) const
165 {
166 double px = param[TwoBodyDecayParameters::px];
167 double py = param[TwoBodyDecayParameters::py];
168 double pz = param[TwoBodyDecayParameters::pz];
169 double theta = param[TwoBodyDecayParameters::theta];
170 double phi = param[TwoBodyDecayParameters::phi];
171
172 // compute transverse and absolute momentum
173 double pT2 = px*px + py*py;
174 double p2 = pT2 + pz*pz;
175 double pT = sqrt( pT2 );
176 double p = sqrt( p2 );
177
178 double sphi = sin( phi );
179 double cphi = cos( phi );
180 double stheta = sin( theta );
181 double ctheta = cos( theta );
182
183 // some constants from kinematics
184 double c1 = 0.5*thePrimaryMass/theSecondaryMass;
185 double c2 = sqrt( c1*c1 - 1. );
186 double c3 = 0.5*c2*ctheta/c1;
187 double c4 = sqrt( p2 + thePrimaryMass*thePrimaryMass );
188
189 // momentum of decay particle 1 in the rest frame of the primary
190 AlgebraicMatrix pplus( 3, 1 );
191 pplus[0][0] = theSecondaryMass*c2*stheta*cphi;
192 pplus[1][0] = theSecondaryMass*c2*stheta*sphi;
193 pplus[2][0] = 0.5*p + c3*c4;
194
195 // momentum of decay particle 2 in the rest frame of the primary
196 AlgebraicMatrix pminus( 3, 1 );
197 pminus[0][0] = -pplus[0][0];
198 pminus[1][0] = -pplus[1][0];
199 pminus[2][0] = 0.5*p - c3*c4;
200
201 // derivative of rotation matrix w.r.t. py
202 AlgebraicMatrix dRotMatdpy( 3, 3 );
203
204 dRotMatdpy[0][0] = -px*py*pz/(pT*p)*(1./pT2+1./p2);
205 dRotMatdpy[0][1] = (py*py/pT2-1.)/pT;
206 dRotMatdpy[0][2] = -px*py/(p*p2);
207
208 dRotMatdpy[1][0] = pz/(pT*p)*(1.-py*py*(1./pT2+1./p2));
209 dRotMatdpy[1][1] = -px*py/(pT*pT2);
210 dRotMatdpy[1][2] = (1.-py*py/p2)/p;
211
212 dRotMatdpy[2][0] = -(1./pT-pT/p2)*py/p;
213 dRotMatdpy[2][1] = 0.;
214 dRotMatdpy[2][2] = -py*pz/(p*p2);
215
216 // derivative of the momentum of particle 1 in the lab frame w.r.t. py
217 double dpplusdpy = py*( 0.5/p + c3/c4 );
218
219 AlgebraicMatrix dqplusdpy = dRotMatdpy*pplus;
220 dqplusdpy[0][0] += px*dpplusdpy/p;
221 dqplusdpy[1][0] += py*dpplusdpy/p;
222 dqplusdpy[2][0] += pz*dpplusdpy/p;
223
224 // derivative of the momentum of particle 2 in the lab frame w.r.t. py
225 double dpminusdpy = py*( 0.5/p - c3/c4 );
226
227 AlgebraicMatrix dqminusdpy = dRotMatdpy*pminus;
228 dqminusdpy[0][0] += px*dpminusdpy/p;
229 dqminusdpy[1][0] += py*dpminusdpy/p;
230 dqminusdpy[2][0] += pz*dpminusdpy/p;
231
232 // return result
233 return std::make_pair( dqplusdpy, dqminusdpy );
234 }
235
236
237 const std::pair< AlgebraicMatrix, AlgebraicMatrix > TwoBodyDecayDerivatives::dqsdpz( const TwoBodyDecayParameters & param ) const
238 {
239 double px = param[TwoBodyDecayParameters::px];
240 double py = param[TwoBodyDecayParameters::py];
241 double pz = param[TwoBodyDecayParameters::pz];
242 double theta = param[TwoBodyDecayParameters::theta];
243 double phi = param[TwoBodyDecayParameters::phi];
244
245 // compute transverse and absolute momentum
246 double pT2 = px*px + py*py;
247 double p2 = pT2 + pz*pz;
248 double pT = sqrt( pT2 );
249 double p = sqrt( p2 );
250
251 double sphi = sin( phi );
252 double cphi = cos( phi );
253 double stheta = sin( theta );
254 double ctheta = cos( theta );
255
256 // some constants from kinematics
257 double c1 = 0.5*thePrimaryMass/theSecondaryMass;
258 double c2 = sqrt( c1*c1 - 1. );
259 double c3 = 0.5*c2*ctheta/c1;
260 double c4 = sqrt( p2 + thePrimaryMass*thePrimaryMass );
261
262 // momentum of decay particle 1 in the rest frame of the primary
263 AlgebraicMatrix pplus( 3, 1 );
264 pplus[0][0] = theSecondaryMass*c2*stheta*cphi;
265 pplus[1][0] = theSecondaryMass*c2*stheta*sphi;
266 pplus[2][0] = 0.5*p + c3*c4;
267
268 // momentum of decay particle 2 in the rest frame of the primary
269 AlgebraicMatrix pminus( 3, 1 );
270 pminus[0][0] = -pplus[0][0];
271 pminus[1][0] = -pplus[1][0];
272 pminus[2][0] = 0.5*p - c3*c4;
273
274 // derivative of rotation matrix w.r.t. py
275 AlgebraicMatrix dRotMatdpz( 3, 3 );
276
277 dRotMatdpz[0][0] = px/(pT*p)*(1.-pz*pz/p2);
278 dRotMatdpz[0][1] = 0.;
279 dRotMatdpz[0][2] = -px*pz/(p*p2);
280
281 dRotMatdpz[1][0] = py/(p*pT)*(1.-pz*pz/p2);
282 dRotMatdpz[1][1] = 0.;
283 dRotMatdpz[1][2] = -py*pz/(p*p2);
284
285 dRotMatdpz[2][0] = pT*pz/(p*p2);
286 dRotMatdpz[2][1] = 0.;
287 dRotMatdpz[2][2] = (1.-pz*pz/p2)/p;
288
289 // derivative of the momentum of particle 1 in the lab frame w.r.t. pz
290 double dpplusdpz = pz*( 0.5/p + c3/c4 );
291
292 AlgebraicMatrix dqplusdpz = dRotMatdpz*pplus;
293 dqplusdpz[0][0] += px*dpplusdpz/p;
294 dqplusdpz[1][0] += py*dpplusdpz/p;
295 dqplusdpz[2][0] += pz*dpplusdpz/p;
296
297 // derivative of the momentum of particle 2 in the lab frame w.r.t. pz
298 double dpminusdpz = pz*( 0.5/p - c3/c4 );
299
300 AlgebraicMatrix dqminusdpz = dRotMatdpz*pminus;
301 dqminusdpz[0][0] += px*dpminusdpz/p;
302 dqminusdpz[1][0] += py*dpminusdpz/p;
303 dqminusdpz[2][0] += pz*dpminusdpz/p;
304
305 // return result
306 return std::make_pair( dqplusdpz, dqminusdpz );
307 }
308
309
310 const std::pair< AlgebraicMatrix, AlgebraicMatrix > TwoBodyDecayDerivatives::dqsdtheta( const TwoBodyDecayParameters & param ) const
311 {
312 double px = param[TwoBodyDecayParameters::px];
313 double py = param[TwoBodyDecayParameters::py];
314 double pz = param[TwoBodyDecayParameters::pz];
315 double theta = param[TwoBodyDecayParameters::theta];
316 double phi = param[TwoBodyDecayParameters::phi];
317
318 // compute transverse and absolute momentum
319 double pT2 = px*px + py*py;
320 double p2 = pT2 + pz*pz;
321
322 double sphi = sin( phi );
323 double cphi = cos( phi );
324 double stheta = sin( theta );
325 double ctheta = cos( theta );
326
327 // some constants from kinematics
328 double c1 = 0.5*thePrimaryMass/theSecondaryMass;
329 double c2 = sqrt( c1*c1 - 1. );
330 double c3 = -0.5*c2*stheta/c1;
331 double c4 = sqrt( p2 + thePrimaryMass*thePrimaryMass );
332
333 // derivative of the momentum of particle 1 in the primary's rest frame w.r.t. theta
334 AlgebraicMatrix dpplusdtheta( 3, 1 );
335 dpplusdtheta[0][0] = theSecondaryMass*c2*ctheta*cphi;
336 dpplusdtheta[1][0] = theSecondaryMass*c2*ctheta*sphi;
337 dpplusdtheta[2][0] = c3*c4;
338
339 // derivative of the momentum of particle 2 in the primary's rest frame w.r.t. theta
340 AlgebraicMatrix dpminusdtheta( 3, 1 );
341 dpminusdtheta[0][0] = -theSecondaryMass*c2*ctheta*cphi;
342 dpminusdtheta[1][0] = -theSecondaryMass*c2*ctheta*sphi;
343 dpminusdtheta[2][0] = -c3*c4;
344
345 TwoBodyDecayModel decayModel;
346 AlgebraicMatrix rotMat = decayModel.rotationMatrix( px, py, pz );
347
348 AlgebraicMatrix dqplusdtheta = rotMat*dpplusdtheta;
349 AlgebraicMatrix dqminusdtheta = rotMat*dpminusdtheta;
350
351 return std::make_pair( dqplusdtheta, dqminusdtheta );
352 }
353
354
355 const std::pair< AlgebraicMatrix, AlgebraicMatrix > TwoBodyDecayDerivatives::dqsdphi( const TwoBodyDecayParameters & param ) const
356 {
357 double px = param[TwoBodyDecayParameters::px];
358 double py = param[TwoBodyDecayParameters::py];
359 double pz = param[TwoBodyDecayParameters::pz];
360 double theta = param[TwoBodyDecayParameters::theta];
361 double phi = param[TwoBodyDecayParameters::phi];
362
363 double sphi = sin( phi );
364 double cphi = cos( phi );
365 double stheta = sin( theta );
366
367 // some constants from kinematics
368 double c1 = 0.5*thePrimaryMass/theSecondaryMass;
369 double c2 = sqrt( c1*c1 - 1. );
370
371 // derivative of the momentum of particle 1 in the primary's rest frame w.r.t. phi
372 AlgebraicMatrix dpplusdphi( 3, 1 );
373 dpplusdphi[0][0] = -theSecondaryMass*c2*stheta*sphi;
374 dpplusdphi[1][0] = theSecondaryMass*c2*stheta*cphi;
375 dpplusdphi[2][0] = 0.;
376
377 // derivative of the momentum of particle 2 in the primary's rest frame w.r.t. phi
378 AlgebraicMatrix dpminusdphi( 3, 1 );
379 dpminusdphi[0][0] = theSecondaryMass*c2*stheta*sphi;
380 dpminusdphi[1][0] = -theSecondaryMass*c2*stheta*cphi;
381 dpminusdphi[2][0] = 0.;
382
383 TwoBodyDecayModel decayModel;
384 AlgebraicMatrix rotMat = decayModel.rotationMatrix( px, py, pz );
385
386 AlgebraicMatrix dqplusdphi = rotMat*dpplusdphi;
387 AlgebraicMatrix dqminusdphi = rotMat*dpminusdphi;
388
389 return std::make_pair( dqplusdphi, dqminusdphi );
390 }
391
392
393 const std::pair< AlgebraicMatrix, AlgebraicMatrix > TwoBodyDecayDerivatives::dqsdm( const TwoBodyDecayParameters & param ) const
394 {
395 double px = param[TwoBodyDecayParameters::px];
396 double py = param[TwoBodyDecayParameters::py];
397 double pz = param[TwoBodyDecayParameters::pz];
398 double theta = param[TwoBodyDecayParameters::theta];
399 double phi = param[TwoBodyDecayParameters::phi];
400
401 double pT2 = px*px + py*py;
402 double p2 = pT2 + pz*pz;
403
404 double sphi = sin( phi );
405 double cphi = cos( phi );
406 double ctheta = cos( theta );
407 double stheta = sin( theta );
408
409 // some constants from kinematics
410 double c1 = 0.5*thePrimaryMass/theSecondaryMass;
411 double c2 = 1./sqrt( c1*c1 - 1. );
412 double m2 = thePrimaryMass*thePrimaryMass;
413
414 // derivative of the momentum of particle 1 in the primary's rest frame w.r.t. the primary's mass
415 AlgebraicMatrix dpplusdm( 3, 1 );
416 dpplusdm[0][0] = c2*0.5*c1*stheta*cphi;
417 dpplusdm[1][0] = c2*0.5*c1*stheta*sphi;
418 dpplusdm[2][0] = c2*theSecondaryMass*( c1*c1 + p2/m2 )/sqrt( p2 + m2 )*ctheta;
419
420 // derivative of the momentum of particle 2 in the primary's rest frame w.r.t. the primary's mass
421 AlgebraicMatrix dpminusdm( 3, 1 );
422 dpminusdm[0][0] = -dpplusdm[0][0];
423 dpminusdm[1][0] = -dpplusdm[1][0];
424 dpminusdm[2][0] = -dpplusdm[2][0];
425
426 TwoBodyDecayModel decayModel;
427 AlgebraicMatrix rotMat = decayModel.rotationMatrix( px, py, pz );
428
429 AlgebraicMatrix dqplusdm = rotMat*dpplusdm;
430 AlgebraicMatrix dqminusdm = rotMat*dpminusdm;
431
432 return std::make_pair( dqplusdm, dqminusdm );
433 }
434
435
436 const std::pair< AlgebraicMatrix, AlgebraicMatrix >
437 TwoBodyDecayDerivatives::dqsdzi( const TwoBodyDecayParameters & param, const DerivativeParameterName & i ) const
438 {
439 switch ( i )
440 {
441 case TwoBodyDecayDerivatives::px :
442 return dqsdpx( param );
443 break;
444 case TwoBodyDecayDerivatives::py :
445 return dqsdpy( param );
446 break;
447 case TwoBodyDecayDerivatives::pz :
448 return dqsdpz( param );
449 break;
450 case TwoBodyDecayDerivatives::theta :
451 return dqsdtheta( param );
452 break;
453 case TwoBodyDecayDerivatives::phi :
454 return dqsdphi( param );
455 break;
456 case TwoBodyDecayDerivatives::mass :
457 return dqsdm( param );
458 break;
459 default:
460 throw cms::Exception( "BadConfig" ) << "@SUB=TwoBodyDecayDerivatives::dqsdzi"
461 << "no decay parameter related to selector (" << i << ").";
462 };
463
464 return std::make_pair( AlgebraicMatrix( 3, 1, 0 ), AlgebraicMatrix( 3, 1, 0 ) );
465 }