2 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
5#include "FourMom/ErrorMatrixBase.h"
6#include "FourMom/ErrorMatrixPxPyPzE.h"
7#include "FourMom/ErrorMatrixEEtaPhiM.h"
8#include "FourMom/ErrorMatrixPtEtaPhiM.h"
9#include "FourMom/ErrorMatrixPtCotThPhiM.h"
10#include "FourMom/P4ErrorTransforms.h"
13template < class FourMom>
14FourMomentumError< FourMom>::FourMomentumError(const ErrorMatrixPxPyPzE& m,
17 m_PxPyPzE(std::make_unique<ErrorMatrixPxPyPzE>(m)),
20 m_PtCotThPhiM(nullptr),
21 m_originalType(PxPyPzE)
24template < class FourMom>
25FourMomentumError< FourMom>::FourMomentumError(const ErrorMatrixEEtaPhiM& m,
29 m_EEtaPhiM(std::make_unique<ErrorMatrixEEtaPhiM>(m)),
31 m_PtCotThPhiM(nullptr),
32 m_originalType(EEtaPhiM)
35template < class FourMom>
36FourMomentumError< FourMom>::FourMomentumError(const ErrorMatrixPtEtaPhiM& m,
41 m_PtEtaPhiM(std::make_unique<ErrorMatrixPtEtaPhiM>(m)),
42 m_PtCotThPhiM(nullptr),
43 m_originalType(PtEtaPhiM)
46template < class FourMom>
47FourMomentumError< FourMom>::FourMomentumError(const ErrorMatrixPtCotThPhiM& m,
53 m_PtCotThPhiM(std::make_unique<ErrorMatrixPtCotThPhiM>(m)),
54 m_originalType(PtCotThPhiM)
57template < class FourMom>
58FourMomentumError< FourMom>::FourMomentumError( const CLHEP::HepSymMatrix& m,
65 m_PtCotThPhiM(nullptr)
68 m_PxPyPzE.store (std::make_unique<ErrorMatrixPxPyPzE>( m));
69 m_originalType = PxPyPzE;
72 m_EEtaPhiM.store (std::make_unique<ErrorMatrixEEtaPhiM>( m));
73 m_originalType = EEtaPhiM;
75 if ( t == PtEtaPhiM) {
76 m_PtEtaPhiM.store (std::make_unique<ErrorMatrixPtEtaPhiM>( m));
77 m_originalType = PtEtaPhiM;
79 if ( t == PtCotThPhiM) {
80 m_PtCotThPhiM.store (std::make_unique<ErrorMatrixPtCotThPhiM>( m));
81 m_originalType = PtCotThPhiM;
85template < class FourMom>
86FourMomentumError< FourMom>::FourMomentumError( const FourMomentumError& other) :
92 m_PtCotThPhiM(nullptr),
93 m_originalType( other.originalType())
95 if (other.originalType() == PxPyPzE) {
96 m_PxPyPzE.store (std::make_unique<ErrorMatrixPxPyPzE>( *other.pxPyPzEMatrix()));
98 else if (other.originalType() == EEtaPhiM) {
99 m_EEtaPhiM.store (std::make_unique<ErrorMatrixEEtaPhiM>(*other.eEtaPhiMMatrix()));
101 else if (other.originalType() == PtEtaPhiM) {
102 m_PtEtaPhiM.store (std::make_unique<ErrorMatrixPtEtaPhiM>( *other.ptEtaPhiMMatrix()));
104 else if (other.originalType() == PtCotThPhiM) {
105 m_PtCotThPhiM.store (std::make_unique<ErrorMatrixPtCotThPhiM>( *other.ptCotThPhiMMatrix()));
110template < class FourMom>
111FourMomentumError< FourMom> &FourMomentumError<FourMom>::operator=( const FourMomentumError& other)
115 m_PxPyPzE.store (std::make_unique<ErrorMatrixPxPyPzE>());
116 m_EEtaPhiM.store (std::make_unique<ErrorMatrixEEtaPhiM>());
117 m_PtEtaPhiM.store (std::make_unique<ErrorMatrixPtEtaPhiM>());
118 m_PtCotThPhiM.store (std::make_unique<ErrorMatrixPtCotThPhiM>());
119 m_originalType = other.originalType();
121 if (other.originalType() == PxPyPzE) {
122 m_PxPyPzE.store (std::make_unique<ErrorMatrixPxPyPzE>( *other.pxPyPzEMatrix()));
124 else if (other.originalType() == EEtaPhiM) {
125 m_EEtaPhiM.store (std::make_unique<ErrorMatrixEEtaPhiM>(*other.eEtaPhiMMatrix()));
127 else if (other.originalType() == PtEtaPhiM) {
128 m_PtEtaPhiM.store (std::make_unique<ErrorMatrixPtEtaPhiM>( *other.ptEtaPhiMMatrix()));
130 else if (other.originalType() == PtCotThPhiM) {
131 m_PtCotThPhiM.store (std::make_unique<ErrorMatrixPtCotThPhiM>( *other.ptCotThPhiMMatrix()));
137template < class FourMom>
138const ErrorMatrixPxPyPzE* FourMomentumError< FourMom>::pxPyPzEMatrix() const
140 if (!m_PxPyPzE) computePxPyPzEMatrix();
141 return m_PxPyPzE.get();
144template < class FourMom>
145const ErrorMatrixEEtaPhiM* FourMomentumError< FourMom>::eEtaPhiMMatrix() const
147 if (!m_EEtaPhiM) computeEEtaPhiMMatrix();
148 return m_EEtaPhiM.get();
151template < class FourMom>
152const ErrorMatrixPtEtaPhiM* FourMomentumError< FourMom>::ptEtaPhiMMatrix() const
154 if (!m_PtEtaPhiM) computePtEtaPhiMMatrix();
155 return m_PtEtaPhiM.get();
158template < class FourMom>
159const ErrorMatrixPtCotThPhiM* FourMomentumError< FourMom>::ptCotThPhiMMatrix() const
161 return m_PtCotThPhiM.get();
162 // FIXME not implemented yet
165template < class FourMom>
166bool FourMomentumError< FourMom>::computePxPyPzEMatrix() const
168 using namespace P4ErrorTransforms;
170 if (m_originalType == EEtaPhiM) {
171 m_PxPyPzE.set(toPxPyPzE( *m_EEtaPhiM, m_p4.e(), m_p4.eta(), m_p4.phi(), m_p4.m()));
174 else if (m_originalType == PtEtaPhiM) {
175 //FIXME m_PxPyPzE = m_helper->pxPyPzE( *m_PtEtaPhiM);
178 else if (m_originalType == PtCotThPhiM) {
179 return false; // FIXME
181 else return false; // should never happen
184template < class FourMom>
185bool FourMomentumError< FourMom>::computeEEtaPhiMMatrix() const
187 using namespace P4ErrorTransforms;
189 if (m_originalType == PxPyPzE) {
190 m_EEtaPhiM.set(toEEtaPhiM( *m_PxPyPzE, m_p4.px(), m_p4.py(), m_p4.pz(), m_p4.e()));
193 else if (m_originalType == PtEtaPhiM) {
194 //FIXME m_EEtaPhiM = m_helper->eEtaPhiM( *m_PtEtaPhiM);
197 else if (m_originalType == PtCotThPhiM) {
198 return false; // FIXME
200 else return false; // should never happen
203template < class FourMom>
204bool FourMomentumError< FourMom>::computePtEtaPhiMMatrix() const
206 if (m_originalType == PxPyPzE) {
207 //FIXME m_PtEtaPhiM = m_helper->ptEtaPhiM( *m_PxPyPzE);
210 else if (m_originalType == EEtaPhiM) {
211 //FIXME m_PtEtaPhiM = m_helper->ptEtaPhiM( *m_EEtaPhiM);
214 else if (m_originalType == PtCotThPhiM) {
215 return false; // FIXME
217 else return false; // should never happen
220template < class FourMom>
221double FourMomentumError< FourMom>::pxError() const
223 const ErrorMatrixPxPyPzE* em = pxPyPzEMatrix();
225 return std::sqrt( (*em)(ErrorMatrixPxPyPzE::ipx));
230template < class FourMom>
231double FourMomentumError< FourMom>::pyError() const
233 const ErrorMatrixPxPyPzE* em = pxPyPzEMatrix();
235 return std::sqrt( (*em)(ErrorMatrixPxPyPzE::ipy));
240template < class FourMom>
241double FourMomentumError< FourMom>::pzError() const
243 const ErrorMatrixPxPyPzE* em = pxPyPzEMatrix();
245 return std::sqrt( (*em)(ErrorMatrixPxPyPzE::ipz));
250template < class FourMom>
251double FourMomentumError< FourMom>::mError() const
253 const ErrorMatrixEEtaPhiM* em = eEtaPhiMMatrix();
255 return std::sqrt( (*em)(ErrorMatrixEEtaPhiM::im));
260template < class FourMom>
261double FourMomentumError< FourMom>::m2Error() const
263 return 2* m_p4.m() * mError();
266template < class FourMom>
267double FourMomentumError< FourMom>::pError() const
269 if (m_originalType == PxPyPzE) {
270 const ErrorMatrixPxPyPzE* em = pxPyPzEMatrix();
272 double pxtmp = m_p4.px(); // avoid calling virtual methods multiple times
273 double pytmp = m_p4.py();
274 double pztmp = m_p4.pz();
276 sqr(pxtmp)*(*em)(ErrorMatrixPxPyPzE::ipx) +
277 sqr(pytmp)*(*em)(ErrorMatrixPxPyPzE::ipy) +
278 sqr(pztmp)*(*em)(ErrorMatrixPxPyPzE::ipz) +
279 2*pxtmp*pytmp*(*em)(ErrorMatrixPxPyPzE::ipx,ErrorMatrixPxPyPzE::ipy) +
280 2*pxtmp*pztmp*(*em)(ErrorMatrixPxPyPzE::ipx,ErrorMatrixPxPyPzE::ipz) +
281 2*pytmp*pztmp*(*em)(ErrorMatrixPxPyPzE::ipy,ErrorMatrixPxPyPzE::ipz);
282 return std::sqrt(sigma2/m_p4.p2()); // divide by p2 globally
286 const ErrorMatrixEEtaPhiM* em = eEtaPhiMMatrix();
288 double E = m_p4.e(); // avoid calling virtual methods multiple times
291 E*E*(*em)(ErrorMatrixEEtaPhiM::ie) +
292 M*M*(*em)(ErrorMatrixEEtaPhiM::im) -
293 E*M*(*em)(ErrorMatrixEEtaPhiM::ie,ErrorMatrixEEtaPhiM::im);
294 return std::sqrt(sigma2/m_p4.p2()); // divide by p2 globally
297 // FIXME: no optimized version for PtEtaPhiM
298 return 0; // in case no error matrix, should never happen
301template < class FourMom>
302double FourMomentumError< FourMom>::p2Error() const
304 return 2* m_p4.p() * pError();
307template < class FourMom>
308double FourMomentumError< FourMom>::eError() const
310 if (m_originalType == PxPyPzE) {
311 const ErrorMatrixPxPyPzE* em = pxPyPzEMatrix();
313 return std::sqrt( (*em)(ErrorMatrixPxPyPzE::ie));
318 const ErrorMatrixEEtaPhiM* em = eEtaPhiMMatrix();
320 return std::sqrt( (*em)(ErrorMatrixEEtaPhiM::ie));
326template < class FourMom>
327double FourMomentumError< FourMom>::etaError() const
329 const ErrorMatrixEEtaPhiM* em = eEtaPhiMMatrix();
331 return std::sqrt( (*em)(ErrorMatrixEEtaPhiM::ieta));
336template < class FourMom>
337double FourMomentumError< FourMom>::rapidityError() const
342template < class FourMom>
343double FourMomentumError< FourMom>::phiError() const
345 if (m_originalType == PtEtaPhiM) {
346 const ErrorMatrixPtEtaPhiM* em = ptEtaPhiMMatrix();
348 return std::sqrt( (*em)(ErrorMatrixPtEtaPhiM::iphi));
352 const ErrorMatrixEEtaPhiM* em = eEtaPhiMMatrix();
354 return std::sqrt( (*em)(ErrorMatrixEEtaPhiM::iphi));
357 return 0; // in case no error matrix, should never happen
360template < class FourMom>
361double FourMomentumError< FourMom>::etError() const
366template < class FourMom>
367double FourMomentumError< FourMom>::ptError() const
369 const ErrorMatrixPxPyPzE* em = pxPyPzEMatrix();
370 if (em == 0) return 0;
372 double pxtmp = m_p4.px(); // avoid calling virtual methods multiple times
373 double pytmp = m_p4.py();
375 sqr(pxtmp)*(*em)(ErrorMatrixPxPyPzE::ipx) +
376 sqr(pytmp)*(*em)(ErrorMatrixPxPyPzE::ipy) +
377 2*pxtmp*pytmp*(*em)(ErrorMatrixPxPyPzE::ipx,ErrorMatrixPxPyPzE::ipy);
378 return std::sqrt(sigma2)/m_p4.pt(); // divide by pt globally
382template < class FourMom>
383double FourMomentumError< FourMom>::iPtError() const
385 double p2tmp = m_p4.p2();
386 return p2tmp == 0? 0 : ptError() / p2tmp;
389template < class FourMom>
390double FourMomentumError< FourMom>::cosPhiError() const
392 const ErrorMatrixEEtaPhiM* em = eEtaPhiMMatrix();
393 if (em == 0) return 0;
395 return -m_p4.sinPhi() * std::sqrt( (*em)( ErrorMatrixEEtaPhiM::iphi));
397 // FIXME: missing optimization for ptEtaPhiMMatrix
400template < class FourMom>
401double FourMomentumError< FourMom>::sinPhiError() const
403 const ErrorMatrixEEtaPhiM* em = eEtaPhiMMatrix();
404 if (em == 0) return 0;
406 return m_p4.cosPhi() * std::sqrt( (*em)( ErrorMatrixEEtaPhiM::iphi));
408 // FIXME: missing optimization for ptEtaPhiMMatrix
411template < class FourMom>
412double FourMomentumError< FourMom>::cosThError() const
414 const ErrorMatrixEEtaPhiM* em = eEtaPhiMMatrix();
415 if (em == 0) return 0;
417 double t = exp(-m_p4.eta()); // intermediate variable
418 // derivative d(cosTheta)/d(theta/2)
419 double deriv_t = -4*t/sqr(1+t*t);
420 return std::abs( deriv_t * t) * std::sqrt( (*em)( ErrorMatrixEEtaPhiM::ieta));
422 // FIXME: missing optimization for ptEtaPhiMMatrix
425template < class FourMom>
426double FourMomentumError< FourMom>::sinThError() const
428 const ErrorMatrixEEtaPhiM* em = eEtaPhiMMatrix();
429 if (em == 0) return 0;
431 double t = exp(-m_p4.eta()); // intermediate variable
432 // derivative d(cosTheta)/d(theta/2)
433 double deriv_t = 2*(1-t*t)/sqr(1+t*t);
434 return std::abs( deriv_t * t) * std::sqrt( (*em)( ErrorMatrixEEtaPhiM::ieta));
436 // FIXME: missing optimization for ptEtaPhiMMatrix
439template < class FourMom>
440double FourMomentumError< FourMom>::tanThError() const
442 const ErrorMatrixEEtaPhiM* em = eEtaPhiMMatrix();
443 if (em == 0) return 0;
445 double t = exp(-m_p4.eta()); // intermediate variable
446 // derivative d(cosTheta)/d(theta/2)
447 double deriv_t = 2*(1+t*t)/sqr(1-t*t);
448 return std::abs( deriv_t * t) * std::sqrt( (*em)( ErrorMatrixEEtaPhiM::ieta));
450 // FIXME: missing optimization for ptEtaPhiMMatrix
453template < class FourMom>
454double FourMomentumError< FourMom>::cotThError() const
456 const ErrorMatrixEEtaPhiM* em = eEtaPhiMMatrix();
457 if (em == 0) return 0;
459 double t = exp(-m_p4.eta()); // intermediate variable
460 // derivative d(cosTheta)/d(theta/2)
461 double deriv_t = -(1+t*t)/(2*t*t);
462 return std::abs( deriv_t * t) * std::sqrt( (*em)( ErrorMatrixEEtaPhiM::ieta));
464 // FIXME: missing optimization for ptEtaPhiMMatrix