CMS 3D CMS Logo

MuonSeedCreator.cc

Go to the documentation of this file.
00001 
00009 #include "RecoMuon/MuonSeedGenerator/src/MuonSeedCreator.h"
00010 
00011 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHit.h"
00012 
00013 #include "RecoMuon/TrackingTools/interface/MuonPatternRecoDumper.h"
00014 
00015 #include "MagneticField/Engine/interface/MagneticField.h"
00016 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00017 
00018 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00019 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00020 
00021 #include "DataFormats/TrajectoryState/interface/PTrajectoryStateOnDet.h"
00022 #include "DataFormats/Common/interface/OwnVector.h"
00023 #include "DataFormats/MuonDetId/interface/DTChamberId.h"
00024 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00025 #include "DataFormats/MuonDetId/interface/RPCDetId.h"
00026 
00027 #include "FWCore/Framework/interface/EventSetup.h"
00028 #include "FWCore/Framework/interface/ESHandle.h"
00029 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00030 
00031 #include "gsl/gsl_statistics.h"
00032 
00033 
00034 /*
00035  * Constructor
00036  */
00037 MuonSeedCreator::MuonSeedCreator(const edm::ParameterSet& pset){
00038   
00039   theMinMomentum  = pset.getParameter<double>("minimumSeedPt");  
00040   theMaxMomentum  = pset.getParameter<double>("maximumSeedPt");  
00041   defaultMomentum = pset.getParameter<double>("defaultSeedPt");
00042   debug           = pset.getParameter<bool>("DebugMuonSeed");
00043   sysError        = pset.getParameter<double>("SeedPtSystematics");
00044   // load seed PT parameters 
00045   DT12 = pset.getParameter<std::vector<double> >("DT_12");
00046   DT13 = pset.getParameter<std::vector<double> >("DT_13");
00047   DT14 = pset.getParameter<std::vector<double> >("DT_14");
00048   DT23 = pset.getParameter<std::vector<double> >("DT_23");
00049   DT24 = pset.getParameter<std::vector<double> >("DT_24");
00050   DT34 = pset.getParameter<std::vector<double> >("DT_34");
00051 
00052   CSC01 = pset.getParameter<std::vector<double> >("CSC_01");
00053   CSC12 = pset.getParameter<std::vector<double> >("CSC_12");
00054   CSC02 = pset.getParameter<std::vector<double> >("CSC_02");
00055   CSC13 = pset.getParameter<std::vector<double> >("CSC_13");
00056   CSC03 = pset.getParameter<std::vector<double> >("CSC_03");
00057   CSC14 = pset.getParameter<std::vector<double> >("CSC_14");
00058   CSC23 = pset.getParameter<std::vector<double> >("CSC_23");
00059   CSC24 = pset.getParameter<std::vector<double> >("CSC_24");
00060   CSC34 = pset.getParameter<std::vector<double> >("CSC_34");
00061 
00062   OL1213 = pset.getParameter<std::vector<double> >("OL_1213");
00063   OL1222 = pset.getParameter<std::vector<double> >("OL_1222");
00064   OL1232 = pset.getParameter<std::vector<double> >("OL_1232");
00065   OL1213 = pset.getParameter<std::vector<double> >("OL_1213");
00066   OL2222 = pset.getParameter<std::vector<double> >("OL_1222");
00067 
00068   SME11 =  pset.getParameter<std::vector<double> >("SME_11");
00069   SME12 =  pset.getParameter<std::vector<double> >("SME_12");
00070   SME13 =  pset.getParameter<std::vector<double> >("SME_13");
00071   SME21 =  pset.getParameter<std::vector<double> >("SME_21");
00072   SME22 =  pset.getParameter<std::vector<double> >("SME_22");
00073   SME31 =  pset.getParameter<std::vector<double> >("SME_31");
00074   SME32 =  pset.getParameter<std::vector<double> >("SME_32");
00075   SME41 =  pset.getParameter<std::vector<double> >("SME_41");
00076 
00077   SMB10 =  pset.getParameter<std::vector<double> >("SMB_10");
00078   SMB11 =  pset.getParameter<std::vector<double> >("SMB_11");
00079   SMB12 =  pset.getParameter<std::vector<double> >("SMB_12");
00080   SMB20 =  pset.getParameter<std::vector<double> >("SMB_20");
00081   SMB21 =  pset.getParameter<std::vector<double> >("SMB_21");
00082   SMB22 =  pset.getParameter<std::vector<double> >("SMB_22");
00083   SMB30 =  pset.getParameter<std::vector<double> >("SMB_30");
00084   SMB31 =  pset.getParameter<std::vector<double> >("SMB_31");
00085   SMB32 =  pset.getParameter<std::vector<double> >("SMB_32");
00086 
00087   // Load dphi scale parameters
00088   CSC01_1 = pset.getParameter<std::vector<double> >("CSC_01_1_scale");
00089   CSC12_1 = pset.getParameter<std::vector<double> >("CSC_12_1_scale");
00090   CSC12_2 = pset.getParameter<std::vector<double> >("CSC_12_2_scale");
00091   CSC12_3 = pset.getParameter<std::vector<double> >("CSC_12_3_scale");
00092   CSC13_2 = pset.getParameter<std::vector<double> >("CSC_13_2_scale");
00093   CSC13_3 = pset.getParameter<std::vector<double> >("CSC_13_3_scale");
00094   CSC14_3 = pset.getParameter<std::vector<double> >("CSC_14_3_scale");
00095   CSC23_1 = pset.getParameter<std::vector<double> >("CSC_23_1_scale");
00096   CSC23_2 = pset.getParameter<std::vector<double> >("CSC_23_2_scale");
00097   CSC24_1 = pset.getParameter<std::vector<double> >("CSC_24_1_scale");
00098   CSC34_1 = pset.getParameter<std::vector<double> >("CSC_34_1_scale");
00099 
00100   DT12_1 = pset.getParameter<std::vector<double> >("DT_12_1_scale");
00101   DT12_2 = pset.getParameter<std::vector<double> >("DT_12_2_scale");
00102   DT13_1 = pset.getParameter<std::vector<double> >("DT_13_1_scale");
00103   DT13_2 = pset.getParameter<std::vector<double> >("DT_13_2_scale");
00104   DT14_1 = pset.getParameter<std::vector<double> >("DT_14_1_scale");
00105   DT14_2 = pset.getParameter<std::vector<double> >("DT_14_2_scale");
00106   DT23_1 = pset.getParameter<std::vector<double> >("DT_23_1_scale");
00107   DT23_2 = pset.getParameter<std::vector<double> >("DT_23_2_scale");
00108   DT24_1 = pset.getParameter<std::vector<double> >("DT_24_1_scale");
00109   DT24_2 = pset.getParameter<std::vector<double> >("DT_24_2_scale");
00110   DT34_1 = pset.getParameter<std::vector<double> >("DT_34_1_scale");
00111   DT34_2 = pset.getParameter<std::vector<double> >("DT_34_2_scale");
00112 
00113   OL_1213 = pset.getParameter<std::vector<double> >("OL_1213_0_scale");
00114   OL_1222 = pset.getParameter<std::vector<double> >("OL_1222_0_scale");
00115   OL_1232 = pset.getParameter<std::vector<double> >("OL_1232_0_scale");
00116   OL_2213 = pset.getParameter<std::vector<double> >("OL_2213_0_scale");
00117   OL_2222 = pset.getParameter<std::vector<double> >("OL_2222_0_scale");
00118 
00119   SMB_10S = pset.getParameter<std::vector<double> >("SMB_10_0_scale");
00120   SMB_11S = pset.getParameter<std::vector<double> >("SMB_11_0_scale");
00121   SMB_12S = pset.getParameter<std::vector<double> >("SMB_12_0_scale");
00122   SMB_20S = pset.getParameter<std::vector<double> >("SMB_20_0_scale");
00123   SMB_21S = pset.getParameter<std::vector<double> >("SMB_21_0_scale");
00124   SMB_22S = pset.getParameter<std::vector<double> >("SMB_22_0_scale");
00125   SMB_30S = pset.getParameter<std::vector<double> >("SMB_30_0_scale");
00126   SMB_31S = pset.getParameter<std::vector<double> >("SMB_31_0_scale");
00127   SMB_32S = pset.getParameter<std::vector<double> >("SMB_32_0_scale");
00128 
00129   SME_11S = pset.getParameter<std::vector<double> >("SME_11_0_scale");
00130   SME_12S = pset.getParameter<std::vector<double> >("SME_12_0_scale");
00131   SME_13S = pset.getParameter<std::vector<double> >("SME_13_0_scale");
00132   SME_21S = pset.getParameter<std::vector<double> >("SME_21_0_scale");
00133   SME_22S = pset.getParameter<std::vector<double> >("SME_22_0_scale");
00134 
00135 }
00136 
00137 
00138 /*
00139  * Destructor
00140  */
00141 MuonSeedCreator::~MuonSeedCreator(){
00142   
00143 }
00144 
00145 
00146 /*
00147  * createSeed
00148  *
00149  * Note type = 1 --> CSC
00150  *           = 2 --> Overlap
00151  *           = 3 --> DT
00152  */
00153 TrajectorySeed MuonSeedCreator::createSeed(int type, SegmentContainer seg, std::vector<int> layers, int NShowers, int NShowerSegments ) {
00154 
00155   // The index of the station closest to the IP
00156   int last = 0;
00157 
00158   double ptmean = theMinMomentum;
00159   double sptmean = theMinMomentum;
00160 
00161   AlgebraicVector t(4);
00162   AlgebraicSymMatrix mat(5,0) ;
00163   LocalPoint segPos;
00164 
00165   // Compute the pt according to station types used;
00166   if (type == 1 ) estimatePtCSC(seg, layers, ptmean, sptmean);
00167   if (type == 2 ) estimatePtOverlap(seg, layers, ptmean, sptmean);
00168   if (type == 3 ) estimatePtDT(seg, layers, ptmean, sptmean);
00169   if (type == 4 ) estimatePtSingle(seg, layers, ptmean, sptmean);
00170   // type 5 are the seeding for ME1/4
00171   if (type == 5 ) estimatePtCSC(seg, layers, ptmean, sptmean);
00172 
00173   // for certain clear showering case, set-up the minimum value 
00174   if ( NShowers > 0 ) estimatePtShowering( NShowers, NShowerSegments, ptmean, sptmean ); 
00175   //if ( NShowers > 0 ) std::cout<<" Showering happened "<<NShowers<<" times w/ "<< NShowerSegments<<std::endl; ; 
00176 
00177 
00178   // Minimal pt
00179   double charge = 1.0;
00180   if (ptmean < 0.) charge = -1.0; 
00181   if ( (charge * ptmean) < theMinMomentum ) {
00182     ptmean  = theMinMomentum * charge;
00183     sptmean = theMinMomentum ;
00184   }
00185   else if ( (charge * ptmean) > theMaxMomentum ) {
00186     ptmean  = theMaxMomentum * charge;
00187     sptmean = theMaxMomentum * 0.25 ;
00188   }
00189 
00190   LocalTrajectoryParameters param;
00191 
00192   //double dof = static_cast<double>(seg[0]->degreesOfFreedom());
00193   //double chi2_dof = seg[0]->chi2() / dof;
00194   double p_err =0.0;
00195   // determine the seed layer
00196   
00197   int    best_seg= 0;
00198   double chi2_dof = 9999.0;
00199   unsigned int ini_seg = 0;
00200   // avoid generating seed from  1st layer(ME1/1)
00201   if ( type == 5 )  ini_seg = 1;
00202   for (size_t i = ini_seg ; i < seg.size(); i++) {
00203       double dof = static_cast<double>(seg[i]->degreesOfFreedom());
00204       if ( chi2_dof  < ( seg[i]->chi2()/dof ) ) continue;
00205       chi2_dof = seg[i]->chi2() / dof ;
00206       best_seg = static_cast<int>(i);
00207   }  
00208   
00209   //bool highPt = (fabs(ptmean) > 500.) ? true : false ;
00210   //bool badDirection = ( chi2_dof  > 50. ) ? true : false ;
00211   /*
00212   int  segsize = seg.size()-1 ;
00213   int  p2 = segsize ;
00214   int  p1 = 0 ;
00215   if ( best_seg < segsize && best_seg > 0 ) { 
00216      p1 = best_seg - 1 ;
00217      p2 = best_seg + 1 ;
00218   }
00219   if ( best_seg == 0 ) { 
00220      p1 = 0 ;
00221      p2 = best_seg + 1 ;
00222   }
00223   if ( best_seg == segsize ) { 
00224      p1 = best_seg -1 ;
00225      p2 = best_seg    ;
00226   }
00227   */
00228 
00229   if ( type==1 || type==5 || type== 4) {
00230      // Fill the LocalTrajectoryParameters
00232      last = best_seg;
00233      // last = 0;
00234      GlobalVector mom = seg[last]->globalPosition()-GlobalPoint();
00235      segPos = seg[last]->localPosition();
00237   
00238      /*   
00239      GlobalVector polar;
00240      if ( highPt && badDirection && type != 4 )  {
00241         // make up the direction for bad segments 
00242         //GlobalVector dv  = seg[ p2 ]->globalPosition() - seg[ p1 ]->globalPosition(); 
00243         GlobalVector dv  = seg[1]->globalPosition() - seg[0]->globalPosition(); 
00244         GlobalVector polar1(GlobalVector::Spherical(dv.theta(),dv.phi(),1.));
00245         polar = polar1;
00246         last = 0; 
00247         mom = seg[last]->globalPosition()-GlobalPoint();
00248         segPos = seg[last]->localPosition();
00249      } else {
00250         GlobalVector polar2(GlobalVector::Spherical(mom.theta(),seg[last]->globalDirection().phi(),1.));
00251         polar = polar2;
00252      }
00253      GlobalVector polar;
00254      if ( highPt ) {
00255         GlobalVector polar2(GlobalVector::Spherical(mom.theta(),mom.phi(),1.));
00256         polar = polar2;
00257      } else {
00258         GlobalVector polar1(GlobalVector::Spherical(mom.theta(),seg[last]->globalDirection().phi(),1.));
00259         polar = polar1;
00260      } 
00261      */ 
00262      GlobalVector polar(GlobalVector::Spherical(mom.theta(),seg[last]->globalDirection().phi(),1.));
00263       
00264 
00266      polar *= fabs(ptmean)/polar.perp();
00268      LocalVector segDirFromPos = seg[last]->det()->toLocal(polar);
00269      int chargeI = static_cast<int>(charge);
00270      LocalTrajectoryParameters param1(segPos, segDirFromPos, chargeI);
00271      param = param1;
00272      p_err =  (sptmean*sptmean)/(polar.mag()*polar.mag()*ptmean*ptmean) ;
00273      mat = seg[last]->parametersError().similarityT( seg[last]->projectionMatrix() );  
00274      mat[0][0]= p_err;
00275      if ( type == 5 ) { 
00276         mat[0][0] = mat[0][0]/fabs( tan(mom.theta()) ); 
00277         mat[1][1] = mat[1][1]/fabs( tan(mom.theta()) ); 
00278         mat[3][3] = 2.25*mat[3][3];
00279         mat[4][4] = 2.25*mat[4][4];
00280      }
00281      if ( type == 4 ) { 
00282         mat[0][0] = mat[0][0]/fabs( tan(mom.theta()) ); 
00283         mat[1][1] = mat[1][1]/fabs( tan(mom.theta()) ); 
00284         mat[2][2] = 2.25*mat[2][2];
00285         mat[3][3] = 2.25*mat[3][3];
00286         mat[4][4] = 2.25*mat[4][4];
00287      }
00288 
00289      //if ( !highPt && type != 1 ) mat[1][1]= 2.25*mat[1][1];
00290      //if (  highPt && type != 1 ) mat[3][3]= 2.25*mat[1][1];
00291      //mat[2][2]= 3.*mat[2][2];
00292      //mat[3][3]= 2.*mat[3][3];
00293      //mat[4][4]= 2.*mat[4][4];
00294   }
00295   else {
00296      // Fill the LocalTrajectoryParameters
00298      last = 0;
00299      segPos = seg[last]->localPosition();
00300      GlobalVector mom = seg[last]->globalPosition()-GlobalPoint();
00302      GlobalVector polar(GlobalVector::Spherical(mom.theta(),seg[last]->globalDirection().phi(),1.));
00303      //GlobalVector polar(GlobalVector::Spherical(seg[last]->globalDirection().theta(),seg[last]->globalDirection().phi(),1.));
00304 
00306      //double ptRatio = 1.0 - (2.808/(fabs(ptmean) -1)) + (4.546/( (fabs(ptmean)-1)*(fabs(ptmean)-1)) );
00307      //ptmean = ptmean*ptRatio ;
00308       
00310      polar *= fabs(ptmean)/polar.perp();
00312      LocalVector segDirFromPos = seg[last]->det()->toLocal(polar);
00313      int chargeI = static_cast<int>(charge);
00314      LocalTrajectoryParameters param1(segPos, segDirFromPos, chargeI);
00315      param = param1;
00316      p_err =  (sptmean*sptmean)/(polar.mag()*polar.mag()*ptmean*ptmean) ;
00317      mat = seg[last]->parametersError().similarityT( seg[last]->projectionMatrix() );  
00318      //mat[0][0]= 1.44 * p_err;
00319      mat[0][0]= p_err;
00320   }
00321 
00322   if ( debug ) {
00323     GlobalPoint gp = seg[last]->globalPosition();
00324     float Geta = gp.eta();
00325 
00326     std::cout << "Type "      << type   << " Nsegments " << layers.size() << " ";
00327     std::cout << "pt "        << ptmean << " errpt    " << sptmean 
00328               << " eta "      << Geta   << " charge "   << charge 
00329               << std::endl;
00330   }
00331 
00332   // this perform H.T() * parErr * H, which is the projection of the 
00333   // the measurement error (rechit rf) to the state error (TSOS rf)
00334   // Legend:
00335   // H => is the 4x5 projection matrix
00336   // parError the 4x4 parameter error matrix of the RecHit
00337 
00338   
00339   LocalTrajectoryError error(mat);
00340   
00341   // Create the TrajectoryStateOnSurface
00342   TrajectoryStateOnSurface tsos(param, error, seg[last]->det()->surface(),&*BField);
00343   
00344   // Take the DetLayer on which relies the segment
00345   DetId id = seg[last]->geographicalId();
00346 
00347   // Transform it in a TrajectoryStateOnSurface
00348   TrajectoryStateTransform tsTransform;
00349   
00350   //PTrajectoryStateOnDet *seedTSOS = tsTransform.persistentState( tsos, id.rawId());
00351   std::auto_ptr<PTrajectoryStateOnDet> seedTSOS(tsTransform.persistentState( tsos, id.rawId()));  
00352 
00353   edm::OwnVector<TrackingRecHit> container;
00354   for (unsigned l=0; l<seg.size(); l++) {
00355       container.push_back( seg[l]->hit()->clone() ); 
00356       //container.push_back(seg[l]->hit()); 
00357   }
00358 
00359   TrajectorySeed theSeed(*seedTSOS,container,alongMomentum);
00360   return theSeed;
00361 }
00362 
00363 
00364 /*
00365  * estimatePtCSC
00366  *
00367  * Look at delta phi to determine pt as:
00368  * pt = (c_1 * eta + c_2) / dphi
00369  *
00370  * Note that only segment pairs with one segment in the ME1 layers give sensitive results
00371  *
00372  */
00373 void MuonSeedCreator::estimatePtCSC(SegmentContainer seg, std::vector<int> layers, double& thePt, double& theSpt ) {
00374 
00375   unsigned size = seg.size();
00376   if (size < 2) return;
00377   
00378   // reverse the segment and layer container first for pure CSC case
00379   //if ( layers[0] > layers[ layers.size()-1 ] ) {
00380   //   reverse( layers.begin(), layers.end() );
00381   //   reverse( seg.begin(), seg.end() );
00382   //}
00383 
00384   std::vector<double> ptEstimate;
00385   std::vector<double> sptEstimate;
00386 
00387   thePt  = defaultMomentum;
00388   theSpt = defaultMomentum;
00389 
00390   double pt = 0.;
00391   double spt = 0.;   
00392   GlobalPoint  segPos[2];
00393 
00394   int layer0 = layers[0];
00395   segPos[0] = seg[0]->globalPosition();
00396   float eta = fabs( segPos[0].eta() );
00397   float corr = fabs( tan(segPos[0].theta()) );
00398   // use pt from vertex information
00399   /*
00400   if ( layer0 == 0 ) {
00401      SegmentContainer seg0;
00402      seg0.push_back(seg[0]);
00403      std::vector<int> lyr0(1,0);
00404      estimatePtSingle( seg0, lyr0, thePt, theSpt);
00405      ptEstimate.push_back( thePt );
00406      sptEstimate.push_back( theSpt );
00407   }
00408   */
00409 
00410   //std::cout<<" estimate CSC "<<std::endl;
00411 
00412   unsigned idx1 = size;
00413   if (size > 1) {
00414     while ( idx1 > 1 ) {
00415       idx1--;
00416       int layer1 = layers[idx1];
00417       if (layer0 == layer1) continue;
00418       segPos[1] = seg[idx1]->globalPosition();      
00419 
00420       double dphi = segPos[0].phi() - segPos[1].phi();
00421       double temp_dphi = dphi/corr;
00422        
00423       double sign = 1.0;  
00424       if (temp_dphi < 0.) {
00425         temp_dphi = -1.0*temp_dphi;
00426         sign = -1.0;
00427       }
00428 
00429       // Ensure that delta phi is not too small to prevent pt from blowing up
00430       if (temp_dphi < 0.0001 ) { 
00431          temp_dphi = 0.0001 ;
00432          pt = theMaxMomentum ;
00433          spt = theMaxMomentum*0.25 ; 
00434          ptEstimate.push_back( pt*sign );
00435          sptEstimate.push_back( spt );
00436       }
00437       // ME1 is inner-most
00438       if ( layer0 == 0 && temp_dphi >= 0.0001 ) {
00439  
00440         // ME1/2 is outer-most
00441         if ( layer1 ==  1 ) {
00442           //temp_dphi = scaledPhi(temp_dphi, CSC01_1[3] );
00443           pt  = getPt( CSC01, eta , temp_dphi )[0];
00444           spt = getPt( CSC01, eta , temp_dphi )[1];
00445         }  
00446         // ME2 is outer-most
00447         else if ( layer1 == 2  ) {
00448           //temp_dphi = scaledPhi(temp_dphi, CSC12_3[3] );
00449           pt  = getPt( CSC02, eta , temp_dphi )[0];
00450           spt = getPt( CSC02, eta , temp_dphi )[1];
00451         }
00452         // ME3 is outer-most
00453         else if ( layer1 == 3 ) {
00454           //temp_dphi = scaledPhi(temp_dphi, CSC13_3[3] );
00455           pt  = getPt( CSC03, eta , temp_dphi )[0];
00456           spt = getPt( CSC03, eta , temp_dphi )[1];
00457         }
00458         // ME4 is outer-most
00459         else {
00460           //temp_dphi = scaledPhi(temp_dphi, CSC14_3[3]);
00461           pt  = getPt( CSC14, eta , temp_dphi )[0];
00462           spt = getPt( CSC14, eta , temp_dphi )[1];
00463         }
00464         ptEstimate.push_back( pt*sign );
00465         sptEstimate.push_back( spt );
00466       }
00467 
00468       // ME1/2,ME1/3 is inner-most
00469       if ( layer0 == 1 ) {
00470         // ME2 is outer-most
00471         if ( layer1 == 2 ) {
00472 
00473           if ( eta <= 1.2 )  {   temp_dphi = scaledPhi(temp_dphi, CSC12_1[3]); }
00474           if ( eta >  1.2 )  {   temp_dphi = scaledPhi(temp_dphi, CSC12_2[3]); }
00475           pt  = getPt( CSC12, eta , temp_dphi )[0];
00476           spt = getPt( CSC12, eta , temp_dphi )[1];
00477         }
00478         // ME3 is outer-most
00479         else if ( layer1 == 3 ) {
00480           temp_dphi = scaledPhi(temp_dphi, CSC13_2[3]);
00481           pt  = getPt( CSC13, eta , temp_dphi )[0];
00482           spt = getPt( CSC13, eta , temp_dphi )[1];
00483         }
00484         // ME4 is outer-most
00485         else {
00486           temp_dphi = scaledPhi(temp_dphi, CSC14_3[3]);
00487           pt  = getPt( CSC14, eta , temp_dphi )[0];
00488           spt = getPt( CSC14, eta , temp_dphi )[1];
00489         }
00490         ptEstimate.push_back( pt*sign );
00491         sptEstimate.push_back( spt );
00492       }
00493 
00494       // ME2 is inner-most
00495       if ( layer0 == 2 && temp_dphi > 0.0001 ) {
00496 
00497         // ME4 is outer-most
00498         bool ME4av =false;
00499         if ( layer1 == 4 )  {
00500           temp_dphi = scaledPhi(temp_dphi, CSC24_1[3]);
00501           pt  = getPt( CSC24, eta , temp_dphi )[0];
00502           spt = getPt( CSC24, eta , temp_dphi )[1];
00503           ME4av = true;
00504         }
00505         // ME3 is outer-most
00506         else {
00507           // if ME2-4 is availabe , discard ME2-3 
00508           if ( !ME4av ) {
00509             if ( eta <= 1.7 )  {   temp_dphi = scaledPhi(temp_dphi, CSC23_1[3]); }
00510             if ( eta >  1.7 )  {   temp_dphi = scaledPhi(temp_dphi, CSC23_2[3]); }
00511             pt  = getPt( CSC23, eta , temp_dphi )[0];
00512             spt = getPt( CSC23, eta , temp_dphi )[1];
00513           }
00514         }
00515         ptEstimate.push_back( pt*sign );   
00516         sptEstimate.push_back( spt );
00517       }
00518 
00519       // ME3 is inner-most
00520       if ( layer0 == 3 && temp_dphi > 0.0001 ) {
00521 
00522         temp_dphi = scaledPhi(temp_dphi, CSC34_1[3]);
00523         pt  = getPt( CSC34, eta , temp_dphi )[0];
00524         spt = getPt( CSC34, eta , temp_dphi )[1];
00525         ptEstimate.push_back( pt*sign );   
00526         sptEstimate.push_back( spt );
00527       }
00528 
00529     } 
00530   }
00531 
00532   // Compute weighted average if have more than one estimator
00533   if ( ptEstimate.size() > 0 ) weightedPt( ptEstimate, sptEstimate, thePt, theSpt);
00534 
00535 }
00536 
00537 
00538 /*
00539  * estimatePtDT
00540  *
00541  * Look at delta phi between segments to determine pt as:
00542  * pt = (c_1 * eta + c_2) / dphi
00543  */
00544 void MuonSeedCreator::estimatePtDT(SegmentContainer seg, std::vector<int> layers, double& thePt, double& theSpt) {
00545 
00546   unsigned size = seg.size();
00547   if (size < 2) return;
00548   
00549   std::vector<double> ptEstimate;
00550   std::vector<double> sptEstimate;
00551 
00552   thePt  = defaultMomentum;
00553   theSpt = defaultMomentum;
00554 
00555   double pt = 0.;
00556   double spt = 0.;   
00557   GlobalPoint segPos[2];
00558 
00559   int layer0 = layers[0];
00560   segPos[0] = seg[0]->globalPosition();
00561   float eta = fabs(segPos[0].eta());
00562 
00563   //std::cout<<" estimate DT "<<std::endl;
00564   // inner-most layer
00565   //for ( unsigned idx0 = 0; idx0 < size-1; ++idx0 ) {
00566   //  layer0 = layers[idx0];
00567   //  segPos[0]  = seg[idx0]->globalPosition();
00568     // outer-most layer
00569     // for ( unsigned idx1 = idx0+1; idx1 < size; ++idx1 ) {
00570     for ( unsigned idx1 = 1; idx1 <size ;  ++idx1 ) {
00571 
00572       int layer1 = layers[idx1];
00573       segPos[1] = seg[idx1]->globalPosition();      
00574  
00575       //eta = fabs(segPos[1].eta());  
00576       //if (layer1 == -4) eta = fabs(segPos[0].eta());
00577 
00578       double dphi = segPos[0].phi() - segPos[1].phi();
00579       double temp_dphi = dphi;
00580 
00581       // Ensure that delta phi is not too small to prevent pt from blowing up
00582       
00583       double sign = 1.0;  
00584       if (temp_dphi < 0.) {
00585         temp_dphi = -temp_dphi;
00586         sign = -1.0;
00587       }
00588       
00589       if (temp_dphi < 0.0001 ) { 
00590          temp_dphi = 0.0001 ;
00591          pt = theMaxMomentum ;
00592          spt = theMaxMomentum*0.25 ; 
00593          ptEstimate.push_back( pt*sign );
00594          sptEstimate.push_back( spt );
00595       }
00596 
00597       // MB1 is inner-most
00598       bool MB23av = false;
00599       if (layer0 == -1 && temp_dphi > 0.0001 ) {
00600         // MB2 is outer-most
00601         if (layer1 == -2) {
00602 
00603           if ( eta <= 0.7 )  {   temp_dphi = scaledPhi(temp_dphi, DT12_1[3]); }
00604           if ( eta >  0.7 )  {   temp_dphi = scaledPhi(temp_dphi, DT12_2[3]); }
00605           pt  = getPt( DT12, eta , temp_dphi )[0];
00606           spt = getPt( DT12, eta , temp_dphi )[1];
00607           MB23av = true;
00608         }
00609         // MB3 is outer-most
00610         else if (layer1 == -3) {
00611 
00612           if ( eta <= 0.6 )  {   temp_dphi = scaledPhi(temp_dphi, DT13_1[3]); }
00613           if ( eta >  0.6 )  {   temp_dphi = scaledPhi(temp_dphi, DT13_2[3]); }
00614           pt  = getPt( DT13, eta , temp_dphi )[0];
00615           spt = getPt( DT13, eta , temp_dphi )[1];
00616           MB23av = true;
00617         }
00618         // MB4 is outer-most
00619         else {
00620           if ( !MB23av ) {
00621              if ( eta <= 0.52 )  {   temp_dphi = scaledPhi(temp_dphi, DT14_1[3]); }
00622              if ( eta >  0.52 )  {   temp_dphi = scaledPhi(temp_dphi, DT14_2[3]); }
00623              pt  = getPt( DT14, eta , temp_dphi )[0];
00624              spt = getPt( DT14, eta , temp_dphi )[1];
00625           }
00626         }
00627         ptEstimate.push_back( pt*sign );
00628         sptEstimate.push_back( spt );
00629       }
00630 
00631       // MB2 is inner-most
00632       if (layer0 == -2 && temp_dphi > 0.0001 ) {
00633         // MB3 is outer-most
00634         if ( layer1 == -3) {
00635 
00636           if ( eta <= 0.6 )  {   temp_dphi = scaledPhi(temp_dphi, DT23_1[3]); }
00637           if ( eta >  0.6 )  {   temp_dphi = scaledPhi(temp_dphi, DT23_2[3]); }
00638           pt  = getPt( DT23, eta , temp_dphi )[0];
00639           spt = getPt( DT23, eta , temp_dphi )[1];
00640         }
00641         // MB4 is outer-most
00642         else {
00643 
00644           if ( eta <= 0.52 )  {   temp_dphi = scaledPhi(temp_dphi, DT24_1[3]); }
00645           if ( eta >  0.52 )  {   temp_dphi = scaledPhi(temp_dphi, DT24_2[3]); }
00646           pt  = getPt( DT24, eta , temp_dphi )[0];
00647           spt = getPt( DT24, eta , temp_dphi )[1];
00648         }
00649         ptEstimate.push_back( pt*sign );
00650         sptEstimate.push_back( spt );
00651       }
00652 
00653       // MB3 is inner-most    -> only marginally useful to pick up the charge
00654       if (layer0 == -3 && temp_dphi > 0.0001 ) {
00655         // MB4 is outer-most
00656 
00657         if ( eta <= 0.51 )  {   temp_dphi = scaledPhi(temp_dphi, DT34_1[3]); }
00658         if ( eta >  0.51 )  {   temp_dphi = scaledPhi(temp_dphi, DT34_2[3]); }
00659         pt  = getPt( DT34, eta , temp_dphi )[0];
00660         spt = getPt( DT34, eta , temp_dphi )[1];
00661         ptEstimate.push_back( pt*sign );   
00662         sptEstimate.push_back( spt );
00663       }
00664     }   
00665   //}
00666   
00667   
00668   // Compute weighted average if have more than one estimator
00669   if (ptEstimate.size() > 0 ) weightedPt( ptEstimate, sptEstimate, thePt, theSpt);
00670 
00671 }
00672 
00673 
00674 /*
00675  * estimatePtOverlap
00676  *
00677  */
00678 void MuonSeedCreator::estimatePtOverlap(SegmentContainer seg, std::vector<int> layers, double& thePt, double& theSpt) {
00679 
00680   int size = layers.size();
00681 
00682   thePt  = defaultMomentum;
00683   theSpt = defaultMomentum;
00684 
00685   SegmentContainer segCSC;
00686   std::vector<int> layersCSC;
00687   SegmentContainer segDT;
00688   std::vector<int> layersDT;
00689 
00690   // DT layers are numbered as -4 to -1, whereas CSC layers go from 0 to 4:
00691   for ( unsigned j = 0; j < layers.size(); ++j ) {
00692     if ( layers[j] > -1 ) {
00693       segCSC.push_back(seg[j]);
00694       layersCSC.push_back(layers[j]);
00695     } 
00696     else {
00697       segDT.push_back(seg[j]);
00698       layersDT.push_back(layers[j]);
00699     } 
00700   }
00701 
00702   std::vector<double> ptEstimate;
00703   std::vector<double> sptEstimate;
00704 
00705   GlobalPoint segPos[2];
00706   int layer0 = layers[0];
00707   segPos[0] = seg[0]->globalPosition();
00708   float eta = fabs(segPos[0].eta());
00709   //std::cout<<" estimate OL "<<std::endl;
00710     
00711   if ( segDT.size() > 0 && segCSC.size() > 0 ) {
00712     int layer1 = layers[size-1];
00713     segPos[1] = seg[size-1]->globalPosition();
00714   
00715     double dphi = segPos[0].phi() - segPos[1].phi();
00716     double temp_dphi = dphi;
00717 
00718     // Ensure that delta phi is not too small to prevent pt from blowing up
00719     
00720     double sign = 1.0;
00721     if (temp_dphi < 0.) {      
00722       temp_dphi = -temp_dphi;
00723       sign = -1.0;  
00724     } 
00725      
00726     if (temp_dphi < 0.0001 ) { 
00727          temp_dphi = 0.0001 ;
00728          thePt = theMaxMomentum ;
00729          theSpt = theMaxMomentum*0.25 ; 
00730          ptEstimate.push_back( thePt*sign );
00731          sptEstimate.push_back( theSpt );
00732     }
00733   
00734     // MB1 is inner-most
00735     if ( layer0 == -1 && temp_dphi > 0.0001 ) {
00736       // ME1/3 is outer-most
00737       if ( layer1 == 1 ) {
00738         temp_dphi = scaledPhi(temp_dphi, OL_1213[3]);
00739         thePt  = getPt( OL1213, eta , temp_dphi )[0];
00740         theSpt = getPt( OL1213, eta , temp_dphi )[1];
00741       }
00742       // ME2 is outer-most
00743       else if ( layer1 == 2) {
00744         temp_dphi = scaledPhi(temp_dphi, OL_1222[3]);
00745         thePt  = getPt( OL1222, eta , temp_dphi )[0];
00746         theSpt = getPt( OL1222, eta , temp_dphi )[1];
00747       }
00748       // ME3 is outer-most
00749       else {
00750         temp_dphi = scaledPhi(temp_dphi, OL_1232[3]);
00751         thePt  = getPt( OL1232, eta , temp_dphi )[0];
00752         theSpt = getPt( OL1232, eta , temp_dphi )[1];
00753       }
00754       ptEstimate.push_back(thePt*sign);
00755       sptEstimate.push_back(theSpt);
00756     } 
00757     // MB2 is inner-most
00758     if ( layer0 == -2 && temp_dphi > 0.0001 ) {
00759       // ME1/3 is outer-most
00760       if ( layer1 == 1 ) {
00761         temp_dphi = scaledPhi(temp_dphi, OL_2213[3]);
00762         thePt  = getPt( OL2213, eta , temp_dphi )[0];
00763         theSpt = getPt( OL2213, eta , temp_dphi )[1];
00764         ptEstimate.push_back(thePt*sign);
00765         sptEstimate.push_back(theSpt);
00766       }
00767       // ME2 is outer-most
00768       if ( layer1 == 2) {
00769         temp_dphi = scaledPhi(temp_dphi, OL_2222[3]);
00770         thePt  = getPt( OL2222, eta , temp_dphi )[0];
00771         theSpt = getPt( OL2222, eta , temp_dphi )[1];
00772       }
00773     }
00774   } 
00775 
00776   if ( segDT.size() > 1 ) {
00777     estimatePtDT(segDT, layersDT, thePt, theSpt);
00778     ptEstimate.push_back(thePt);
00779     sptEstimate.push_back(theSpt);
00780   } 
00781 
00782   /*
00783   // not useful ....and pt estimation is bad
00784   if ( segCSC.size() > 1 ) {
00785     // don't estimate pt without ME1 information
00786     bool CSCLayer1=false;
00787     for (unsigned i=0; i< layersCSC.size(); i++) {
00788         if ( layersCSC[i]==0 || layersCSC[i]==1 ) CSCLayer1 = true;
00789     }
00790     if (CSCLayer1) {
00791        estimatePtCSC(segCSC, layersCSC, thePt, theSpt);
00792        ptEstimate.push_back(thePt);
00793        sptEstimate.push_back(theSpt);
00794     }
00795   }
00796   */
00797 
00798   // Compute weighted average if have more than one estimator
00799   if (ptEstimate.size() > 0 ) weightedPt( ptEstimate, sptEstimate, thePt, theSpt);
00800 
00801 }
00802 /*
00803  *
00804  *   estimate Pt for single segment events
00805  *
00806  */
00807 void MuonSeedCreator::estimatePtSingle(SegmentContainer seg, std::vector<int> layers, double& thePt, double& theSpt) {
00808 
00809   thePt  = defaultMomentum;
00810   theSpt = defaultMomentum;
00811 
00812   GlobalPoint segPos = seg[0]->globalPosition();
00813   double eta = segPos.eta();
00814   GlobalVector gv = seg[0]->globalDirection();
00815 
00816   // Psi is angle between the segment origin and segment direction
00817   // Use dot product between two vectors to get Psi in global x-y plane
00818   double cosDpsi  = (gv.x()*segPos.x() + gv.y()*segPos.y());
00819   cosDpsi /= sqrt(segPos.x()*segPos.x() + segPos.y()*segPos.y());
00820   cosDpsi /= sqrt(gv.x()*gv.x() + gv.y()*gv.y());
00821 
00822   double axb = ( segPos.x()*gv.y() ) - ( segPos.y()*gv.x() ) ;
00823   double sign = (axb < 0.) ? 1.0 : -1.0;
00824 
00825   double dpsi = fabs(acos(cosDpsi)) ;
00826   if ( dpsi > 1.570796 ) {
00827       dpsi = 3.141592 - dpsi;
00828       sign = -1.*sign ;
00829   }
00830   if (fabs(dpsi) < 0.00005) {
00831      dpsi = 0.00005;
00832   }
00833 
00834   // the 1st layer
00835   if ( layers[0] == -1 ) {
00836      // MB10
00837      if ( fabs(eta) < 0.3 ) {
00838         dpsi = scaledPhi(dpsi, SMB_10S[3] );
00839         thePt  = getPt( SMB10, eta , dpsi )[0];
00840         theSpt = getPt( SMB10, eta , dpsi )[1];
00841      }
00842      // MB11
00843      if ( fabs(eta) >= 0.3 && fabs(eta) < 0.82 ) {
00844         dpsi = scaledPhi(dpsi, SMB_11S[3] );
00845         thePt  = getPt( SMB11, eta , dpsi )[0];
00846         theSpt = getPt( SMB11, eta , dpsi )[1];
00847      }
00848      // MB12
00849      if ( fabs(eta) >= 0.82 && fabs(eta) < 1.2 ) {
00850         dpsi = scaledPhi(dpsi, SMB_12S[3] );
00851         thePt  = getPt( SMB12, eta , dpsi )[0];
00852         theSpt = getPt( SMB12, eta , dpsi )[1];
00853      }
00854   }
00855   if ( layers[0] == 1 ) {
00856      // ME13
00857      if ( fabs(eta) > 0.92 && fabs(eta) < 1.16 ) {
00858         dpsi = scaledPhi(dpsi, SME_13S[3] );
00859         thePt  = getPt( SME13, eta , dpsi )[0];
00860         theSpt = getPt( SME13, eta , dpsi )[1];
00861      }
00862      // ME12
00863      if ( fabs(eta) >= 1.16 && fabs(eta) <= 1.6 ) {
00864         dpsi = scaledPhi(dpsi, SME_12S[3] );
00865         thePt  = getPt( SME12, eta , dpsi )[0];
00866         theSpt = getPt( SME12, eta , dpsi )[1];
00867      }
00868   }
00869   if ( layers[0] == 0  ) {
00870      // ME11
00871      if ( fabs(eta) > 1.6 ) {
00872         dpsi = scaledPhi(dpsi, SMB_11S[3] );
00873         thePt  = getPt( SME11, eta , dpsi )[0];
00874         theSpt = getPt( SME11, eta , dpsi )[1];
00875      }
00876   }
00877   // the 2nd layer
00878   if ( layers[0] == -2 ) {
00879      // MB20
00880      if ( fabs(eta) < 0.25 ) {
00881         dpsi = scaledPhi(dpsi, SMB_20S[3] );
00882         thePt  = getPt( SMB20, eta , dpsi )[0];
00883         theSpt = getPt( SMB20, eta , dpsi )[1];
00884      }
00885      // MB21
00886      if ( fabs(eta) >= 0.25 && fabs(eta) < 0.72 ) {
00887         dpsi = scaledPhi(dpsi, SMB_21S[3] );
00888         thePt  = getPt( SMB21, eta , dpsi )[0];
00889         theSpt = getPt( SMB21, eta , dpsi )[1];
00890      }
00891      // MB22
00892      if ( fabs(eta) >= 0.72 && fabs(eta) < 1.04 ) {
00893         dpsi = scaledPhi(dpsi, SMB_22S[3] );
00894         thePt  = getPt( SMB22, eta , dpsi )[0];
00895         theSpt = getPt( SMB22, eta , dpsi )[1];
00896      }
00897   }
00898   if ( layers[0] == 2 ) {
00899      // ME22
00900      if ( fabs(eta) > 0.95 && fabs(eta) <= 1.6 ) {
00901         dpsi = scaledPhi(dpsi, SME_22S[3] );
00902         thePt  = getPt( SME22, eta , dpsi )[0];
00903         theSpt = getPt( SME22, eta , dpsi )[1];
00904      }
00905      // ME21
00906      if ( fabs(eta) > 1.6 && fabs(eta) < 2.45 ) {
00907         dpsi = scaledPhi(dpsi, SME_21S[3] );
00908         thePt  = getPt( SME21, eta , dpsi )[0];
00909         theSpt = getPt( SME21, eta , dpsi )[1];
00910      }
00911   }
00912 
00913   // the 3rd layer
00914   if ( layers[0] == -3 ) {
00915      // MB30
00916      if ( fabs(eta) <= 0.22 ) {
00917         dpsi = scaledPhi(dpsi, SMB_30S[3] );
00918         thePt  = getPt( SMB30, eta , dpsi )[0];
00919         theSpt = getPt( SMB30, eta , dpsi )[1];
00920      }
00921      // MB31
00922      if ( fabs(eta) > 0.22 && fabs(eta) <= 0.6 ) {
00923         dpsi = scaledPhi(dpsi, SMB_31S[3] );
00924         thePt  = getPt( SMB31, eta , dpsi )[0];
00925         theSpt = getPt( SMB31, eta , dpsi )[1];
00926      }
00927      // MB32
00928      if ( fabs(eta) > 0.6 && fabs(eta) < 0.95 ) {
00929         dpsi = scaledPhi(dpsi, SMB_32S[3] );
00930         thePt  = getPt( SMB32, eta , dpsi )[0];
00931         theSpt = getPt( SMB32, eta , dpsi )[1];
00932      }
00933   }
00934   thePt = fabs(thePt)*sign;
00935   theSpt = fabs(theSpt);
00936 
00937   return;
00938 }
00939 
00940 // setup the minimum value for obvious showering cases  
00941 void MuonSeedCreator::estimatePtShowering(int& NShowers, int& NShowerSegments,  double& thePt, double& theSpt) {
00942 
00943   if ( NShowers > 2 && thePt < 300. ) {
00944      thePt  = 800. ;
00945      theSpt = 200. ; 
00946   } 
00947   if ( NShowers == 2 && NShowerSegments >  11 && thePt < 150. ) {
00948      thePt = 280. ;
00949      theSpt = 70. ; 
00950   }
00951   if ( NShowers == 2 && NShowerSegments <= 11 && thePt < 50.  ) {
00952      thePt =  80.;
00953      theSpt = 40. ;
00954   }
00955   if ( NShowers == 1 && NShowerSegments <= 5 && thePt < 10. ) {
00956      thePt = 16. ;
00957      theSpt = 8. ; 
00958   }
00959 
00960 }
00961 
00962 /*
00963  * weightedPt
00964  *
00965  * Look at delta phi between segments to determine pt as:
00966  * pt = (c_1 * eta + c_2) / dphi
00967  */
00968 void MuonSeedCreator::weightedPt(std::vector<double> ptEstimate, std::vector<double> sptEstimate, double& thePt, double& theSpt) {
00969 
00970  
00971   int size = ptEstimate.size();
00972 
00973   // If only one element, by-pass computation below
00974   if (size < 2) {
00975     thePt = ptEstimate[0];
00976     theSpt = sptEstimate[0];
00977     return;
00978   }
00979 
00980   double charge = 0.;
00981   // If have more than one pt estimator, first look if any estimator is biased
00982   // by comparing the charge of each estimator
00983 
00984   for ( unsigned j = 0; j < ptEstimate.size(); j++ ) {
00985     //std::cout<<" weighting pt: "<< ptEstimate[j] <<std::endl; 
00986     if ( ptEstimate[j] < 0. ) {
00987       // To prevent from blowing up, add 0.1 
00988       charge -= 1. * (ptEstimate[j]*ptEstimate[j]) / (sptEstimate[j]*sptEstimate[j] );  // weight by relative error on pt
00989     } else {
00990       charge += 1. * (ptEstimate[j]*ptEstimate[j]) / (sptEstimate[j]*sptEstimate[j] );  // weight by relative error on pt
00991     }
00992   }
00993  
00994   // No need to normalize as we want to know only sign ( + or - )
00995   if (charge < 0.) {
00996     charge = -1.;
00997   } else {
00998     charge = 1.;
00999   }
01000 
01001   //int n = 0;
01002   double weightPtSum  = 0.;
01003   double sigmaSqr_sum = 0.;
01004           
01005   // Now, we want to compute average Pt using estimators with "correct" charge
01006   // This is to remove biases
01007   for ( unsigned j = 0; j < ptEstimate.size(); ++j ) {
01008     //if ( (minpt_ratio < 0.5) && (fabs(ptEstimate[j]) < 5.0) ) continue;
01009     //if ( ptEstimate[j] * charge > 0. ) {
01010       //n++;
01011       sigmaSqr_sum += 1.0 / (sptEstimate[j]*sptEstimate[j]);
01012       weightPtSum  += fabs(ptEstimate[j])/(sptEstimate[j]*sptEstimate[j]);
01013     //}
01014   }
01015   /*  
01016   if (n < 1) {
01017     thePt  = defaultMomentum*charge;
01018     theSpt = defaultMomentum; 
01019     return;
01020   } 
01021   */
01022   // Compute weighted mean and error
01023 
01024   thePt  = (charge*weightPtSum) / sigmaSqr_sum;
01025   theSpt = sqrt( 1.0 / sigmaSqr_sum ) ;
01026 
01027   //std::cout<<" final weighting : "<< thePt <<" ~ "<< fabs( theSpt/thePt ) <<std::endl;
01028 
01029   return;
01030 }
01031 
01032 std::vector<double> MuonSeedCreator::getPt(std::vector<double> vPara, double eta, double dPhi ) {
01033 
01034        double h  = fabs(eta);
01035        double estPt  = ( vPara[0] + vPara[1]*h + vPara[2]*h*h ) / dPhi;
01036        double estSPt = ( vPara[3] + vPara[4]*h + vPara[5]*h*h ) * estPt;
01037        std::vector<double> paraPt ;
01038        paraPt.push_back( estPt );
01039        paraPt.push_back( estSPt ) ;
01040 
01041        //std::cout<<"      pt:"<<estPt<<" +/-"<< estSPt<<"   h:"<<eta<<"  df:"<<dPhi<<std::endl;
01042        return paraPt ;
01043 }
01044 
01045 double MuonSeedCreator::scaledPhi( double dphi, double t1) {
01046 
01047   if (dphi != 0. ) {
01048 
01049     double oPhi = 1./dphi ;
01050     dphi = dphi /( 1. + t1/( oPhi + 10. ) ) ;
01051     return dphi ;
01052 
01053   } else {
01054     return dphi ;
01055   } 
01056 
01057 }
01058 

Generated on Tue Jun 9 17:44:26 2009 for CMSSW by  doxygen 1.5.4