CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoTracker/ConversionSeedGenerators/src/Conv4HitsReco.cc

Go to the documentation of this file.
00001 #define Conv4HitsReco_cxx
00002 #include "RecoTracker/ConversionSeedGenerators/interface/Conv4HitsReco.h"
00003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00004 #include <sstream>
00005 // 1 -> 4
00006 // 2 -> 3
00007 // 3 -> 2
00008 // 4 -> 1
00009 
00010 double Conv4HitsReco::GetDm(){
00011 
00012   return (Tq*O0-T0*Oq)/(Tq*Om-Tm*Oq); //dm
00013   
00014 }
00015 
00016 double Conv4HitsReco::GetDq(){
00017 
00018   return (Tm*O0-T0*Om)/(Tm*Oq-Tq*Om); //dq
00019   
00020 }
00021 
00022 void Conv4HitsReco::SetLinSystCoeff(double m, double q){
00023   
00024   // dq*Tq + dm*Tm = T0 // Tangent condition
00025   // dq*Oq + dm*Om = O0 // Orthogonality condition
00026 
00027   double sqrtEta2mm = sqrt(_eta2+m*m);
00028   double sqrtPi2qq = sqrt(_pi2+q*q);
00029 
00030   double signT = 1.;
00031 
00032   Tq = -2.*pPN+2.*m*pn+signT*2.*q*sqrtEta2mm/sqrtPi2qq;
00033   Tm =  2.*nPN+2.*q*pn+signT*2.*m*sqrtPi2qq/sqrtEta2mm;
00034   T0 = PN2-_eta2-_pi2-2.*q*m*pn+2.*q*pPN-2.*m*nPN-signT*2.*sqrtEta2mm*sqrtPi2qq;
00035   
00036   TVector3 vQminusM = q*unitVp - m*unitVn + vPminusN;
00037   double QM = vQminusM.Mag();
00038   double pQM = unitVp*vQminusM;
00039   double nQM = unitVn*vQminusM;
00040   double NVQM = vNminusV*vQminusM;
00041   
00042   double signO = 1.;
00043 
00044   Oq = sqrtEta2mm*pQM/QM+m*pn+pNV;
00045   Om = m*QM/sqrtEta2mm-signO*sqrtEta2mm*nQM/QM+nQM-nNV-m;
00046   O0 = -signO*sqrtEta2mm*QM-m*nQM-NVQM;
00047 
00048 }
00049 
00050 std::string Conv4HitsReco::qFromM_print(double m){
00051   std::stringstream ss;
00052   TVector3 vPminusM = vPminusN - m*unitVn;
00053   double m2 = m*m;
00054   double nPM = unitVn*vPminusM;
00055   double pPM = unitVp*vPminusM;
00056   double NVPM = vNminusV*vPminusM;
00057 
00058   double alpha = (m*pn+pNV)*(m*pn+pNV)-_eta2-m2;
00059   double beta = m2*pn*nPM+m*pn*NVPM+m*nPM*pNV-pPM*(_eta2+m2)+pNV*NVPM;
00060   double gamma = m2*nPM*nPM+NVPM*NVPM+2.*m*nPM*NVPM-vPminusM.Mag2()*(_eta2+m2);
00061 
00062   double disc = sqrt(beta*beta - alpha*gamma);
00063 
00064   double q01 = (-beta+disc)/alpha;
00065   double q02 = (-beta-disc)/alpha;
00066 
00067 
00068   ss << " m: " << m << " q01: " << std::setw(20) << q01 << " q02: "<< std::setw(20) << q02 << "/n";  
00069   return ss.str();
00070 }
00071 
00072 double Conv4HitsReco::qFromM(double m){
00073 
00074   LogDebug("Conv4HitsReco")<<qFromM_print(m);
00075   return 0.;
00076 
00077 }
00078 
00079 TVector3 Conv4HitsReco::GetPlusCenter(double &radius){
00080   radius = plusRadius;
00081   return plusCenter;
00082 }
00083 
00084 TVector3 Conv4HitsReco::GetMinusCenter(double &radius){
00085   radius = minusRadius;
00086   return minusCenter;
00087 }
00088 
00089 //
00090 //Point of intersection between two lines (each identified by a vector and a point)
00091 TVector3 Conv4HitsReco::GetIntersection(TVector3& V1, TVector3& p1, TVector3& V2, TVector3& p2){
00092 
00093   TVector3 v1 = V1.Unit();
00094   TVector3 v2 = V2.Unit();
00095   
00096   double v1v2=v1*v2;
00097   return v2*((p1 - p2)*(v1v2*v1-v2)/(v1v2*v1v2-1.))+p2;
00098 
00099 }
00100 
00101 double Conv4HitsReco::GetPtFromParamAndHitPair(double &m, double &eta){
00102 
00103   return 0.01*0.3*3.8*sqrt(m*m+eta*eta);
00104 
00105 }
00106 
00107 double Conv4HitsReco::GetPtMinusFromParam(double &m){
00108 
00109   return GetPtFromParamAndHitPair(m, _eta);
00110 
00111 }
00112 
00113 double Conv4HitsReco::GetPtPlusFromParam(double &q){
00114 
00115   return GetPtFromParamAndHitPair(q, _pi);
00116 
00117 }
00118 
00119 TVector3 Conv4HitsReco::GetConvVertexFromParams(double &m, double &q){
00120 
00121   TVector3 unitVQminusM = (plusCenter-minusCenter).Unit();
00122   TVector3 vtxViaPlus = vP+q*unitVp-plusRadius*unitVQminusM;
00123   TVector3 vtxViaMinus = vN+m*unitVn+minusRadius*unitVQminusM;
00124 
00125   //  return 0.5*(vN+m*unitVn+m*unitVQminusM+vP+q*unitVp-q*unitVQminusM);
00126   LogDebug("Conv4HitsReco")  << ">>>>>>>> Conversion vertex computed via Plus pair\n"
00127                              << vtxViaPlus
00128                              << ">>>>>>>> Conversion vertex computed via Minus pair\n"
00129                              << vtxViaMinus;
00130 
00131   return 0.5*(vtxViaPlus+vtxViaMinus);
00132 
00133 }
00134 
00135 int Conv4HitsReco::ConversionCandidate(TVector3 &vtx, double &ptplus, double &ptminus){
00136 
00137   double m;
00138   double q;
00139   int nits = 0;
00140 
00141   int isNotValidBefore = ComputeMaxLimits()+ComputeMinLimits();
00142   int isNotValidAfter = 0;
00143   if ( ! isNotValidBefore ){
00144 
00145     GuessStartingValues(m, q);
00146     nits = mqFindByIteration(m, q);
00147     
00148     if ( q > qMaxLimit || q < qMinLimit ) {
00149       isNotValidAfter = 1;
00150       LogDebug("Conv4HitsReco")<< ">>>>>>>> quad result not valid for q: qMin= " << qMinLimit << " q= " << q << " qMax=  " << qMaxLimit << "\n";
00151 
00152     }
00153     if ( m > mMaxLimit || m < mMinLimit ) {
00154       isNotValidAfter = 1;
00155       LogDebug("Conv4HitsReco")<<">>>>>>>> quad result not valid for m: mMin= " << mMinLimit << " m= " << m << " mMax=  " << mMaxLimit << "\n";
00156     }
00157     
00158     ptminus = GetPtMinusFromParam(m);
00159     ptplus = GetPtPlusFromParam(q);
00160     minusCenter = vN+m*unitVn; 
00161     minusRadius = (hit4-minusCenter).Mag();
00162     plusCenter = vP+q*unitVp;
00163     plusRadius = (hit1-plusCenter).Mag();
00164     convVtx = GetConvVertexFromParams(m, q);
00165     vtx = convVtx;
00166 
00167   }
00168 
00169   if ( isNotValidBefore ) return 0;
00170   if ( IsNotValidForPtLimit(m, q, ptLegMinCut, ptLegMaxCut) ) return -1000;
00171   if ( IsNotValidForVtxPosition(maxVtxDistance) ) return -2000;
00172   if ( isNotValidAfter ) return -1*nits;
00173   return nits;
00174 
00175 }
00176 
00177 int Conv4HitsReco::mqFindByIteration(double &m, double &q){
00178 
00179   int maxIte = maxNumberOfIterations;
00180   double err = iterationStopRelThreshold;
00181   double edm = 1.;
00182   double edq = 1.;
00183   int i = 0;
00184   while ( ((edq > err) || (edm > err)) && (i < maxIte) ){
00185     SetLinSystCoeff(m,q);
00186     double dm = GetDm();
00187     double dq = GetDq();
00188     /*    
00189           while( m+dm > mMaxLimit || m+dm < mMinLimit || q+dq > qMaxLimit || q+dq < qMinLimit ){
00190 
00191           LogDebug("Conv4HitsReco")<<">>>>>>>> Going outside limits, reducing increments \n";
00192           dm=dm/2.;
00193           dq=dq/2.;
00194           }
00195     */
00196     m+=dm;
00197     q+=dq;
00198     edm = fabs(dm/m);
00199     edq = fabs(dq/q);
00200     LogDebug("Conv4HitsReco")<< ">>>>>>>> Iteration " << i << " m: " << m << " q: " << q << " dm: " << dm << " dq: " << dq << " edm: " << edm << " edq: " << edq << "\n";
00201     i++;
00202   }
00203 
00204   return i;
00205 
00206 }
00207 
00208 int Conv4HitsReco::ComputeMaxLimits(){
00209 
00210   // Q max limit
00211   TVector3 vVminusHit2Orthogonal = (vV-hit2).Orthogonal();
00212   TVector3 medianPointHit2V = 0.5*(vV+hit2);
00213   vQMaxLimit = GetIntersection(vVminusHit2Orthogonal, medianPointHit2V, unitVp, vP);
00214   qMaxLimit = (vQMaxLimit-vP).Mag();
00215 
00216   // M max limit
00217   TVector3 vVminusHit3Orthogonal = (vV-hit3).Orthogonal();
00218   TVector3 medianPointHit3V = 0.5*(vV+hit3);
00219   vMMaxLimit = GetIntersection(vVminusHit3Orthogonal, medianPointHit3V, unitVn, vN);
00220   mMaxLimit = (vMMaxLimit-vN).Mag();
00221 
00222   LogDebug("Conv4HitsReco")<< " >>>>>> Limits: qMax= " << qMaxLimit << " ==>pt " << GetPtFromParamAndHitPair(qMaxLimit, _pi)  << " mMax= " << mMaxLimit << " ==>pt " <<GetPtFromParamAndHitPair(mMaxLimit, _eta) << "\n"; 
00223 
00224   return IsNotValidForPtLimit(mMaxLimit, qMaxLimit, ptLegMinCut, 100000.); //Max limit not applied here
00225 
00226 }
00227 
00228 int Conv4HitsReco::IsNotValidForPtLimit(double m, double q, double ptmin, double ptmax){
00229 
00230   if ( GetPtFromParamAndHitPair(q, _pi) < ptmin ) return 1;
00231   if ( GetPtFromParamAndHitPair(m, _eta) < ptmin ) return 1;
00232   if ( GetPtFromParamAndHitPair(q, _pi) > ptmax ) return 1;
00233   if ( GetPtFromParamAndHitPair(m, _eta) > ptmax ) return 1;
00234   return 0;
00235 
00236 }
00237 
00238 int Conv4HitsReco::IsNotValidForVtxPosition(double& maxDist){
00239 
00240   TVector3 hitAve = 0.25*(hit1+hit2+hit3+hit4); 
00241   if ( (convVtx-hitAve).Mag() > maxDist ) return 1;
00242   return 0;
00243 
00244 }
00245 
00246 int Conv4HitsReco::ComputeMinLimits(){
00247 
00248   //Evaluate if quad is valid and compute min limits 
00249   if ( ((vV-vQMaxLimit).Cross(vMMaxLimit-vQMaxLimit)).Z() > 0. ){
00250     //
00251     //Quad is invalid
00252     LogDebug("Conv4HitsReco")<< " >>>>>> Quad is invalid\n"; 
00253     return 1;
00254   } else {
00255     //
00256     // Compute q and m Min limits
00257     TVector3 vQMinLimit = GetIntersection(v1minus2, vMMaxLimit, unitVp, vP);
00258     qMinLimit = (vQMinLimit-vP)*unitVp;
00259     TVector3 vMMinLimit = GetIntersection(v3minus4, vQMaxLimit, unitVn, vN);
00260     mMinLimit = (vMMinLimit-vN)*unitVn;
00261     if ( mMinLimit > mMaxLimit || qMinLimit > qMaxLimit ){
00262       LogDebug("Conv4HitsReco")<< " >>>>>> Quad is invalid. qMin= " << qMinLimit << " mMin= " << mMinLimit << "\n"; 
00263       return 2;
00264     }
00265     if ( IsNotValidForPtLimit(mMinLimit, qMinLimit, -1000., ptLegMaxCut) ){ //Min limit not applied here
00266       return 2;
00267     }
00268 
00269     LogDebug("Conv4HitsReco")<< " >>>>>> Quad is valid. qMin= " << qMinLimit << " mMin= " << mMinLimit << "\n"; 
00270     return 0;
00271   }
00272 
00273 }
00274 
00275 int Conv4HitsReco::GuessStartingValues(double &m, double &q){
00276 
00277   /*
00278   m = 0.5*(mMinLimit+mMaxLimit);
00279   q = 0.5*(qMinLimit+qMaxLimit);
00280   */
00281 
00282   m = mMaxLimit;
00283   q = qMaxLimit;
00284 
00285   LogDebug("Conv4HitsReco")<< " >>>>>> Starting values: q= " << q << " m= " << m << "\n"; 
00286 
00287   return 0;
00288 
00289 }
00290 
00291 
00292 void Conv4HitsReco::Dump(){
00293 
00294   LogDebug("Conv4HitsReco")
00295     << " ======================================= " << "\n"
00296     << " Photon Vertex: "
00297     << vV
00298     << " Hit1: "
00299     << hit1
00300     << " Hit2: "
00301     << hit2
00302     << " Hit3: "
00303     << hit3
00304     << " Hit4: "
00305     << hit4
00306     << " N: "
00307     << vN
00308     << " P: "
00309     << vP
00310     << " P-N: "
00311     << vPminusN
00312     << " n: "
00313     << unitVn
00314     << " p: "
00315     << unitVp
00316     << " eta: " << _eta << " pi: " << _pi << "\n";
00317 
00318 }