00001 #define Conv4HitsReco_cxx
00002 #include "RecoTracker/ConversionSeedGenerators/interface/Conv4HitsReco.h"
00003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00004 #include <sstream>
00005
00006
00007
00008
00009
00010 double Conv4HitsReco::GetDm(){
00011
00012 return (Tq*O0-T0*Oq)/(Tq*Om-Tm*Oq);
00013
00014 }
00015
00016 double Conv4HitsReco::GetDq(){
00017
00018 return (Tm*O0-T0*Om)/(Tm*Oq-Tq*Om);
00019
00020 }
00021
00022 void Conv4HitsReco::SetLinSystCoeff(double m, double q){
00023
00024
00025
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
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
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
00190
00191
00192
00193
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
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
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.);
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
00249 if ( ((vV-vQMaxLimit).Cross(vMMaxLimit-vQMaxLimit)).Z() > 0. ){
00250
00251
00252 LogDebug("Conv4HitsReco")<< " >>>>>> Quad is invalid\n";
00253 return 1;
00254 } else {
00255
00256
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) ){
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
00279
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 }