CMS 3D CMS Logo

TwoBodyDecayDerivatives.cc

Go to the documentation of this file.
00001 
00002 #include "Alignment/TwoBodyDecay/interface/TwoBodyDecayDerivatives.h"
00003 #include "Alignment/TwoBodyDecay/interface/TwoBodyDecayModel.h"
00004 
00005 #include "FWCore/Utilities/interface/Exception.h"
00006 
00007 #include <algorithm>
00008 
00009 using namespace std;
00010 
00011 
00012 TwoBodyDecayDerivatives::TwoBodyDecayDerivatives( double mPrimary, double mSecondary ) : 
00013   thePrimaryMass( mPrimary ), theSecondaryMass( mSecondary ) {}
00014 
00015 
00016 TwoBodyDecayDerivatives::~TwoBodyDecayDerivatives() {}
00017 
00018 
00019 const pair< AlgebraicMatrix, AlgebraicMatrix >
00020 TwoBodyDecayDerivatives::derivatives( const TwoBodyDecay & tbd )  const
00021 {
00022   return derivatives( tbd.decayParameters() );
00023 }
00024 
00025 const pair< AlgebraicMatrix, AlgebraicMatrix >
00026 TwoBodyDecayDerivatives::derivatives( const TwoBodyDecayParameters & param )  const
00027 {
00028   // get the derivatives with respect to all parameters
00029   pair< AlgebraicMatrix, AlgebraicMatrix > dqsdpx = this->dqsdpx( param );
00030   pair< AlgebraicMatrix, AlgebraicMatrix > dqsdpy = this->dqsdpy( param );
00031   pair< AlgebraicMatrix, AlgebraicMatrix > dqsdpz = this->dqsdpz( param );
00032   pair< AlgebraicMatrix, AlgebraicMatrix > dqsdtheta = this->dqsdtheta( param );
00033   pair< AlgebraicMatrix, AlgebraicMatrix > dqsdphi = this->dqsdphi( param );
00034   pair< AlgebraicMatrix, AlgebraicMatrix > dqsdm = this->dqsdm( param );
00035 
00036   AlgebraicMatrix dqplusdz( 3, dimension );
00037   dqplusdz.sub( 1, px, dqsdpx.first );
00038   dqplusdz.sub( 1, py, dqsdpy.first );
00039   dqplusdz.sub( 1, pz, dqsdpz.first );
00040   dqplusdz.sub( 1, theta, dqsdtheta.first );
00041   dqplusdz.sub( 1, phi, dqsdphi.first );
00042   dqplusdz.sub( 1, mass, dqsdm.first );
00043 
00044   AlgebraicMatrix dqminusdz( 3, dimension );
00045   dqminusdz.sub( 1, px, dqsdpx.second );
00046   dqminusdz.sub( 1, py, dqsdpy.second );
00047   dqminusdz.sub( 1, pz, dqsdpz.second );
00048   dqminusdz.sub( 1, theta, dqsdtheta.second );
00049   dqminusdz.sub( 1, phi, dqsdphi.second );
00050   dqminusdz.sub( 1, mass, dqsdm.second );
00051 
00052   return make_pair( dqplusdz, dqminusdz );
00053 }
00054 
00055 
00056 const pair< AlgebraicMatrix, AlgebraicMatrix >
00057 TwoBodyDecayDerivatives::selectedDerivatives( const TwoBodyDecay & tbd, const vector< bool > & selector ) const
00058 {
00059   return selectedDerivatives( tbd.decayParameters(), selector );
00060 }
00061 
00062 
00063 const pair< AlgebraicMatrix, AlgebraicMatrix >
00064 TwoBodyDecayDerivatives::selectedDerivatives( const TwoBodyDecayParameters & param, const vector< bool > & selector ) const
00065 {
00066   if ( selector.size() != dimension )
00067   {
00068     throw cms::Exception( "BadConfig" ) << "@SUB=TwoBodyDecayDerivatives::selectedDerivatives"
00069                                         << "selector has bad dimension (size=" << selector.size() << ").";
00070   }
00071 
00072   int nSelected = count( selector.begin(), selector.end(), true );
00073   int iSelected = 1;
00074 
00075   AlgebraicMatrix dqplusdz( 3, nSelected );
00076   AlgebraicMatrix dqminusdz( 3, nSelected );
00077   pair< AlgebraicMatrix, AlgebraicMatrix > dqsdzi;
00078 
00079   for ( unsigned int i = 1; i <= dimension; i++ )
00080   {
00081     if ( selector[i] )
00082     {
00083       dqsdzi = this->dqsdzi( param, DerivativeParameterName(i) );
00084       dqplusdz.sub( 1, iSelected, dqsdzi.first );
00085       dqminusdz.sub( 1, iSelected, dqsdzi.second );
00086       iSelected++;
00087     }
00088   }
00089 
00090   return make_pair( dqplusdz, dqminusdz );
00091 }
00092 
00093 
00094 const pair< AlgebraicMatrix, AlgebraicMatrix > TwoBodyDecayDerivatives::dqsdpx( const TwoBodyDecayParameters & param ) const
00095 {
00096   double px = param[TwoBodyDecayParameters::px];
00097   double py = param[TwoBodyDecayParameters::py];
00098   double pz = param[TwoBodyDecayParameters::pz];
00099   double theta = param[TwoBodyDecayParameters::theta];
00100   double phi = param[TwoBodyDecayParameters::phi];
00101 
00102   // compute transverse and absolute momentum
00103   double pT2 = px*px + py*py;
00104   double p2 = pT2 + pz*pz;
00105   double pT = sqrt( pT2 );
00106   double p = sqrt( p2 );
00107 
00108   double sphi = sin( phi );
00109   double cphi = cos( phi );
00110   double stheta = sin( theta );
00111   double ctheta = cos( theta );
00112 
00113   // some constants from kinematics
00114   double c1 = 0.5*thePrimaryMass/theSecondaryMass;
00115   double c2 = sqrt( c1*c1 - 1. );
00116   double c3 = 0.5*c2*ctheta/c1;
00117   double c4 = sqrt( p2 + thePrimaryMass*thePrimaryMass );
00118 
00119   // momentum of decay particle 1 in the primary's boosted frame
00120   AlgebraicMatrix pplus( 3, 1 );
00121   pplus[0][0] = theSecondaryMass*c2*stheta*cphi;
00122   pplus[1][0] = theSecondaryMass*c2*stheta*sphi;
00123   pplus[2][0] = 0.5*p + c3*c4;
00124 
00125   // momentum of decay particle 2 in the primary's boosted frame
00126   AlgebraicMatrix pminus( 3, 1 );
00127   pminus[0][0] = -pplus[0][0];
00128   pminus[1][0] = -pplus[1][0];
00129   pminus[2][0] = 0.5*p - c3*c4;
00130 
00131   // derivative of rotation matrix w.r.t. px
00132   AlgebraicMatrix dRotMatdpx( 3, 3 );
00133 
00134   dRotMatdpx[0][0] = pz/(pT*p)*(1.-px*px*(1./pT2+1./p2));
00135   dRotMatdpx[0][1] = px*py/(pT*pT2);
00136   dRotMatdpx[0][2] = (1.-px*px/p2)/p;
00137 
00138   dRotMatdpx[1][0] = -px*py*pz/(pT*p)*(1./pT2+1./p2);
00139   dRotMatdpx[1][1] = (1.-px*px/pT2)/pT;
00140   dRotMatdpx[1][2] = -px*py/(p*p2);
00141 
00142   dRotMatdpx[2][0] = -(1./pT-pT/p2)*px/p;
00143   dRotMatdpx[2][1] = 0.;
00144   dRotMatdpx[2][2] = -px*pz/(p*p2);
00145 
00146   // derivative of the momentum of particle 1 in the lab frame w.r.t. px
00147   double dpplusdpx = px*( 0.5/p + c3/c4 );
00148 
00149   AlgebraicMatrix dqplusdpx = dRotMatdpx*pplus;
00150   dqplusdpx[0][0] += px*dpplusdpx/p;
00151   dqplusdpx[1][0] += py*dpplusdpx/p;
00152   dqplusdpx[2][0] += pz*dpplusdpx/p;
00153 
00154   // derivative of the momentum of particle 2 in the lab frame w.r.t. px
00155   double dpminusdpx = px*( 0.5/p - c3/c4 );
00156 
00157   AlgebraicMatrix dqminusdpx = dRotMatdpx*pminus; 
00158   dqminusdpx[0][0] += px*dpminusdpx/p;
00159   dqminusdpx[1][0] += py*dpminusdpx/p;
00160   dqminusdpx[2][0] += pz*dpminusdpx/p;
00161 
00162   // return result
00163   return make_pair( dqplusdpx, dqminusdpx );
00164 }
00165 
00166 
00167 const pair< AlgebraicMatrix, AlgebraicMatrix > TwoBodyDecayDerivatives::dqsdpy( const TwoBodyDecayParameters & param ) const
00168 {
00169   double px = param[TwoBodyDecayParameters::px];
00170   double py = param[TwoBodyDecayParameters::py];
00171   double pz = param[TwoBodyDecayParameters::pz];
00172   double theta = param[TwoBodyDecayParameters::theta];
00173   double phi = param[TwoBodyDecayParameters::phi];
00174 
00175   // compute transverse and absolute momentum
00176   double pT2 = px*px + py*py;
00177   double p2 = pT2 + pz*pz;
00178   double pT = sqrt( pT2 );
00179   double p = sqrt( p2 );
00180 
00181   double sphi = sin( phi );
00182   double cphi = cos( phi );
00183   double stheta = sin( theta );
00184   double ctheta = cos( theta );
00185 
00186   // some constants from kinematics
00187   double c1 = 0.5*thePrimaryMass/theSecondaryMass;
00188   double c2 = sqrt( c1*c1 - 1. );
00189   double c3 = 0.5*c2*ctheta/c1;
00190   double c4 = sqrt( p2 + thePrimaryMass*thePrimaryMass );
00191 
00192   // momentum of decay particle 1 in the rest frame of the primary
00193   AlgebraicMatrix pplus( 3, 1 );
00194   pplus[0][0] = theSecondaryMass*c2*stheta*cphi;
00195   pplus[1][0] = theSecondaryMass*c2*stheta*sphi;
00196   pplus[2][0] = 0.5*p + c3*c4;
00197 
00198   // momentum of decay particle 2 in the rest frame of the primary
00199   AlgebraicMatrix pminus( 3, 1 );
00200   pminus[0][0] = -pplus[0][0];
00201   pminus[1][0] = -pplus[1][0];
00202   pminus[2][0] = 0.5*p - c3*c4;
00203 
00204   // derivative of rotation matrix w.r.t. py
00205   AlgebraicMatrix dRotMatdpy( 3, 3 );
00206 
00207   dRotMatdpy[0][0] = -px*py*pz/(pT*p)*(1./pT2+1./p2);
00208   dRotMatdpy[0][1] = (py*py/pT2-1.)/pT;
00209   dRotMatdpy[0][2] = -px*py/(p*p2);
00210 
00211   dRotMatdpy[1][0] = pz/(pT*p)*(1.-py*py*(1./pT2+1./p2));
00212   dRotMatdpy[1][1] = -px*py/(pT*pT2);
00213   dRotMatdpy[1][2] = (1.-py*py/p2)/p;
00214 
00215   dRotMatdpy[2][0] = -(1./pT-pT/p2)*py/p;
00216   dRotMatdpy[2][1] = 0.;
00217   dRotMatdpy[2][2] = -py*pz/(p*p2);
00218 
00219   // derivative of the momentum of particle 1 in the lab frame w.r.t. py
00220   double dpplusdpy = py*( 0.5/p + c3/c4 );
00221 
00222   AlgebraicMatrix dqplusdpy = dRotMatdpy*pplus;
00223   dqplusdpy[0][0] += px*dpplusdpy/p;
00224   dqplusdpy[1][0] += py*dpplusdpy/p;
00225   dqplusdpy[2][0] += pz*dpplusdpy/p;
00226 
00227   // derivative of the momentum of particle 2 in the lab frame w.r.t. py
00228   double dpminusdpy = py*( 0.5/p - c3/c4 );
00229 
00230   AlgebraicMatrix dqminusdpy = dRotMatdpy*pminus;
00231   dqminusdpy[0][0] += px*dpminusdpy/p;
00232   dqminusdpy[1][0] += py*dpminusdpy/p;
00233   dqminusdpy[2][0] += pz*dpminusdpy/p;
00234 
00235   // return result
00236   return make_pair( dqplusdpy, dqminusdpy );
00237 }
00238 
00239 
00240 const pair< AlgebraicMatrix, AlgebraicMatrix > TwoBodyDecayDerivatives::dqsdpz( const TwoBodyDecayParameters & param ) const
00241 {
00242   double px = param[TwoBodyDecayParameters::px];
00243   double py = param[TwoBodyDecayParameters::py];
00244   double pz = param[TwoBodyDecayParameters::pz];
00245   double theta = param[TwoBodyDecayParameters::theta];
00246   double phi = param[TwoBodyDecayParameters::phi];
00247 
00248   // compute transverse and absolute momentum
00249   double pT2 = px*px + py*py;
00250   double p2 = pT2 + pz*pz;
00251   double pT = sqrt( pT2 );
00252   double p = sqrt( p2 );
00253 
00254   double sphi = sin( phi );
00255   double cphi = cos( phi );
00256   double stheta = sin( theta );
00257   double ctheta = cos( theta );
00258 
00259   // some constants from kinematics
00260   double c1 = 0.5*thePrimaryMass/theSecondaryMass;
00261   double c2 = sqrt( c1*c1 - 1. );
00262   double c3 = 0.5*c2*ctheta/c1;
00263   double c4 = sqrt( p2 + thePrimaryMass*thePrimaryMass );
00264 
00265   // momentum of decay particle 1 in the rest frame of the primary
00266   AlgebraicMatrix pplus( 3, 1 );
00267   pplus[0][0] = theSecondaryMass*c2*stheta*cphi;
00268   pplus[1][0] = theSecondaryMass*c2*stheta*sphi;
00269   pplus[2][0] = 0.5*p + c3*c4;
00270 
00271   // momentum of decay particle 2 in the rest frame of the primary
00272   AlgebraicMatrix pminus( 3, 1 );
00273   pminus[0][0] = -pplus[0][0];
00274   pminus[1][0] = -pplus[1][0];
00275   pminus[2][0] = 0.5*p - c3*c4;
00276 
00277   // derivative of rotation matrix w.r.t. py
00278   AlgebraicMatrix dRotMatdpz( 3, 3 );
00279 
00280   dRotMatdpz[0][0] = px/(pT*p)*(1.-pz*pz/p2);
00281   dRotMatdpz[0][1] = 0.;
00282   dRotMatdpz[0][2] = -px*pz/(p*p2);
00283 
00284   dRotMatdpz[1][0] = py/(p*pT)*(1.-pz*pz/p2);
00285   dRotMatdpz[1][1] = 0.;
00286   dRotMatdpz[1][2] = -py*pz/(p*p2);
00287 
00288   dRotMatdpz[2][0] = pT*pz/(p*p2);
00289   dRotMatdpz[2][1] = 0.;
00290   dRotMatdpz[2][2] = (1.-pz*pz/p2)/p;
00291 
00292   // derivative of the momentum of particle 1 in the lab frame w.r.t. pz
00293   double dpplusdpz = pz*( 0.5/p + c3/c4 );
00294 
00295   AlgebraicMatrix dqplusdpz = dRotMatdpz*pplus;
00296   dqplusdpz[0][0] += px*dpplusdpz/p;
00297   dqplusdpz[1][0] += py*dpplusdpz/p;
00298   dqplusdpz[2][0] += pz*dpplusdpz/p;
00299 
00300   // derivative of the momentum of particle 2 in the lab frame w.r.t. pz
00301   double dpminusdpz = pz*( 0.5/p - c3/c4 );
00302 
00303   AlgebraicMatrix dqminusdpz = dRotMatdpz*pminus;
00304   dqminusdpz[0][0] += px*dpminusdpz/p;
00305   dqminusdpz[1][0] += py*dpminusdpz/p;
00306   dqminusdpz[2][0] += pz*dpminusdpz/p;
00307 
00308   // return result
00309   return make_pair( dqplusdpz, dqminusdpz );
00310 }
00311 
00312 
00313 const pair< AlgebraicMatrix, AlgebraicMatrix > TwoBodyDecayDerivatives::dqsdtheta( const TwoBodyDecayParameters & param ) const
00314 {
00315   double px = param[TwoBodyDecayParameters::px];
00316   double py = param[TwoBodyDecayParameters::py];
00317   double pz = param[TwoBodyDecayParameters::pz];
00318   double theta = param[TwoBodyDecayParameters::theta];
00319   double phi = param[TwoBodyDecayParameters::phi];
00320 
00321   // compute transverse and absolute momentum
00322   double pT2 = px*px + py*py;
00323   double p2 = pT2 + pz*pz;
00324 
00325   double sphi = sin( phi );
00326   double cphi = cos( phi );
00327   double stheta = sin( theta );
00328   double ctheta = cos( theta );
00329 
00330   // some constants from kinematics
00331   double c1 = 0.5*thePrimaryMass/theSecondaryMass;
00332   double c2 = sqrt( c1*c1 - 1. );
00333   double c3 = -0.5*c2*stheta/c1;
00334   double c4 = sqrt( p2 + thePrimaryMass*thePrimaryMass );
00335 
00336   // derivative of the momentum of particle 1 in the primary's rest frame w.r.t. theta
00337   AlgebraicMatrix dpplusdtheta( 3, 1 );
00338   dpplusdtheta[0][0] = theSecondaryMass*c2*ctheta*cphi;
00339   dpplusdtheta[1][0] = theSecondaryMass*c2*ctheta*sphi;
00340   dpplusdtheta[2][0] = c3*c4;
00341 
00342   // derivative of the momentum of particle 2 in the primary's rest frame w.r.t. theta
00343   AlgebraicMatrix dpminusdtheta( 3, 1 );
00344   dpminusdtheta[0][0] = -theSecondaryMass*c2*ctheta*cphi;
00345   dpminusdtheta[1][0] = -theSecondaryMass*c2*ctheta*sphi;
00346   dpminusdtheta[2][0] = -c3*c4;
00347 
00348   TwoBodyDecayModel decayModel;
00349   AlgebraicMatrix rotMat = decayModel.rotationMatrix( px, py, pz );
00350 
00351   AlgebraicMatrix dqplusdtheta = rotMat*dpplusdtheta;
00352   AlgebraicMatrix dqminusdtheta = rotMat*dpminusdtheta;
00353 
00354   return make_pair( dqplusdtheta, dqminusdtheta );
00355 }
00356 
00357 
00358 const pair< AlgebraicMatrix, AlgebraicMatrix > TwoBodyDecayDerivatives::dqsdphi( const TwoBodyDecayParameters & param ) const
00359 {
00360   double px = param[TwoBodyDecayParameters::px];
00361   double py = param[TwoBodyDecayParameters::py];
00362   double pz = param[TwoBodyDecayParameters::pz];
00363   double theta = param[TwoBodyDecayParameters::theta];
00364   double phi = param[TwoBodyDecayParameters::phi];
00365 
00366   double sphi = sin( phi );
00367   double cphi = cos( phi );
00368   double stheta = sin( theta );
00369 
00370   // some constants from kinematics
00371   double c1 = 0.5*thePrimaryMass/theSecondaryMass;
00372   double c2 = sqrt( c1*c1 - 1. );
00373 
00374   // derivative of the momentum of particle 1 in the primary's rest frame w.r.t. phi
00375   AlgebraicMatrix dpplusdphi( 3, 1 );
00376   dpplusdphi[0][0] = -theSecondaryMass*c2*stheta*sphi;
00377   dpplusdphi[1][0] = theSecondaryMass*c2*stheta*cphi;
00378   dpplusdphi[2][0] = 0.;
00379 
00380   // derivative of the momentum of particle 2 in the primary's rest frame w.r.t. phi
00381   AlgebraicMatrix dpminusdphi( 3, 1 );
00382   dpminusdphi[0][0] = theSecondaryMass*c2*stheta*sphi;
00383   dpminusdphi[1][0] = -theSecondaryMass*c2*stheta*cphi;
00384   dpminusdphi[2][0] = 0.;
00385 
00386   TwoBodyDecayModel decayModel;
00387   AlgebraicMatrix rotMat = decayModel.rotationMatrix( px, py, pz );
00388 
00389   AlgebraicMatrix dqplusdphi = rotMat*dpplusdphi;
00390   AlgebraicMatrix dqminusdphi = rotMat*dpminusdphi;
00391 
00392   return make_pair( dqplusdphi, dqminusdphi );
00393 }
00394 
00395 
00396 const pair< AlgebraicMatrix, AlgebraicMatrix > TwoBodyDecayDerivatives::dqsdm( const TwoBodyDecayParameters & param ) const
00397 {
00398   double px = param[TwoBodyDecayParameters::px];
00399   double py = param[TwoBodyDecayParameters::py];
00400   double pz = param[TwoBodyDecayParameters::pz];
00401   double theta = param[TwoBodyDecayParameters::theta];
00402   double phi = param[TwoBodyDecayParameters::phi];
00403 
00404   double pT2 = px*px + py*py;
00405   double p2 = pT2 + pz*pz;
00406 
00407   double sphi = sin( phi );
00408   double cphi = cos( phi );
00409   double ctheta = cos( theta );
00410   double stheta = sin( theta );
00411 
00412   // some constants from kinematics
00413   double c1 = 0.5*thePrimaryMass/theSecondaryMass;
00414   double c2 = 1./sqrt( c1*c1 - 1. );
00415   double m2 = thePrimaryMass*thePrimaryMass;
00416 
00417   // derivative of the momentum of particle 1 in the primary's rest frame w.r.t. the primary's mass
00418   AlgebraicMatrix dpplusdm( 3, 1 );
00419   dpplusdm[0][0] = c2*0.5*c1*stheta*cphi;
00420   dpplusdm[1][0] = c2*0.5*c1*stheta*sphi;
00421   dpplusdm[2][0] = c2*theSecondaryMass*( c1*c1 + p2/m2 )/sqrt( p2 + m2 )*ctheta;
00422 
00423   // derivative of the momentum of particle 2 in the primary's rest frame w.r.t. the primary's mass
00424   AlgebraicMatrix dpminusdm( 3, 1 );
00425   dpminusdm[0][0] = -dpplusdm[0][0];
00426   dpminusdm[1][0] = -dpplusdm[1][0];
00427   dpminusdm[2][0] = -dpplusdm[2][0];
00428 
00429   TwoBodyDecayModel decayModel;
00430   AlgebraicMatrix rotMat = decayModel.rotationMatrix( px, py, pz );
00431 
00432   AlgebraicMatrix dqplusdm = rotMat*dpplusdm;
00433   AlgebraicMatrix dqminusdm = rotMat*dpminusdm;
00434 
00435   return make_pair( dqplusdm, dqminusdm );
00436 }
00437 
00438 
00439 const pair< AlgebraicMatrix, AlgebraicMatrix >
00440 TwoBodyDecayDerivatives::dqsdzi( const TwoBodyDecayParameters & param, const DerivativeParameterName & i ) const
00441 {
00442   switch ( i )
00443   {
00444   case TwoBodyDecayDerivatives::px :
00445     return dqsdpx( param );
00446     break;
00447   case TwoBodyDecayDerivatives::py :
00448     return dqsdpy( param );
00449     break;
00450   case TwoBodyDecayDerivatives::pz :
00451     return dqsdpz( param );
00452     break;
00453   case TwoBodyDecayDerivatives::theta :
00454     return dqsdtheta( param );
00455     break;
00456   case TwoBodyDecayDerivatives::phi :
00457     return dqsdphi( param );
00458     break;
00459   case TwoBodyDecayDerivatives::mass :
00460     return dqsdm( param );
00461     break;
00462   default:
00463     throw cms::Exception( "BadConfig" ) << "@SUB=TwoBodyDecayDerivatives::dqsdzi"
00464                                         << "no decay parameter related to selector (" << i << ").";
00465   };
00466 
00467   return make_pair( AlgebraicMatrix( 3, 1, 0 ), AlgebraicMatrix( 3, 1, 0 ) );
00468 }

Generated on Tue Jun 9 17:25:05 2009 for CMSSW by  doxygen 1.5.4