CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/RecoMuon/MuonSeedGenerator/src/RPCSeedPattern.cc

Go to the documentation of this file.
00001 /*
00002  *  See header file for a description of this class.
00003  *
00004  *
00005  *  $Date: 2011/12/23 05:05:35 $
00006  *  $Revision: 1.5 $
00007  *  \author Haiyun.Teng - Peking University
00008  *
00009  */
00010 
00011 #include "RecoMuon/MuonSeedGenerator/src/RPCSeedPattern.h"
00012 #include <RecoMuon/TrackingTools/interface/MuonPatternRecoDumper.h>
00013 #include <MagneticField/Engine/interface/MagneticField.h>
00014 #include <MagneticField/Records/interface/IdealMagneticFieldRecord.h>
00015 #include <TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h>
00016 #include <TrackingTools/DetLayers/interface/DetLayer.h>
00017 #include <DataFormats/TrajectoryState/interface/PTrajectoryStateOnDet.h>
00018 #include <DataFormats/Common/interface/OwnVector.h>
00019 #include <DataFormats/MuonDetId/interface/RPCDetId.h>
00020 #include <FWCore/Framework/interface/ESHandle.h>
00021 #include <FWCore/MessageLogger/interface/MessageLogger.h>
00022 #include <Geometry/CommonDetUnit/interface/GeomDet.h>
00023 #include <Geometry/RPCGeometry/interface/RPCChamber.h>
00024 #include <Geometry/RPCGeometry/interface/RPCGeometry.h>
00025 #include <Geometry/Records/interface/MuonGeometryRecord.h>
00026 
00027 #include "gsl/gsl_statistics.h"
00028 #include "TH1F.h"
00029 #include "math.h"
00030 
00031 using namespace std;
00032 using namespace edm;
00033 
00034 
00035 RPCSeedPattern::RPCSeedPattern() {
00036 
00037     isPatternChecked = false;
00038     isConfigured = false;
00039     MagnecticFieldThreshold = 0.5;
00040 }
00041 
00042 RPCSeedPattern::~RPCSeedPattern() {
00043 
00044 }
00045 
00046 void RPCSeedPattern::configure(const edm::ParameterSet& iConfig) {
00047 
00048     MaxRSD = iConfig.getParameter<double>("MaxRSD");
00049     deltaRThreshold = iConfig.getParameter<double>("deltaRThreshold");
00050     AlgorithmType = iConfig.getParameter<unsigned int>("AlgorithmType");
00051     autoAlgorithmChoose = iConfig.getParameter<bool>("autoAlgorithmChoose");
00052     ZError = iConfig.getParameter<double>("ZError");
00053     MinDeltaPhi = iConfig.getParameter<double>("MinDeltaPhi");
00054     MagnecticFieldThreshold = iConfig.getParameter<double>("MagnecticFieldThreshold");
00055     stepLength = iConfig.getParameter<double>("stepLength");
00056     sampleCount = iConfig.getParameter<unsigned int>("sampleCount");
00057     isConfigured = true;
00058 }
00059 
00060 RPCSeedPattern::weightedTrajectorySeed RPCSeedPattern::seed(const edm::EventSetup& eSetup, int& isGoodSeed) {
00061 
00062     if(isConfigured == false)
00063     {
00064         cout << "Configuration not set yet" << endl;
00065         return createFakeSeed(isGoodSeed, eSetup);
00066     }
00067 
00068     // Check recHit number, if fail we return a fake seed and set pattern to "wrong"
00069     unsigned int NumberofHitsinSeed = nrhit();
00070     if(NumberofHitsinSeed < 3)
00071         return createFakeSeed(isGoodSeed, eSetup);
00072     // If only three recHits, we don't have other choice
00073     if(NumberofHitsinSeed == 3)
00074         ThreePointsAlgorithm();
00075 
00076     if(NumberofHitsinSeed > 3)
00077     {
00078         if(autoAlgorithmChoose == false)
00079         {
00080             cout << "computePtWithmorerecHits" << endl;
00081             if(AlgorithmType == 0)
00082                 ThreePointsAlgorithm();
00083             if(AlgorithmType == 1)
00084                 MiddlePointsAlgorithm();
00085             if(AlgorithmType == 2)
00086                 SegmentAlgorithm();
00087             if(AlgorithmType == 3)
00088             {
00089                 if(checkSegment())
00090                     SegmentAlgorithmSpecial(eSetup);
00091                 else
00092                 {
00093                     cout << "Not enough recHits for Special Segment Algorithm" << endl;
00094                     return createFakeSeed(isGoodSeed, eSetup);
00095                 }
00096             }
00097         }
00098         else
00099         {
00100             if(checkSegment())
00101             {
00102                 AlgorithmType = 3;
00103                 SegmentAlgorithmSpecial(eSetup);
00104             }
00105             else
00106             {
00107                 AlgorithmType = 2;
00108                 SegmentAlgorithm();
00109             }
00110         }
00111     }
00112 
00113     // Check the pattern
00114     if(isPatternChecked == false){
00115       if(AlgorithmType != 3){
00116         checkSimplePattern(eSetup);
00117       } else {
00118         checkSegmentAlgorithmSpecial(eSetup);
00119       }
00120     }
00121 
00122     return createSeed(isGoodSeed, eSetup);
00123 }
00124 
00125 void RPCSeedPattern::ThreePointsAlgorithm()
00126 {
00127     cout << "computePtWith3recHits" << endl;
00128     unsigned int NumberofHitsinSeed = nrhit();
00129     // Check recHit number, if fail we set the pattern to "wrong"
00130     if(NumberofHitsinSeed < 3)
00131     {
00132         isPatternChecked = true;
00133         isGoodPattern = -1;
00134         return;
00135     }
00136     // Choose every 3 recHits to form a part
00137     unsigned int NumberofPart = NumberofHitsinSeed * (NumberofHitsinSeed - 1) * (NumberofHitsinSeed - 2) / (3 * 2);;
00138     double *pt = new double[NumberofPart];
00139     double *pt_err = new double[NumberofPart];
00140     // Loop for each three-recHits part
00141     ConstMuonRecHitPointer precHit[3];
00142     unsigned int n = 0;
00143     unsigned int NumberofStraight = 0;
00144     for(unsigned int i = 0; i < (NumberofHitsinSeed - 2); i++)
00145         for(unsigned int j = (i + 1); j < (NumberofHitsinSeed - 1); j++)
00146             for(unsigned int k = (j + 1); k < NumberofHitsinSeed; k++)
00147             {
00148                 precHit[0] = theRecHits[i];
00149                 precHit[1] = theRecHits[j];
00150                 precHit[2] = theRecHits[k];
00151                 bool checkStraight = checkStraightwithThreerecHits(precHit, MinDeltaPhi);
00152                 if(!checkStraight)
00153                 {
00154                     GlobalVector Center_temp = computePtwithThreerecHits(pt[n], pt_err[n], precHit);
00155                     // For simple pattern                        
00156                     Center += Center_temp;
00157                 }
00158                 else
00159                 {
00160                     // For simple pattern
00161                     NumberofStraight++;
00162                     pt[n] = upper_limit_pt;
00163                     pt_err[n] = 0;
00164                 }
00165                 n++;
00166             }
00167     // For simple pattern, only one general parameter for pattern
00168     if(NumberofStraight == NumberofPart)
00169     {
00170         isStraight = true;
00171         meanRadius = -1;
00172     }
00173     else
00174     {
00175         isStraight = false;
00176         Center /= (NumberofPart - NumberofStraight);
00177         double meanR = 0.;
00178         for(ConstMuonRecHitContainer::const_iterator iter = theRecHits.begin(); iter != theRecHits.end(); iter++)
00179             meanR += getDistance(*iter, Center);
00180         meanR /= NumberofHitsinSeed;
00181         meanRadius = meanR;
00182     }
00183 
00184     // Unset the pattern estimation signa
00185     isPatternChecked = false;
00186 
00187     //double ptmean0 = 0;
00188     //double sptmean0 = 0;
00189     //computeBestPt(pt, pt_err, ptmean0, sptmean0, (NumberofPart - NumberofStraight));
00190 
00191     delete [] pt;
00192     delete [] pt_err;
00193 }
00194 
00195 void RPCSeedPattern::MiddlePointsAlgorithm()
00196 {
00197     cout << "Using middle points algorithm" << endl;
00198     unsigned int NumberofHitsinSeed = nrhit();
00199     // Check recHit number, if fail we set the pattern to "wrong"
00200     if(NumberofHitsinSeed < 4)
00201     {
00202         isPatternChecked = true;
00203         isGoodPattern = -1;
00204         return;
00205     }
00206     double *X = new double[NumberofHitsinSeed];
00207     double *Y = new double[NumberofHitsinSeed];
00208     unsigned int n = 0;
00209     for(ConstMuonRecHitContainer::const_iterator iter = theRecHits.begin(); iter != theRecHits.end(); iter++) 
00210     {
00211         X[n] = (*iter)->globalPosition().x();
00212         Y[n] = (*iter)->globalPosition().y();
00213         cout << "X[" << n <<"] = " << X[n] << ", Y[" << n <<"]= " << Y[n] << endl;
00214         n++;
00215     }
00216     unsigned int NumberofPoints = NumberofHitsinSeed;
00217     while(NumberofPoints > 3)
00218     {
00219         for(unsigned int i = 0; i <= (NumberofPoints - 2); i++)
00220         {
00221             X[i] = (X[i] + X[i+1]) / 2;
00222             Y[i] = (Y[i] + Y[i+1]) / 2;
00223         }
00224         NumberofPoints--;
00225     }
00226     double x[3], y[3];
00227     for(unsigned int i = 0; i < 3; i++)
00228     {
00229         x[i] = X[i];
00230         y[i] = Y[i];
00231     }
00232     double pt = 0;
00233     double pt_err = 0;
00234     bool checkStraight = checkStraightwithThreerecHits(x, y, MinDeltaPhi);
00235     if(!checkStraight)
00236     {
00237 
00238         GlobalVector Center_temp = computePtWithThreerecHits(pt, pt_err, x, y);
00239         double meanR = 0.;
00240         for(ConstMuonRecHitContainer::const_iterator iter = theRecHits.begin(); iter != theRecHits.end(); iter++)
00241             meanR += getDistance(*iter, Center_temp);
00242         meanR /= NumberofHitsinSeed;
00243         // For simple pattern
00244         isStraight = false;
00245         Center = Center_temp;
00246         meanRadius = meanR;
00247     }
00248     else
00249     {
00250         // For simple pattern
00251         isStraight = true;
00252         meanRadius = -1;
00253     }
00254 
00255     // Unset the pattern estimation signa
00256     isPatternChecked = false;
00257 
00258     delete [] X;
00259     delete [] Y;
00260 }
00261 
00262 void RPCSeedPattern::SegmentAlgorithm()
00263 {
00264     cout << "Using segments algorithm" << endl;
00265     unsigned int NumberofHitsinSeed = nrhit();
00266     // Check recHit number, if fail we set the pattern to "wrong"
00267     if(NumberofHitsinSeed < 4)
00268     {
00269         isPatternChecked = true;
00270         isGoodPattern = -1;
00271         return;
00272     }
00273 
00274     RPCSegment* Segment;
00275     unsigned int NumberofSegment = NumberofHitsinSeed - 2;
00276     Segment = new RPCSegment[NumberofSegment];
00277     unsigned int n = 0;
00278     for(ConstMuonRecHitContainer::const_iterator iter = theRecHits.begin(); iter != (theRecHits.end()-2); iter++)
00279     {
00280         Segment[n].first = (*iter);
00281         Segment[n].second = (*(iter + 2));
00282         n++;
00283     }
00284     unsigned int NumberofStraight = 0;
00285     for(unsigned int i = 0; i < NumberofSegment - 1; i++)
00286     {
00287         bool checkStraight = checkStraightwithSegment(Segment[i], Segment[i+1], MinDeltaPhi);
00288         if(checkStraight == true)
00289         {
00290             // For simple patterm
00291             NumberofStraight++;
00292         }
00293         else
00294         {
00295             GlobalVector Center_temp = computePtwithSegment(Segment[i], Segment[i+1]);
00296             // For simple patterm
00297             Center += Center_temp;
00298         }
00299     }
00300     // For simple pattern, only one general parameter for pattern
00301     if((NumberofSegment-1-NumberofStraight) > 0)
00302     {
00303         isStraight = false;
00304         Center /= (NumberofSegment - 1 - NumberofStraight);
00305         double meanR = 0.;
00306         for(ConstMuonRecHitContainer::const_iterator iter = theRecHits.begin(); iter != theRecHits.end(); iter++)
00307             meanR += getDistance(*iter, Center);
00308         meanR /= NumberofHitsinSeed;
00309         meanRadius = meanR;
00310     }
00311     else
00312     {
00313         isStraight = true;
00314         meanRadius = -1;
00315     }
00316 
00317     // Unset the pattern estimation signal
00318     isPatternChecked = false;
00319 
00320     delete [] Segment;
00321 }
00322 
00323 void RPCSeedPattern::SegmentAlgorithmSpecial(const edm::EventSetup& eSetup)
00324 {
00325     // Get magnetic field
00326     edm::ESHandle<MagneticField> Field;
00327     eSetup.get<IdealMagneticFieldRecord>().get(Field);
00328 
00329     //unsigned int NumberofHitsinSeed = nrhit();
00330     if(!checkSegment())
00331     {
00332         isPatternChecked = true;
00333         isGoodPattern = -1;
00334         return;
00335     }
00336 
00337     // Get magnetice field sampling information, recHit's position is not the border of Chamber and Iron
00338     for(ConstMuonRecHitContainer::const_iterator iter = theRecHits.begin(); iter != (theRecHits.end()-1); iter++) 
00339     {
00340         GlobalPoint gpFirst = (*iter)->globalPosition();
00341         GlobalPoint gpLast = (*(iter+1))->globalPosition();
00342         GlobalPoint* gp = new GlobalPoint[sampleCount];
00343         double dx = (gpLast.x() - gpFirst.x()) / (sampleCount + 1);
00344         double dy = (gpLast.y() - gpFirst.y()) / (sampleCount + 1);
00345         double dz = (gpLast.z() - gpFirst.z()) / (sampleCount + 1);
00346         for(unsigned int index = 0; index < sampleCount; index++)
00347         {
00348             gp[index] = GlobalPoint((gpFirst.x()+dx*(index+1)), (gpFirst.y()+dy*(index+1)), (gpFirst.z()+dz*(index+1)));
00349             GlobalVector MagneticVec_temp = Field->inTesla(gp[index]);
00350             cout << "Sampling magnetic field : " << MagneticVec_temp << endl;
00351             //BValue.push_back(MagneticVec_temp);
00352         }
00353         delete [] gp;
00354     }
00355 
00356     // form two segments
00357     ConstMuonRecHitContainer::const_iterator iter=theRecHits.begin();
00358     for(unsigned int n = 0; n <= 1; n++)
00359     {
00360         SegmentRB[n].first = (*iter);
00361         cout << "SegmentRB " << n << " recHit: " << (*iter)->globalPosition() << endl;
00362         iter++;
00363         SegmentRB[n].second = (*iter);
00364         cout << "SegmentRB " << n << " recHit: " << (*iter)->globalPosition() << endl;
00365         iter++;
00366     }
00367     GlobalVector segvec1 = (SegmentRB[0].second)->globalPosition() - (SegmentRB[0].first)->globalPosition();
00368     GlobalVector segvec2 = (SegmentRB[1].second)->globalPosition() - (SegmentRB[1].first)->globalPosition();
00369 
00370     // extrapolate the segment to find the Iron border which magnetic field is at large value
00371     entryPosition = (SegmentRB[0].second)->globalPosition();
00372     leavePosition = (SegmentRB[1].first)->globalPosition();
00373     while(fabs(Field->inTesla(entryPosition).z()) < MagnecticFieldThreshold)
00374     {
00375         cout << "Entry position is : " << entryPosition << ", and stepping into next point" << endl;
00376         entryPosition += segvec1.unit() * stepLength;
00377     }
00378     // Loop back for more accurate by stepLength/10
00379     while(fabs(Field->inTesla(entryPosition).z()) >= MagnecticFieldThreshold)
00380     {   
00381         cout << "Entry position is : " << entryPosition << ", and stepping back into next point" << endl;
00382         entryPosition -= segvec1.unit() * stepLength / 10;
00383     }
00384     entryPosition += 0.5 * segvec1.unit() * stepLength / 10;
00385     cout << "Final entry position is : " << entryPosition << endl;
00386 
00387     while(fabs(Field->inTesla(leavePosition).z()) < MagnecticFieldThreshold)
00388     {
00389         cout << "Leave position is : " << leavePosition << ", and stepping into next point" << endl;
00390         leavePosition -= segvec2.unit() * stepLength;
00391     }
00392     // Loop back for more accurate by stepLength/10
00393     while(fabs(Field->inTesla(leavePosition).z()) >= MagnecticFieldThreshold)
00394     {                      
00395         cout << "Leave position is : " << leavePosition << ", and stepping back into next point" << endl;
00396         leavePosition += segvec2.unit() * stepLength / 10;
00397     }
00398     leavePosition -= 0.5 * segvec2.unit() * stepLength / 10;
00399     cout << "Final leave position is : " << leavePosition << endl;
00400 
00401     // Sampling magnetic field in Iron region
00402     GlobalPoint* gp = new GlobalPoint[sampleCount];
00403     double dx = (leavePosition.x() - entryPosition.x()) / (sampleCount + 1);
00404     double dy = (leavePosition.y() - entryPosition.y()) / (sampleCount + 1);
00405     double dz = (leavePosition.z() - entryPosition.z()) / (sampleCount + 1);
00406     std::vector<GlobalVector> BValue;
00407     BValue.clear();
00408     for(unsigned int index = 0; index < sampleCount; index++)
00409     {
00410         gp[index] = GlobalPoint((entryPosition.x()+dx*(index+1)), (entryPosition.y()+dy*(index+1)), (entryPosition.z()+dz*(index+1)));
00411         GlobalVector MagneticVec_temp = Field->inTesla(gp[index]);
00412         cout << "Sampling magnetic field : " << MagneticVec_temp << endl;
00413         BValue.push_back(MagneticVec_temp);
00414     }
00415     delete [] gp;
00416     GlobalVector meanB2(0, 0, 0);
00417     for(std::vector<GlobalVector>::const_iterator BIter = BValue.begin(); BIter != BValue.end(); BIter++)
00418         meanB2 += (*BIter);
00419     meanB2 /= BValue.size();
00420     cout << "Mean B field is " << meanB2 << endl;
00421     meanMagneticField2 = meanB2;
00422 
00423     double meanBz2 = meanB2.z();
00424     double deltaBz2 = 0.;
00425     for(std::vector<GlobalVector>::const_iterator BIter = BValue.begin(); BIter != BValue.end(); BIter++)
00426         deltaBz2 += (BIter->z() - meanBz2) * (BIter->z() - meanBz2);;
00427     deltaBz2 /= BValue.size();
00428     deltaBz2 = sqrt(deltaBz2);
00429     cout<< "delta Bz is " << deltaBz2 << endl;
00430 
00431     // Distance of the initial 3 segment
00432     S = 0;
00433     bool checkStraight = checkStraightwithSegment(SegmentRB[0], SegmentRB[1], MinDeltaPhi);
00434     if(checkStraight == true)
00435     {
00436         // Just for complex pattern
00437         isStraight2 = checkStraight;
00438         Center2 = GlobalVector(0, 0, 0);
00439         meanRadius2 = -1;
00440         GlobalVector MomentumVec = (SegmentRB[1].second)->globalPosition() - (SegmentRB[0].first)->globalPosition();
00441         S += MomentumVec.perp();
00442         lastPhi = MomentumVec.phi().value();
00443     }
00444     else
00445     {
00446         GlobalVector seg1 = entryPosition - (SegmentRB[0].first)->globalPosition();
00447         S += seg1.perp();
00448         GlobalVector seg2 = (SegmentRB[1].second)->globalPosition() - leavePosition;
00449         S += seg2.perp();
00450         GlobalVector vecZ(0, 0, 1);
00451         GlobalVector gvec1 = seg1.cross(vecZ);
00452         GlobalVector gvec2 = seg2.cross(vecZ);
00453         double A1 = gvec1.x();
00454         double B1 = gvec1.y();
00455         double A2 = gvec2.x();
00456         double B2 = gvec2.y();
00457         double X1 = entryPosition.x();
00458         double Y1 = entryPosition.y();
00459         double X2 = leavePosition.x();
00460         double Y2 = leavePosition.y();
00461         double XO = (A1*A2*(Y2-Y1)+A2*B1*X1-A1*B2*X2)/(A2*B1-A1*B2);
00462         double YO = (B1*B2*(X2-X1)+B2*A1*Y1-B1*A2*Y2)/(B2*A1-B1*A2);
00463         GlobalVector Center_temp(XO, YO, 0);
00464         // Just for complex pattern
00465         isStraight2 = checkStraight;
00466         Center2 = Center_temp;
00467 
00468         cout << "entryPosition: " << entryPosition << endl;
00469         cout << "leavePosition: " << leavePosition << endl;
00470         cout << "Center2 is : " << Center_temp << endl;
00471 
00472         double R1 = GlobalVector((entryPosition.x() - Center_temp.x()), (entryPosition.y() - Center_temp.y()), (entryPosition.z() - Center_temp.z())).perp();
00473         double R2 = GlobalVector((leavePosition.x() - Center_temp.x()), (leavePosition.y() - Center_temp.y()), (leavePosition.z() - Center_temp.z())).perp();
00474         double meanR = (R1 + R2) / 2;
00475         double deltaR = sqrt(((R1-meanR)*(R1-meanR)+(R2-meanR)*(R2-meanR))/2);
00476         meanRadius2 = meanR;
00477         cout << "R1 is " << R1 << ", R2 is " << R2 << endl;
00478         cout << "Mean radius is " << meanR << endl;
00479         cout << "Delta R is " << deltaR << endl;
00480         double deltaPhi = fabs(((leavePosition-GlobalPoint(XO, YO, 0)).phi()-(entryPosition-GlobalPoint(XO, YO, 0)).phi()).value());
00481         S += meanR * deltaPhi;
00482         lastPhi = seg2.phi().value();
00483     }
00484 
00485     // Unset the pattern estimation signa
00486     isPatternChecked = false;
00487 }
00488 
00489 bool RPCSeedPattern::checkSegment() const
00490 {
00491     bool isFit = true;
00492     unsigned int count = 0;
00493     // first 4 recHits should be located in RB1 and RB2
00494     for(ConstMuonRecHitContainer::const_iterator iter=theRecHits.begin(); iter!=theRecHits.end(); iter++)
00495     {
00496         count++;
00497         const GeomDet* Detector = (*iter)->det();
00498         if(dynamic_cast<const RPCChamber*>(Detector) != 0)
00499         {
00500             const RPCChamber* RPCCh = dynamic_cast<const RPCChamber*>(Detector);
00501             RPCDetId RPCId = RPCCh->id();
00502             int Region = RPCId.region();
00503             unsigned int Station = RPCId.station();
00504             //int Layer = RPCId.layer();
00505             if(count <= 4)
00506             {
00507                 if(Region != 0)
00508                     isFit = false;
00509                 if(Station > 2)
00510                     isFit = false;
00511             }
00512         }
00513     }
00514     // more than 4 recHits for pattern building
00515     if(count <= 4)
00516         isFit = false;
00517     cout << "Check for segment fit: " << isFit << endl;
00518     return isFit;
00519 }
00520 
00521 MuonTransientTrackingRecHit::ConstMuonRecHitPointer RPCSeedPattern::FirstRecHit() const 
00522 { 
00523     return theRecHits.front(); 
00524 }
00525 
00526 MuonTransientTrackingRecHit::ConstMuonRecHitPointer RPCSeedPattern::BestRefRecHit() const 
00527 {
00528     ConstMuonRecHitPointer best;
00529     int index = 0;
00530     // Use the last one for recHit on last layer has minmum delta Z for barrel or delta R for endcap while calculating the momentum
00531     // But for Algorithm 3 we use the 4th recHit on the 2nd segment for more accurate
00532     for (ConstMuonRecHitContainer::const_iterator iter=theRecHits.begin(); iter!=theRecHits.end(); iter++)
00533     {
00534         if(AlgorithmType != 3)
00535             best = (*iter);
00536         else
00537             if(index < 4)
00538                 best = (*iter);
00539         index++;        
00540     }
00541     return best;
00542 }
00543 
00544 double RPCSeedPattern::getDistance(const ConstMuonRecHitPointer& precHit, const GlobalVector& Center) const
00545 {
00546     return sqrt((precHit->globalPosition().x()-Center.x())*(precHit->globalPosition().x()-Center.x())+(precHit->globalPosition().y()-Center.y())*(precHit->globalPosition().y()-Center.y()));
00547 }
00548 
00549 bool RPCSeedPattern::checkStraightwithThreerecHits(ConstMuonRecHitPointer (&precHit)[3], double MinDeltaPhi) const
00550 {
00551     GlobalVector segvec1 = precHit[1]->globalPosition() - precHit[0]->globalPosition();
00552     GlobalVector segvec2 = precHit[2]->globalPosition() - precHit[1]->globalPosition();
00553     double dPhi = (segvec2.phi() - segvec1.phi()).value();
00554     if(fabs(dPhi) > MinDeltaPhi)
00555     {
00556         cout << "Part is estimate to be not straight" << endl;
00557         return false;
00558     }
00559     else
00560     {
00561         cout << "Part is estimate to be straight" << endl;
00562         return true;
00563     }
00564 }
00565 
00566 GlobalVector RPCSeedPattern::computePtwithThreerecHits(double& pt, double& pt_err, ConstMuonRecHitPointer (&precHit)[3]) const
00567 {
00568     double x[3], y[3];
00569     x[0] = precHit[0]->globalPosition().x();
00570     y[0] = precHit[0]->globalPosition().y();
00571     x[1] = precHit[1]->globalPosition().x();
00572     y[1] = precHit[1]->globalPosition().y();
00573     x[2] = precHit[2]->globalPosition().x();
00574     y[2] = precHit[2]->globalPosition().y();
00575     double A = (y[2]-y[1])/(x[2]-x[1]) - (y[1]-y[0])/(x[1]-x[0]);
00576     double TYO = (x[2]-x[0])/A + (y[2]*y[2]-y[1]*y[1])/((x[2]-x[1])*A) - (y[1]*y[1]-y[0]*y[0])/((x[1]-x[0])*A);
00577     double TXO = (x[2]+x[1]) + (y[2]*y[2]-y[1]*y[1])/(x[2]-x[1]) - TYO*(y[2]-y[1])/(x[2]-x[1]);
00578     double XO = 0.5 * TXO;
00579     double YO = 0.5 * TYO;
00580     double R2 = (x[0]-XO)*(x[0]-XO) + (y[0]-YO)*(y[0]-YO);
00581     cout << "R2 is " << R2 << endl;
00582     // How this algorithm get the pt without magnetic field??
00583     pt = 0.01 * sqrt(R2) * 2 * 0.3;
00584     cout << "pt is " << pt << endl;
00585     GlobalVector Center(XO, YO, 0);
00586     return Center;
00587 }
00588 
00589 bool RPCSeedPattern::checkStraightwithSegment(const RPCSegment& Segment1, const RPCSegment& Segment2, double MinDeltaPhi) const
00590 {
00591     GlobalVector segvec1 = (Segment1.second)->globalPosition() - (Segment1.first)->globalPosition();
00592     GlobalVector segvec2 = (Segment2.second)->globalPosition() - (Segment2.first)->globalPosition();
00593     GlobalVector segvec3 = (Segment2.first)->globalPosition() - (Segment1.first)->globalPosition();
00594     // compare segvec 1&2 for paralle, 1&3 for straight
00595     double dPhi1 = (segvec2.phi() - segvec1.phi()).value();
00596     double dPhi2 = (segvec3.phi() - segvec1.phi()).value();
00597     cout << "Checking straight with 2 segments. dPhi1: " << dPhi1 << ", dPhi2: " << dPhi2 << endl;
00598     cout << "Checking straight with 2 segments. dPhi1 in degree: " << dPhi1*180/3.1415926 << ", dPhi2 in degree: " << dPhi2*180/3.1415926 << endl;
00599     if(fabs(dPhi1) > MinDeltaPhi || fabs(dPhi2) > MinDeltaPhi)
00600     {
00601         cout << "Segment is estimate to be not straight" << endl;
00602         return false;
00603     }
00604     else
00605     {
00606         cout << "Segment is estimate to be straight" << endl;
00607         return true;
00608     }
00609 }
00610 
00611 GlobalVector RPCSeedPattern::computePtwithSegment(const RPCSegment& Segment1, const RPCSegment& Segment2) const
00612 {
00613     GlobalVector segvec1 = (Segment1.second)->globalPosition() - (Segment1.first)->globalPosition();
00614     GlobalVector segvec2 = (Segment2.second)->globalPosition() - (Segment2.first)->globalPosition();
00615     GlobalPoint Point1(((Segment1.second)->globalPosition().x() + (Segment1.first)->globalPosition().x()) / 2, ((Segment1.second)->globalPosition().y() + (Segment1.first)->globalPosition().y()) / 2, ((Segment1.second)->globalPosition().z() + (Segment1.first)->globalPosition().z()) / 2);
00616     GlobalPoint Point2(((Segment2.second)->globalPosition().x() + (Segment2.first)->globalPosition().x()) / 2, ((Segment2.second)->globalPosition().y() + (Segment2.first)->globalPosition().y()) / 2, ((Segment2.second)->globalPosition().z() + (Segment2.first)->globalPosition().z()) / 2);
00617     GlobalVector vecZ(0, 0, 1);
00618     GlobalVector gvec1 = segvec1.cross(vecZ);
00619     GlobalVector gvec2 = segvec2.cross(vecZ);
00620     double A1 = gvec1.x();
00621     double B1 = gvec1.y();
00622     double A2 = gvec2.x();
00623     double B2 = gvec2.y();
00624     double X1 = Point1.x();
00625     double Y1 = Point1.y();
00626     double X2 = Point2.x();
00627     double Y2 = Point2.y();
00628     double XO = (A1*A2*(Y2-Y1)+A2*B1*X1-A1*B2*X2)/(A2*B1-A1*B2);
00629     double YO = (B1*B2*(X2-X1)+B2*A1*Y1-B1*A2*Y2)/(B2*A1-B1*A2);
00630     GlobalVector Center(XO, YO, 0);
00631     return Center;
00632 }
00633 
00634 bool RPCSeedPattern::checkStraightwithThreerecHits(double (&x)[3], double (&y)[3], double MinDeltaPhi) const
00635 {
00636     GlobalVector segvec1((x[1]-x[0]), (y[1]-y[0]), 0);
00637     GlobalVector segvec2((x[2]-x[1]), (y[2]-y[1]), 0);
00638     double dPhi = (segvec2.phi() - segvec1.phi()).value();
00639     if(fabs(dPhi) > MinDeltaPhi)
00640     {
00641         cout << "Part is estimate to be not straight" << endl;
00642         return false;
00643     }
00644     else
00645     {
00646         cout << "Part is estimate to be straight" << endl;
00647         return true;
00648     }
00649 }
00650 
00651 GlobalVector RPCSeedPattern::computePtWithThreerecHits(double& pt, double& pt_err, double (&x)[3], double (&y)[3]) const
00652 {
00653     double A = (y[2]-y[1])/(x[2]-x[1]) - (y[1]-y[0])/(x[1]-x[0]);
00654     double TYO = (x[2]-x[0])/A + (y[2]*y[2]-y[1]*y[1])/((x[2]-x[1])*A) - (y[1]*y[1]-y[0]*y[0])/((x[1]-x[0])*A);
00655     double TXO = (x[2]+x[1]) + (y[2]*y[2]-y[1]*y[1])/(x[2]-x[1]) - TYO*(y[2]-y[1])/(x[2]-x[1]);
00656     double XO = 0.5 * TXO;
00657     double YO = 0.5 * TYO;
00658     double R2 = (x[0]-XO)*(x[0]-XO) + (y[0]-YO)*(y[0]-YO);
00659     cout << "R2 is " << R2 << endl;
00660     // How this algorithm get the pt without magnetic field??
00661     pt = 0.01 * sqrt(R2) * 2 * 0.3;
00662     cout << "pt is " << pt << endl;
00663     GlobalVector Center(XO, YO, 0);
00664     return Center;
00665 }
00666 
00667 void RPCSeedPattern::checkSimplePattern(const edm::EventSetup& eSetup)
00668 {
00669     if(isPatternChecked == true)
00670         return;
00671 
00672     // Get magnetic field
00673     edm::ESHandle<MagneticField> Field;
00674     eSetup.get<IdealMagneticFieldRecord>().get(Field);
00675 
00676     unsigned int NumberofHitsinSeed = nrhit();
00677 
00678     // Print the recHit's position
00679     for(ConstMuonRecHitContainer::const_iterator iter = theRecHits.begin(); iter != theRecHits.end(); iter++)
00680         cout << "Position of recHit is: " << (*iter)->globalPosition() << endl;
00681 
00682     // Get magnetice field information
00683     std::vector<double> BzValue;
00684     for(ConstMuonRecHitContainer::const_iterator iter = theRecHits.begin(); iter != (theRecHits.end()-1); iter++) 
00685     {
00686         GlobalPoint gpFirst = (*iter)->globalPosition();
00687         GlobalPoint gpLast = (*(iter+1))->globalPosition();
00688         GlobalPoint *gp = new GlobalPoint[sampleCount];
00689         double dx = (gpLast.x() - gpFirst.x()) / (sampleCount + 1);
00690         double dy = (gpLast.y() - gpFirst.y()) / (sampleCount + 1);
00691         double dz = (gpLast.z() - gpFirst.z()) / (sampleCount + 1);
00692         for(unsigned int index = 0; index < sampleCount; index++)
00693         {
00694             gp[index] = GlobalPoint((gpFirst.x()+dx*(index+1)), (gpFirst.y()+dy*(index+1)), (gpFirst.z()+dz*(index+1)));
00695             GlobalVector MagneticVec_temp = Field->inTesla(gp[index]);
00696             cout << "Sampling magnetic field : " << MagneticVec_temp << endl;
00697             BzValue.push_back(MagneticVec_temp.z());
00698         }
00699         delete [] gp;
00700     }
00701     meanBz = 0.;
00702     for(unsigned int index = 0; index < BzValue.size(); index++)
00703         meanBz += BzValue[index];
00704     meanBz /= BzValue.size();
00705     cout << "Mean Bz is " << meanBz << endl;
00706     deltaBz = 0.;
00707     for(unsigned int index = 0; index < BzValue.size(); index++)
00708         deltaBz += (BzValue[index] - meanBz) * (BzValue[index] - meanBz);
00709     deltaBz /= BzValue.size();
00710     deltaBz = sqrt(deltaBz);
00711     cout<< "delata Bz is " << deltaBz << endl;
00712 
00713     // Set isGoodPattern to default true and check the failure 
00714     isGoodPattern = 1;
00715 
00716     // Check the Z direction
00717     if(fabs((*(theRecHits.end()-1))->globalPosition().z() - (*(theRecHits.begin()))->globalPosition().z()) > ZError)
00718     {
00719         if(((*(theRecHits.end()-1))->globalPosition().z() - (*(theRecHits.begin()))->globalPosition().z()) > ZError)
00720             isParralZ = 1;
00721         else
00722             isParralZ = -1;
00723     }
00724     else
00725         isParralZ = 0;
00726 
00727     cout << " Check isParralZ is :" << isParralZ << endl;
00728     for(ConstMuonRecHitContainer::const_iterator iter = theRecHits.begin(); iter != (theRecHits.end()-1); iter++) 
00729     {
00730         if(isParralZ == 0)
00731         {
00732             if(fabs((*(iter+1))->globalPosition().z()-(*iter)->globalPosition().z()) > ZError)
00733             {
00734                 cout << "Pattern find error in Z direction: wrong perpendicular direction" << endl;
00735                 isGoodPattern = 0;
00736             }
00737         }
00738         else
00739         {
00740             if((int)(((*(iter+1))->globalPosition().z()-(*iter)->globalPosition().z())/ZError)*isParralZ < 0)
00741             {
00742                 cout << "Pattern find error in Z direction: wrong Z direction" << endl;
00743                 isGoodPattern = 0;
00744             }
00745         }
00746     }
00747 
00748     // Check pattern
00749     if(isStraight == false)
00750     {
00751         // Check clockwise direction
00752         GlobalVector *vec = new GlobalVector[NumberofHitsinSeed];
00753         unsigned int index = 0;
00754         for(ConstMuonRecHitContainer::const_iterator iter = theRecHits.begin(); iter != theRecHits.end(); iter++) 
00755         {
00756             GlobalVector vec_temp(((*iter)->globalPosition().x()-Center.x()), ((*iter)->globalPosition().y()-Center.y()), ((*iter)->globalPosition().z()-Center.z()));
00757             vec[index] = vec_temp;
00758             index++;
00759         }
00760         isClockwise = 0;
00761         for(unsigned int index = 0; index < (NumberofHitsinSeed-1); index++)
00762         {
00763             // Check phi direction, all sub-dphi direction should be the same
00764             if((vec[index+1].phi()-vec[index].phi()) > 0)
00765                 isClockwise--;
00766             else
00767                 isClockwise++;
00768             cout << "Current isClockwise is : " << isClockwise << endl;
00769         }
00770         cout << "Check isClockwise is : " << isClockwise << endl;
00771         if((unsigned int)abs(isClockwise) != (NumberofHitsinSeed-1))
00772         {
00773             cout << "Pattern find error in Phi direction" << endl;
00774             isGoodPattern = 0;
00775             isClockwise = 0;
00776         }
00777         else
00778             isClockwise /= abs(isClockwise);
00779         delete [] vec;
00780 
00781         // Get meanPt and meanSpt
00782         double deltaRwithBz = fabs(deltaBz * meanRadius / meanBz);
00783         cout << "deltaR with Bz is " << deltaRwithBz << endl;
00784 
00785         if(isClockwise == 0)
00786             meanPt = upper_limit_pt;
00787         else
00788             meanPt = 0.01 * meanRadius * meanBz * 0.3 * isClockwise;
00789         if(fabs(meanPt) > upper_limit_pt)
00790             meanPt = upper_limit_pt * meanPt / fabs(meanPt);
00791         cout << " meanRadius is " << meanRadius << endl;
00792         cout << " meanPt is " << meanPt << endl;
00793 
00794         double deltaR = 0.;
00795         for(ConstMuonRecHitContainer::const_iterator iter = theRecHits.begin(); iter != theRecHits.end(); iter++) 
00796         {
00797             deltaR += (getDistance(*iter, Center) - meanRadius) * (getDistance(*iter, Center) - meanRadius);
00798         }
00799         deltaR = deltaR / NumberofHitsinSeed;
00800         deltaR = sqrt(deltaR);
00801         //meanSpt = 0.01 * deltaR * meanBz * 0.3;
00802         meanSpt = deltaR;
00803         cout << "DeltaR is " << deltaR << endl;
00804         if(deltaR > deltaRThreshold)
00805         {
00806             cout << "Pattern find error: deltaR over threshold" << endl;
00807             isGoodPattern = 0;
00808         }
00809     }
00810     else
00811     {
00812         // Just set pattern to be straight
00813         isClockwise =0;
00814         meanPt = upper_limit_pt;
00815         // Set the straight pattern with lowest priority among good pattern
00816         meanSpt = deltaRThreshold;
00817     }
00818     cout << "III--> Seed Pt : " << meanPt << endl;
00819     cout << "III--> Pattern is: " << isGoodPattern << endl;
00820 
00821     // Set the pattern estimation signal
00822     isPatternChecked = true;
00823 }
00824 
00825 void RPCSeedPattern::checkSegmentAlgorithmSpecial(const edm::EventSetup& eSetup)
00826 {
00827     if(isPatternChecked == true)
00828         return;
00829 
00830     if(!checkSegment())
00831     {
00832         isPatternChecked = true;
00833         isGoodPattern = -1;
00834         return;
00835     }
00836 
00837     // Set isGoodPattern to default true and check the failure 
00838     isGoodPattern = 1;
00839 
00840     // Print the recHit's position
00841     for(ConstMuonRecHitContainer::const_iterator iter = theRecHits.begin(); iter != theRecHits.end(); iter++)
00842         cout << "Position of recHit is: " << (*iter)->globalPosition() << endl;
00843 
00844     // Check the Z direction
00845     if(fabs((*(theRecHits.end()-1))->globalPosition().z() - (*(theRecHits.begin()))->globalPosition().z()) > ZError)
00846     {
00847         if(((*(theRecHits.end()-1))->globalPosition().z() - (*(theRecHits.begin()))->globalPosition().z()) > ZError)
00848             isParralZ = 1;
00849         else
00850             isParralZ = -1;
00851     }
00852     else
00853         isParralZ = 0;
00854 
00855     cout << " Check isParralZ is :" << isParralZ << endl;
00856     for(ConstMuonRecHitContainer::const_iterator iter = theRecHits.begin(); iter != (theRecHits.end()-1); iter++) 
00857     {
00858         if(isParralZ == 0)
00859         {
00860             if(fabs((*(iter+1))->globalPosition().z()-(*iter)->globalPosition().z()) > ZError)
00861             {
00862                 cout << "Pattern find error in Z direction: wrong perpendicular direction" << endl;
00863                 isGoodPattern = 0;
00864             }
00865         }
00866         else
00867         {
00868             if((int)(((*(iter+1))->globalPosition().z()-(*iter)->globalPosition().z())/ZError)*isParralZ < 0)
00869             {
00870                 cout << "Pattern find error in Z direction: wrong Z direction" << endl;
00871                 isGoodPattern = 0;
00872             }
00873         }
00874     }
00875 
00876     // Check the pattern
00877     if(isStraight2 == true)
00878     {
00879         // Set pattern to be straight
00880         isClockwise = 0;
00881         meanPt = upper_limit_pt;
00882         // Set the straight pattern with lowest priority among good pattern
00883         meanSpt = deltaRThreshold;
00884 
00885         // Extrapolate to other recHits and check deltaR
00886         GlobalVector startSegment = (SegmentRB[1].second)->globalPosition() - (SegmentRB[1].first)->globalPosition();
00887         GlobalPoint startPosition = (SegmentRB[1].first)->globalPosition();
00888         GlobalVector startMomentum = startSegment*(meanPt/startSegment.perp());
00889         unsigned int index = 0;
00890         for(ConstMuonRecHitContainer::const_iterator iter = theRecHits.begin(); iter != theRecHits.end(); iter++)
00891         {
00892             if(index < 4)
00893             {
00894                 index++;
00895                 continue;
00896             }
00897             double tracklength = 0;
00898             cout << "Now checking recHit " << index << endl;
00899             double Distance = extropolateStep(startPosition, startMomentum, iter, isClockwise, tracklength, eSetup);
00900             cout << "Final distance is " << Distance << endl;
00901             if(Distance > MaxRSD)
00902             {
00903                 cout << "Pattern find error in distance for other recHits: " << Distance << endl;
00904                 isGoodPattern = 0;
00905             }
00906             index++;
00907         }
00908     }
00909     else
00910     {
00911         // Get clockwise direction
00912         GlobalVector vec[2];
00913         vec[0] = GlobalVector((entryPosition.x()-Center2.x()), (entryPosition.y()-Center2.y()), (entryPosition.z()-Center2.z()));
00914         vec[1] = GlobalVector((leavePosition.x()-Center2.x()), (leavePosition.y()-Center2.y()), (leavePosition.z()-Center2.z()));
00915         isClockwise = 0;
00916         if((vec[1].phi()-vec[0].phi()).value() > 0)
00917             isClockwise = -1;
00918         else
00919             isClockwise = 1;
00920 
00921         cout << "Check isClockwise is : " << isClockwise << endl;
00922 
00923         // Get meanPt
00924         meanPt = 0.01 * meanRadius2 * meanMagneticField2.z() * 0.3 * isClockwise;
00925         //meanPt = 0.01 * meanRadius2[0] * (-3.8) * 0.3 * isClockwise;
00926         cout << " meanRadius is " << meanRadius2 << ", with meanBz " << meanMagneticField2.z() << endl;
00927         cout << " meanPt is " << meanPt << endl;
00928         if(fabs(meanPt) > upper_limit_pt)
00929             meanPt = upper_limit_pt * meanPt / fabs(meanPt);
00930 
00931         // Check the initial 3 segments
00932         cout << "entryPosition: " << entryPosition << endl;
00933         cout << "leavePosition: " << leavePosition << endl;
00934         cout << "Center2 is : " << Center2 << endl;
00935         double R1 = vec[0].perp();
00936         double R2 = vec[1].perp();
00937         double deltaR  = sqrt(((R1-meanRadius2)*(R1-meanRadius2)+(R2-meanRadius2)*(R2-meanRadius2))/2);
00938         meanSpt = deltaR;
00939         cout << "R1 is " << R1 << ", R2 is " << R2 << endl;
00940         cout << "Delta R for the initial 3 segments is " << deltaR << endl;
00941         if(deltaR > deltaRThreshold)
00942         {
00943             cout << "Pattern find error in delta R for the initial 3 segments" << endl;
00944             isGoodPattern = 0;
00945         }
00946 
00947         // Extrapolate to other recHits and check deltaR
00948         GlobalVector startSegment = (SegmentRB[1].second)->globalPosition() - (SegmentRB[1].first)->globalPosition();
00949         GlobalPoint startPosition = (SegmentRB[1].first)->globalPosition();
00950         GlobalVector startMomentum = startSegment*(fabs(meanPt)/startSegment.perp());
00951         unsigned int index = 0;
00952         for(ConstMuonRecHitContainer::const_iterator iter = theRecHits.begin(); iter != theRecHits.end(); iter++)
00953         {
00954             if(index < 4)
00955             {
00956                 index++;
00957                 continue;
00958             }
00959             double tracklength = 0;
00960             cout << "Now checking recHit " << index << endl;
00961             double Distance = extropolateStep(startPosition, startMomentum, iter, isClockwise, tracklength, eSetup);
00962             cout << "Final distance is " << Distance << endl;
00963             if(Distance > MaxRSD)
00964             {
00965                 cout << "Pattern find error in distance for other recHits: " << Distance << endl;
00966                 isGoodPattern = 0;
00967             }
00968             index++;
00969         }
00970     }
00971 
00972     cout << "Checking finish, isGoodPattern now is " << isGoodPattern << endl; 
00973     // Set the pattern estimation signal
00974     isPatternChecked = true;
00975 }
00976 
00977 double RPCSeedPattern::extropolateStep(const GlobalPoint& startPosition, const GlobalVector& startMomentum, ConstMuonRecHitContainer::const_iterator iter, const int ClockwiseDirection, double& tracklength, const edm::EventSetup& eSetup)
00978 {
00979     // Get magnetic field
00980     edm::ESHandle<MagneticField> Field;
00981     eSetup.get<IdealMagneticFieldRecord>().get(Field);
00982 
00983     cout << "Extrapolating the track to check the pattern" << endl;
00984     tracklength = 0;
00985     // Get the iter recHit's detector geometry
00986     DetId hitDet = (*iter)->hit()->geographicalId();
00987     RPCDetId RPCId = RPCDetId(hitDet.rawId());
00988     //const RPCChamber* hitRPC = dynamic_cast<const RPCChamber*>(hitDet);
00989     edm::ESHandle<RPCGeometry> pRPCGeom;
00990     eSetup.get<MuonGeometryRecord>().get(pRPCGeom);
00991     const RPCGeometry* rpcGeometry = (const RPCGeometry*)&*pRPCGeom;
00992 
00993     const BoundPlane RPCSurface = rpcGeometry->chamber(RPCId)->surface();
00994     double startSide = RPCSurface.localZ(startPosition);
00995     cout << "Start side : " << startSide;
00996 
00997     GlobalPoint currentPosition = startPosition;
00998     double currentSide = RPCSurface.localZ(currentPosition);
00999     GlobalVector currentMomentum = startMomentum;
01000     GlobalVector ZDirection(0, 0, 1);
01001 
01002     // Use the perp other than mag, since initial segment might have small value while final recHit have large difference value at Z direction
01003     double currentDistance = ((GlobalVector)(currentPosition - (*iter)->globalPosition())).perp();
01004     cout << "Start current position is : " << currentPosition << endl;
01005     cout << "Start current Momentum is: " << currentMomentum.mag() << ", in vector: " << currentMomentum << endl;
01006     cout << "Start current distance is " << currentDistance << endl;
01007     cout << "Start current radius is " << currentPosition.perp() << endl;
01008     cout << "Destination radius is " << (*iter)->globalPosition().perp() << endl;
01009 
01010     // Judge roughly if the stepping cross the Det surface of the recHit
01011     //while((currentPosition.perp() < ((*iter)->globalPosition().perp())))
01012     double currentDistance_next = currentDistance;
01013     do
01014     {
01015         currentDistance = currentDistance_next;
01016         if(ClockwiseDirection == 0)
01017         {
01018             currentPosition += currentMomentum.unit() * stepLength;
01019         }
01020         else
01021         {
01022             double Bz = Field->inTesla(currentPosition).z();
01023             double Radius = currentMomentum.perp()/fabs(Bz*0.01*0.3);
01024             double deltaPhi = (stepLength*currentMomentum.perp()/currentMomentum.mag())/Radius;
01025 
01026             // Get the center for current step
01027             GlobalVector currentPositiontoCenter = currentMomentum.unit().cross(ZDirection);
01028             currentPositiontoCenter *= Radius;
01029             // correction of ClockwiseDirection correction
01030             currentPositiontoCenter *= ClockwiseDirection;
01031             // continue to get the center for current step
01032             GlobalPoint currentCenter = currentPosition;
01033             currentCenter += currentPositiontoCenter;
01034 
01035             // Get the next step position
01036             GlobalVector CentertocurrentPosition = (GlobalVector)(currentPosition - currentCenter);
01037             double Phi = CentertocurrentPosition.phi().value();
01038             Phi += deltaPhi * (-1) * ClockwiseDirection;
01039             double deltaZ = stepLength*currentMomentum.z()/currentMomentum.mag();
01040             GlobalVector CentertonewPosition(GlobalVector::Cylindrical(CentertocurrentPosition.perp(), Phi, deltaZ));
01041             double PtPhi = currentMomentum.phi().value();
01042             PtPhi += deltaPhi * (-1) * ClockwiseDirection;
01043             currentMomentum = GlobalVector(GlobalVector::Cylindrical(currentMomentum.perp(), PtPhi, currentMomentum.z()));
01044             currentPosition = currentCenter + CentertonewPosition;
01045         }
01046 
01047         // count the total step length
01048         tracklength += stepLength * currentMomentum.perp() / currentMomentum.mag();
01049 
01050         // Get the next step distance
01051         currentSide = RPCSurface.localZ(currentPosition);
01052         cout << "Stepping current side : " << currentSide << endl;
01053         cout << "Stepping current position is: " << currentPosition << endl;
01054         cout << "Stepping current Momentum is: " << currentMomentum.mag() << ", in vector: " << currentMomentum << endl;
01055         currentDistance_next = ((GlobalVector)(currentPosition - (*iter)->globalPosition())).perp();
01056         cout << "Stepping current distance is " << currentDistance << endl;
01057         cout << "Stepping current radius is " << currentPosition.perp() << endl;
01058     }while(currentDistance_next < currentDistance);
01059 
01060     return currentDistance;
01061 }
01062 
01063 RPCSeedPattern::weightedTrajectorySeed RPCSeedPattern::createFakeSeed(int& isGoodSeed, const edm::EventSetup& eSetup)
01064 {
01065     // Create a fake seed and return
01066     cout << "Now create a fake seed" << endl;
01067     isPatternChecked = true;
01068     isGoodPattern = -1;
01069     isStraight = true;
01070     meanPt = upper_limit_pt;
01071     meanSpt = 0;
01072     Charge = 0;
01073     isClockwise = 0;
01074     isParralZ = 0;
01075     meanRadius = -1;
01076     //return createSeed(isGoodSeed, eSetup);
01077 
01078     // Get the reference recHit, DON'T use the recHit on 1st layer(inner most layer) 
01079     const ConstMuonRecHitPointer best = BestRefRecHit();
01080 
01081     Momentum = GlobalVector(0, 0, 0);
01082     LocalPoint segPos=best->localPosition();
01083     LocalVector segDirFromPos=best->det()->toLocal(Momentum);
01084     LocalTrajectoryParameters param(segPos, segDirFromPos, Charge);
01085 
01086     //AlgebraicVector t(4);
01087     AlgebraicSymMatrix mat(5,0);
01088     mat = best->parametersError().similarityT(best->projectionMatrix());
01089     mat[0][0] = meanSpt;
01090     LocalTrajectoryError error(asSMatrix<5>(mat));
01091 
01092     edm::ESHandle<MagneticField> Field;
01093     eSetup.get<IdealMagneticFieldRecord>().get(Field);
01094 
01095     TrajectoryStateOnSurface tsos(param, error, best->det()->surface(), &*Field);
01096 
01097     DetId id = best->geographicalId();
01098     
01099     PTrajectoryStateOnDet seedTSOS = trajectoryStateTransform::persistentState(tsos, id.rawId());
01100 
01101     edm::OwnVector<TrackingRecHit> container;
01102     for(ConstMuonRecHitContainer::const_iterator iter=theRecHits.begin(); iter!=theRecHits.end(); iter++)
01103         container.push_back((*iter)->hit()->clone());
01104 
01105     TrajectorySeed theSeed(seedTSOS, container, alongMomentum);
01106     weightedTrajectorySeed theweightedSeed;
01107     theweightedSeed.first = theSeed;
01108     theweightedSeed.second = meanSpt;
01109     isGoodSeed = isGoodPattern;
01110 
01111     return theweightedSeed;
01112 }
01113 
01114 RPCSeedPattern::weightedTrajectorySeed RPCSeedPattern::createSeed(int& isGoodSeed, const edm::EventSetup& eSetup)
01115 {
01116     if(isPatternChecked == false || isGoodPattern == -1)
01117     {
01118         cout <<"Pattern is not yet checked! Create a fake seed instead!" << endl;
01119         return createFakeSeed(isGoodSeed, eSetup);
01120     }
01121 
01122     edm::ESHandle<MagneticField> Field;
01123     eSetup.get<IdealMagneticFieldRecord>().get(Field);
01124 
01125     MuonPatternRecoDumper debug;
01126 
01127     //double theMinMomentum = 3.0;
01128     //if(fabs(meanPt) < lower_limit_pt) 
01129     //meanPt = lower_limit_pt * meanPt / fabs(meanPt);
01130 
01131     // For pattern we use is Clockwise other than isStraight to estimate charge
01132     if(isClockwise == 0)
01133         Charge = 0;
01134     else
01135         Charge = (int)(meanPt / fabs(meanPt));
01136 
01137     // Get the reference recHit, DON'T use the recHit on 1st layer(inner most layer) 
01138     const ConstMuonRecHitPointer best = BestRefRecHit();
01139     const ConstMuonRecHitPointer first = FirstRecHit();
01140 
01141     if(isClockwise != 0)
01142     {
01143         if(AlgorithmType != 3)
01144         {
01145             // Get the momentum on reference recHit
01146             GlobalVector vecRef1((first->globalPosition().x()-Center.x()), (first->globalPosition().y()-Center.y()), (first->globalPosition().z()-Center.z()));
01147             GlobalVector vecRef2((best->globalPosition().x()-Center.x()), (best->globalPosition().y()-Center.y()), (best->globalPosition().z()-Center.z()));
01148 
01149             double deltaPhi = (vecRef2.phi() - vecRef1.phi()).value();
01150             double deltaS = meanRadius * fabs(deltaPhi);
01151             double deltaZ = best->globalPosition().z() - first->globalPosition().z();
01152 
01153             GlobalVector vecZ(0, 0, 1);
01154             GlobalVector vecPt = (vecRef2.unit()).cross(vecZ);
01155             if(isClockwise == -1)
01156                 vecPt *= -1;
01157             vecPt *= deltaS;
01158             Momentum = GlobalVector(0, 0, deltaZ);
01159             Momentum += vecPt;
01160             Momentum *= fabs(meanPt / deltaS);
01161         }
01162         else
01163         {
01164             double deltaZ = best->globalPosition().z() - first->globalPosition().z();
01165             Momentum = GlobalVector(GlobalVector::Cylindrical(S, lastPhi, deltaZ));
01166             Momentum *= fabs(meanPt / S);
01167         }
01168     }
01169     else
01170     {
01171         Momentum = best->globalPosition() - first->globalPosition();
01172         double deltaS = Momentum.perp();
01173         Momentum *= fabs(meanPt / deltaS);
01174     }
01175     LocalPoint segPos = best->localPosition();
01176     LocalVector segDirFromPos = best->det()->toLocal(Momentum);
01177     LocalTrajectoryParameters param(segPos, segDirFromPos, Charge);
01178 
01179     LocalTrajectoryError error = getSpecialAlgorithmErrorMatrix(first, best);
01180 
01181     TrajectoryStateOnSurface tsos(param, error, best->det()->surface(), &*Field);
01182     cout << "Trajectory State on Surface before the extrapolation" << endl;
01183     cout << debug.dumpTSOS(tsos);
01184     DetId id = best->geographicalId();
01185     cout << "The RecSegment relies on: " << endl;
01186     cout << debug.dumpMuonId(id);
01187     cout << debug.dumpTSOS(tsos);
01188     
01189     PTrajectoryStateOnDet const & seedTSOS = trajectoryStateTransform::persistentState(tsos, id.rawId());
01190 
01191     edm::OwnVector<TrackingRecHit> container;
01192     for(ConstMuonRecHitContainer::const_iterator iter=theRecHits.begin(); iter!=theRecHits.end(); iter++)
01193     {
01194         // This casting withou clone will cause memory overflow when used in push_back
01195         // Since container's deconstructor functiion free the pointer menber!
01196         //TrackingRecHit* pt = dynamic_cast<TrackingRecHit*>(&*(*iter));
01197         //cout << "Push recHit type " << pt->getType() << endl;
01198         container.push_back((*iter)->hit()->clone());
01199     }
01200 
01201     TrajectorySeed theSeed(seedTSOS, container, alongMomentum);
01202     weightedTrajectorySeed theweightedSeed;
01203     theweightedSeed.first = theSeed;
01204     theweightedSeed.second = meanSpt;
01205     isGoodSeed = isGoodPattern;
01206 
01207     return theweightedSeed;
01208 }
01209 
01210 LocalTrajectoryError RPCSeedPattern::getSpecialAlgorithmErrorMatrix(const ConstMuonRecHitPointer& first, const ConstMuonRecHitPointer& best) {
01211 
01212     LocalTrajectoryError Error;
01213     double dXdZ = 0;
01214     double dYdZ = 0;
01215     double dP = 0;
01216     AlgebraicSymMatrix mat(5, 0);
01217     mat = best->parametersError().similarityT(best->projectionMatrix());
01218     if(AlgorithmType != 3) {
01219         GlobalVector vecRef1((first->globalPosition().x()-Center.x()), (first->globalPosition().y()-Center.y()), (first->globalPosition().z()-Center.z()));
01220         GlobalVector vecRef2((best->globalPosition().x()-Center.x()), (best->globalPosition().y()-Center.y()), (best->globalPosition().z()-Center.z()));     
01221         double deltaPhi = (vecRef2.phi() - vecRef1.phi()).value();
01222         double L = meanRadius * fabs(deltaPhi);
01223         double N = nrhit();
01224         double A_N = 180*N*N*N/((N-1)*(N+1)*(N+2)*(N+3));
01225         double sigma_x = sqrt(mat[3][3]);
01226         double betaovergame = Momentum.mag()/0.1066;
01227         double beta = sqrt((betaovergame*betaovergame)/(1+betaovergame*betaovergame));
01228         double dPt = meanPt*(0.0136*sqrt(1/100)*sqrt(4*A_N/N)/(beta*0.3*meanBz*L) + sigma_x*meanPt*sqrt(4*A_N)/(0.3*meanBz*L*L));
01229         double dP = dPt * Momentum.mag() / meanPt;
01230         mat[0][0] = (dP * dP) / (Momentum.mag() * Momentum.mag() * Momentum.mag() * Momentum.mag());
01231         mat[1][1] = dXdZ * dXdZ;
01232         mat[2][2] = dYdZ * dYdZ;
01233         Error = LocalTrajectoryError(asSMatrix<5>(mat));
01234     }
01235     else {
01236         AlgebraicSymMatrix mat0(5, 0);
01237         mat0 = (SegmentRB[0].first)->parametersError().similarityT((SegmentRB[0].first)->projectionMatrix());
01238         double dX0 = sqrt(mat0[3][3]);
01239         double dY0 = sqrt(mat0[4][4]);
01240         AlgebraicSymMatrix mat1(5, 0);
01241         mat1 = (SegmentRB[0].second)->parametersError().similarityT((SegmentRB[0].second)->projectionMatrix());
01242         double dX1 = sqrt(mat1[3][3]);
01243         double dY1 = sqrt(mat1[4][4]);
01244         AlgebraicSymMatrix mat2(5, 0);
01245         mat2 = (SegmentRB[1].first)->parametersError().similarityT((SegmentRB[1].first)->projectionMatrix());
01246         double dX2 = sqrt(mat2[3][3]);
01247         double dY2 = sqrt(mat2[4][4]);
01248         AlgebraicSymMatrix mat3(5, 0);
01249         mat3 = (SegmentRB[1].second)->parametersError().similarityT((SegmentRB[1].second)->projectionMatrix());
01250         double dX3 = sqrt(mat3[3][3]);
01251         double dY3 = sqrt(mat3[4][4]);
01252         cout << "Local error for 4 recHits are: " << dX0 << ", " << dY0 << ", " << dX1 << ", " << dY1 << ", " << dX2 << ", " << dY2 << ", " << dX3 << ", " << dY3 << endl; 
01253         const GeomDetUnit* refRPC1 = (SegmentRB[0].second)->detUnit();
01254         LocalPoint recHit0 = refRPC1->toLocal((SegmentRB[0].first)->globalPosition());
01255         LocalPoint recHit1 = refRPC1->toLocal((SegmentRB[0].second)->globalPosition());
01256         LocalVector localSegment00 = (LocalVector)(recHit1 - recHit0);
01257         LocalVector localSegment01 = LocalVector(localSegment00.x()+dX0+dX1, localSegment00.y(), localSegment00.z());
01258         LocalVector localSegment02 = LocalVector(localSegment00.x()-dX0-dX1, localSegment00.y(), localSegment00.z());
01259         GlobalVector globalSegment00 = refRPC1->toGlobal(localSegment00);
01260         GlobalVector globalSegment01 = refRPC1->toGlobal(localSegment01);
01261         GlobalVector globalSegment02 = refRPC1->toGlobal(localSegment02);
01262 
01263         const GeomDetUnit* refRPC2 = (SegmentRB[1].first)->detUnit();
01264         LocalPoint recHit2 = refRPC2->toLocal((SegmentRB[1].first)->globalPosition());
01265         LocalPoint recHit3 = refRPC2->toLocal((SegmentRB[1].second)->globalPosition());
01266         LocalVector localSegment10 = (LocalVector)(recHit3 - recHit2);
01267         LocalVector localSegment11 = LocalVector(localSegment10.x()+dX2+dX3, localSegment10.y(), localSegment10.z());
01268         LocalVector localSegment12 = LocalVector(localSegment10.x()-dX2-dX3, localSegment10.y(), localSegment10.z());
01269         GlobalVector globalSegment10 = refRPC2->toGlobal(localSegment10);
01270         GlobalVector globalSegment11 = refRPC2->toGlobal(localSegment11);
01271         GlobalVector globalSegment12 = refRPC2->toGlobal(localSegment12);
01272         
01273         if(isClockwise != 0) {
01274             GlobalVector vec[2];
01275             vec[0] = GlobalVector((entryPosition.x()-Center2.x()), (entryPosition.y()-Center2.y()), (entryPosition.z()-Center2.z()));
01276             vec[1] = GlobalVector((leavePosition.x()-Center2.x()), (leavePosition.y()-Center2.y()), (leavePosition.z()-Center2.z()));
01277             double halfPhiCenter = fabs((vec[1].phi() - vec[0].phi()).value()) / 2;
01278             // dPhi0 shoule be the same clockwise direction, while dPhi1 should be opposite clockwise direction, w.r.t to the track clockwise
01279             double dPhi0 = (((globalSegment00.phi() - globalSegment01.phi()).value()*isClockwise) > 0) ? fabs((globalSegment00.phi() - globalSegment01.phi()).value()) : fabs((globalSegment00.phi() - globalSegment02.phi()).value());
01280             double dPhi1 = (((globalSegment10.phi() - globalSegment11.phi()).value()*isClockwise) < 0) ? fabs((globalSegment10.phi() - globalSegment11.phi()).value()) : fabs((globalSegment10.phi() - globalSegment12.phi()).value());
01281             // For the deltaR should be kept small, we assume the delta Phi0/Phi1 should be in a same limit value
01282             double dPhi = (dPhi0 <= dPhi1) ? dPhi0 : dPhi1;
01283             cout << "DPhi for new Segment is about " << dPhi << endl;
01284             // Check the variance of halfPhiCenter
01285             double newhalfPhiCenter = ((halfPhiCenter-dPhi) > 0 ? (halfPhiCenter-dPhi) : 0);
01286             if(newhalfPhiCenter != 0) {
01287                 double newmeanPt = meanPt * halfPhiCenter / newhalfPhiCenter;
01288                 if(fabs(newmeanPt) > upper_limit_pt)
01289                     newmeanPt = upper_limit_pt * meanPt / fabs(meanPt);
01290                 cout << "The error is inside range. Max meanPt could be " << newmeanPt << endl;
01291                 dP = fabs(Momentum.mag() * (newmeanPt - meanPt) / meanPt);
01292             }
01293             else {
01294                 double newmeanPt = upper_limit_pt * meanPt / fabs(meanPt);
01295                 cout << "The error is outside range. Max meanPt could be " << newmeanPt << endl;
01296                 dP = fabs(Momentum.mag() * (newmeanPt - meanPt) / meanPt);
01297             }
01298         }
01299         else {
01300             double dPhi0 = (fabs((globalSegment00.phi() - globalSegment01.phi()).value()) <= fabs((globalSegment00.phi() - globalSegment02.phi()).value())) ? fabs((globalSegment00.phi() - globalSegment01.phi()).value()) : fabs((globalSegment00.phi() - globalSegment02.phi()).value());
01301             double dPhi1 = (fabs((globalSegment10.phi() - globalSegment11.phi()).value()) <= fabs((globalSegment10.phi() - globalSegment12.phi()).value())) ? fabs((globalSegment10.phi() - globalSegment11.phi()).value()) : fabs((globalSegment10.phi() - globalSegment12.phi()).value());
01302             double dPhi = (dPhi0 <= dPhi1) ? dPhi0 : dPhi1;
01303             GlobalVector middleSegment = leavePosition - entryPosition;
01304             double halfDistance = middleSegment.perp() / 2;
01305             double newmeanPt = halfDistance / dPhi;
01306             cout << "The error is for straight. Max meanPt could be " << newmeanPt << endl;
01307             dP = fabs(Momentum.mag() * (newmeanPt - meanPt) / meanPt);
01308         }
01309 
01310         double dXdZ1 = globalSegment11.x() / globalSegment11.z() - globalSegment10.x() / globalSegment10.z();
01311         double dXdZ2 = globalSegment12.x() / globalSegment12.z() - globalSegment10.x() / globalSegment10.z();
01312         dXdZ = (fabs(dXdZ1) >= fabs(dXdZ2)) ? dXdZ1 : dXdZ2;
01313         
01314         LocalVector localSegment13 = LocalVector(localSegment10.x(), localSegment10.y()+dY2+dY3, localSegment10.z());
01315         LocalVector localSegment14 = LocalVector(localSegment10.x(), localSegment10.y()-dY2-dY3, localSegment10.z());
01316         GlobalVector globalSegment13 = refRPC2->toGlobal(localSegment13);
01317         GlobalVector globalSegment14 = refRPC2->toGlobal(localSegment14);        
01318         double dYdZ1 = globalSegment13.y() / globalSegment13.z() - globalSegment10.y() / globalSegment10.z();
01319         double dYdZ2 = globalSegment14.y() / globalSegment14.z() - globalSegment10.y() / globalSegment10.z();
01320         dYdZ = (fabs(dYdZ1) >= fabs(dYdZ2)) ? dYdZ1 : dYdZ2;
01321 
01322         mat[0][0] = (dP * dP) / (Momentum.mag() * Momentum.mag() * Momentum.mag() * Momentum.mag());
01323         mat[1][1] = dXdZ * dXdZ;
01324         mat[2][2] = dYdZ * dYdZ;
01325         Error = LocalTrajectoryError(asSMatrix<5>(mat));
01326     }
01327     return Error;
01328 }