CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/L1Trigger/CSCTrackFinder/src/CSCTFPtLUT.cc

Go to the documentation of this file.
00001 /*****************************************************
00002  * 28/01/2010
00003  * GP: added new switch to use the beam start Pt LUTs
00004  * if (eta > 2.1) 2 stations tracks have quality 2
00005  *                3 stations tracks have quality 3
00006  * NB: no matter if the have ME1
00007  * 
00008  * --> by default is set to true
00009  *****************************************************/
00010 
00011 #include <L1Trigger/CSCTrackFinder/interface/CSCTFPtLUT.h>
00012 #include <DataFormats/L1CSCTrackFinder/interface/CSCTFConstants.h>
00013 #include <FWCore/MessageLogger/interface/MessageLogger.h>
00014 #include <fstream>
00015 
00016 ptdat* CSCTFPtLUT::pt_lut = NULL;
00017 bool CSCTFPtLUT::lut_read_in = false;
00018 // L1MuTriggerScales CSCTFPtLUT::trigger_scale;
00019 // L1MuTriggerPtScale CSCTFPtLUT::trigger_ptscale;
00020 // CSCTFPtMethods CSCTFPtLUT::ptMethods;
00021 
00023 #include "CondFormats/L1TObjects/interface/L1MuCSCPtLut.h"
00024 #include "CondFormats/DataRecord/interface/L1MuCSCPtLutRcd.h"
00025 #include "FWCore/Framework/interface/ESHandle.h"
00026 #include <L1Trigger/CSCTrackFinder/interface/CSCTFPtLUT.h>
00027 
00028 #include "CondFormats/L1TObjects/interface/L1MuTriggerScales.h"
00029 #include "CondFormats/DataRecord/interface/L1MuTriggerScalesRcd.h"
00030 #include "CondFormats/L1TObjects/interface/L1MuTriggerPtScale.h"
00031 #include "CondFormats/DataRecord/interface/L1MuTriggerPtScaleRcd.h"
00032 
00033 CSCTFPtLUT::CSCTFPtLUT(const edm::EventSetup& es) 
00034     : read_pt_lut(false),
00035       isBinary(false)
00036 {
00037         pt_method = 4;
00038         lowQualityFlag = 4;
00039         isBeamStartConf = true;
00040         pt_lut = new ptdat[1<<21];
00041 
00042         edm::ESHandle<L1MuCSCPtLut> ptLUT;
00043         es.get<L1MuCSCPtLutRcd>().get(ptLUT);
00044         const L1MuCSCPtLut *myConfigPt_ = ptLUT.product();
00045 
00046         memcpy((void*)pt_lut,(void*)myConfigPt_->lut(),(1<<21)*sizeof(ptdat));
00047 
00048         lut_read_in = true;
00049 
00050         edm::ESHandle< L1MuTriggerScales > scales ;
00051         es.get< L1MuTriggerScalesRcd >().get( scales ) ;
00052         trigger_scale = scales.product() ;
00053 
00054         edm::ESHandle< L1MuTriggerPtScale > ptScale ;
00055         es.get< L1MuTriggerPtScaleRcd >().get( ptScale ) ;
00056         trigger_ptscale = ptScale.product() ;
00057 
00058         ptMethods = CSCTFPtMethods( ptScale.product() ) ;
00059 }
00061 
00062 CSCTFPtLUT::CSCTFPtLUT(const edm::ParameterSet& pset,
00063                        const L1MuTriggerScales* scales,
00064                        const L1MuTriggerPtScale* ptScale)
00065   : trigger_scale( scales ),
00066     trigger_ptscale( ptScale ),
00067     ptMethods( ptScale ),
00068     read_pt_lut(false),
00069     isBinary(false)
00070 {
00071   //read_pt_lut = pset.getUntrackedParameter<bool>("ReadPtLUT",false);
00072   read_pt_lut = pset.getParameter<bool>("ReadPtLUT");
00073   if(read_pt_lut)
00074     {
00075       pt_lut_file = pset.getParameter<edm::FileInPath>("PtLUTFile");
00076       //isBinary = pset.getUntrackedParameter<bool>("isBinary", false);
00077       isBinary = pset.getParameter<bool>("isBinary");
00078 
00079       edm::LogInfo("CSCTFPtLUT::CSCTFPtLUT") << "Reading file: "
00080                                              << pt_lut_file.fullPath().c_str()
00081                                              << " isBinary?(1/0): "
00082                                              << isBinary;
00083     }
00084 
00085   // Determine the pt assignment method to use
00086   // 1 - Darin's parameterization method
00087   // 2 - Cathy Yeh's chi-square minimization method
00088   // 3 - Hybrid
00089   // 4 - Anna's parameterization method
00090   pt_method = pset.getUntrackedParameter<unsigned>("PtMethod",4);
00091   // what does this mean???
00092   lowQualityFlag = pset.getUntrackedParameter<unsigned>("LowQualityFlag",4);
00093 
00094   if(read_pt_lut && !lut_read_in)
00095     {
00096       pt_lut = new ptdat[1<<21];
00097       readLUT();
00098       lut_read_in = true;
00099     }
00100 
00101   isBeamStartConf = pset.getUntrackedParameter<bool>("isBeamStartConf", true);
00102 }
00103 
00104 ptdat CSCTFPtLUT::Pt(const ptadd& address) const
00105 {
00106   ptdat result;
00107   if(read_pt_lut)
00108   {
00109     int shortAdd = (address.toint()& 0x1fffff);
00110     result = pt_lut[shortAdd];
00111   } else
00112     result = calcPt(address);
00113   return result;
00114 }
00115 
00116 ptdat CSCTFPtLUT::Pt(const unsigned& address) const
00117 {
00118   return Pt(ptadd(address));
00119 }
00120 
00121 ptdat CSCTFPtLUT::Pt(const unsigned& delta_phi_12, const unsigned& delta_phi_23,
00122                      const unsigned& track_eta, const unsigned& track_mode,
00123                      const unsigned& track_fr, const unsigned& delta_phi_sign) const
00124 {
00125   ptadd address;
00126   address.delta_phi_12 = delta_phi_12;
00127   address.delta_phi_23 = delta_phi_23;
00128   address.track_eta = track_eta;
00129   address.track_mode = track_mode;
00130   address.track_fr = track_fr;
00131   address.delta_phi_sign = delta_phi_sign;
00132 
00133   return Pt(address);
00134 }
00135 
00136 ptdat CSCTFPtLUT::Pt(const unsigned& delta_phi_12, const unsigned& track_eta,
00137                      const unsigned& track_mode, const unsigned& track_fr,
00138                      const unsigned& delta_phi_sign) const
00139 {
00140   ptadd address;
00141   address.delta_phi_12 = ((1<<8)-1)&delta_phi_12;
00142   address.delta_phi_23 = ((1<<4)-1)&(delta_phi_12>>8);
00143   address.track_eta = track_eta;
00144   address.track_mode = track_mode;
00145   address.track_fr = track_fr;
00146   address.delta_phi_sign = delta_phi_sign;
00147 
00148   return Pt(address);
00149 }
00150 
00151 
00152 ptdat CSCTFPtLUT::calcPt(const ptadd& address) const
00153 {
00154   ptdat result;
00155 
00156   float etaR = 0, ptR_front = 0, ptR_rear = 0, dphi12R = 0, dphi23R = 0;
00157   int charge12, charge23;
00158   unsigned type, mode, eta, fr, quality, charge, absPhi12, absPhi23;
00159 
00160   eta = address.track_eta;
00161   mode = address.track_mode;
00162   fr = address.track_fr;
00163   charge = address.delta_phi_sign;
00164   quality = trackQuality(eta, mode);
00165   unsigned front_pt, rear_pt;
00166   unsigned front_quality, rear_quality;
00167 
00168   etaR = trigger_scale->getRegionalEtaScale(2)->getLowEdge(2*eta+1);
00169 
00170   front_quality = rear_quality = quality;
00171 
00172   //  kluge to use 2-stn track in overlap region
00173   //  see also where this routine is called, and encode LUTaddress, and assignPT
00174   if (pt_method != 4 && (mode == 2 || mode == 3 || mode == 4) && (eta<3)) mode = 6;
00175   if (pt_method != 4 && (mode == 5)                           && (eta<3)) mode = 8;
00176 
00177   switch(mode)
00178     {
00179     case 2:
00180     case 3:
00181     case 4:
00182     case 5:
00183       type = mode - 1;
00184       charge12 = 1;
00185       absPhi12 = address.delta_phi_12;
00186       absPhi23 = address.delta_phi_23;
00187 
00188       if(charge) charge23 = 1;
00189       else charge23 = -1;
00190 
00191       // now convert to real numbers for input into PT assignment algos.
00192 
00193       if(pt_method == 4) // param method 2010
00194         {
00195           dphi12R = (static_cast<float>(absPhi12<<1)) / (static_cast<float>(1<<12)) * CSCTFConstants::SECTOR_RAD;
00196           dphi23R = (static_cast<float>(absPhi23<<4)) / (static_cast<float>(1<<12)) * CSCTFConstants::SECTOR_RAD;
00197           if(charge12 * charge23 < 0) dphi23R = -dphi23R;
00198 
00199           ptR_front = ptMethods.Pt3Stn2010(mode, etaR, dphi12R, dphi23R, 1);
00200           ptR_rear  = ptMethods.Pt3Stn2010(mode, etaR, dphi12R, dphi23R, 0);
00201 
00202         }
00203       else if(pt_method == 1) // param method
00204         {
00205           dphi12R = (static_cast<float>(absPhi12<<1)) / (static_cast<float>(1<<12)) * CSCTFConstants::SECTOR_RAD;
00206           dphi23R = (static_cast<float>(absPhi23<<4)) / (static_cast<float>(1<<12)) * CSCTFConstants::SECTOR_RAD;
00207           if(charge12 * charge23 < 0) dphi23R = -dphi23R;
00208 
00209           ptR_front = ptMethods.Pt3Stn(type, etaR, dphi12R, dphi23R, 1);
00210           ptR_rear  = ptMethods.Pt3Stn(type, etaR, dphi12R, dphi23R, 0);
00211 
00212         }
00213       else if(pt_method == 2) // cathy's method
00214         {
00215           if(type <= 2)
00216             {
00217               ptR_front = ptMethods.Pt3StnChiSq(type+3, etaR, absPhi12<<1, ((charge == 0) ? -(absPhi23<<4) : (absPhi23<<4)), 1);
00218               ptR_rear  = ptMethods.Pt3StnChiSq(type+3, etaR, absPhi12<<1, ((charge == 0) ? -(absPhi23<<4) : (absPhi23<<4)), 0);
00219             }
00220           else
00221             {
00222               ptR_front = ptMethods.Pt2StnChiSq(type-2, etaR, absPhi12<<1, 1);
00223               ptR_rear  = ptMethods.Pt2StnChiSq(type-2, etaR, absPhi12<<1, 0);
00224             }
00225 
00226         }
00227       else // hybrid
00228         {
00229 
00230           if(type <= 2)
00231             {
00232               ptR_front = ptMethods.Pt3StnHybrid(type+3, etaR, absPhi12<<1, ((charge == 0) ? -(absPhi23<<4) : (absPhi23<<4)), 1);
00233               ptR_rear  = ptMethods.Pt3StnHybrid(type+3, etaR, absPhi12<<1, ((charge == 0) ? -(absPhi23<<4) : (absPhi23<<4)), 0);
00234             }
00235           else
00236             {
00237               ptR_front = ptMethods.Pt2StnHybrid(type-2, etaR, absPhi12<<1, 1);
00238               ptR_rear  = ptMethods.Pt2StnHybrid(type-2, etaR, absPhi12<<1, 0);
00239             }
00240 
00241         }
00242       break;
00243     case 6:
00244     case 7:
00245     case 8:
00246     case 9:
00247     case 10:
00248       type = mode - 5;
00249 
00250       if(charge) absPhi12 = address.delta_phi();
00251       else
00252         {
00253           int temp_phi = address.delta_phi();
00254           absPhi12 = static_cast<unsigned>(-temp_phi) & 0xfff;
00255         }
00256 
00257       if(absPhi12 < (1<<9))
00258         {
00259           if(pt_method == 1 || type == 5)
00260             {
00261               dphi12R = (static_cast<float>(absPhi12)) / (static_cast<float>(1<<12)) * CSCTFConstants::SECTOR_RAD;
00262 
00263               ptR_front = ptMethods.Pt2Stn(type, etaR, dphi12R, 1);
00264               ptR_rear  = ptMethods.Pt2Stn(type, etaR, dphi12R, 0);
00265 
00266             }
00267           else if(pt_method == 2)
00268             {
00269               ptR_front = ptMethods.Pt2StnChiSq(type-1, etaR, absPhi12, 1);
00270               ptR_rear  = ptMethods.Pt2StnChiSq(type-1, etaR, absPhi12, 0);
00271             }
00272           else
00273             {
00274               ptR_front = ptMethods.Pt2StnHybrid(type-1, etaR, absPhi12, 1);
00275               ptR_rear  = ptMethods.Pt2StnHybrid(type-1, etaR, absPhi12, 0);
00276             }
00277         }
00278       else
00279         {
00280           ptR_front = trigger_ptscale->getPtScale()->getLowEdge(1);
00281           ptR_rear  = trigger_ptscale->getPtScale()->getLowEdge(1);
00282         }
00283       if(pt_method == 4) // param method 2010
00284         {
00285               dphi12R = (static_cast<float>(absPhi12)) / (static_cast<float>(1<<12)) * CSCTFConstants::SECTOR_RAD;
00286 
00287               //std::cout<< " Sector_rad = " << (CSCTFConstants::SECTOR_RAD) << std::endl;
00288               ptR_front = ptMethods.Pt2Stn2010(mode, etaR, dphi12R, 1);
00289               ptR_rear  = ptMethods.Pt2Stn2010(mode, etaR, dphi12R, 0);
00290         }
00291 
00292       break;
00293     case 12:  // 1-2-b1 calculated only delta_phi12 = 2-b1
00294     case 14:
00295       type = 2;
00296 
00297       if(charge) absPhi12 = address.delta_phi();
00298       else
00299         {
00300           int temp_phi = address.delta_phi();
00301           absPhi12 = static_cast<unsigned>(-temp_phi) & 0xfff;
00302         }
00303       if(absPhi12 < (1<<9))
00304         {
00305           dphi12R = (static_cast<float>(absPhi12)) / (static_cast<float>(1<<12)) * CSCTFConstants::SECTOR_RAD;
00306           ptR_front = ptMethods.Pt2Stn(type, etaR, dphi12R, 1);
00307           ptR_rear  = ptMethods.Pt2Stn(type, etaR, dphi12R, 0);
00308         }
00309       else
00310         {
00311           ptR_front = trigger_ptscale->getPtScale()->getLowEdge(1);
00312           ptR_rear  = trigger_ptscale->getPtScale()->getLowEdge(1);
00313         }
00314       if(pt_method == 4) // param method 2010 
00315         {
00316               dphi12R = (static_cast<float>(absPhi12)) / (static_cast<float>(1<<12)) * CSCTFConstants::SECTOR_RAD;
00317 
00318               ptR_front = ptMethods.Pt2Stn2010(mode, etaR, dphi12R, 1);
00319               ptR_rear  = ptMethods.Pt2Stn2010(mode, etaR, dphi12R, 0);
00320 
00321               if(fabs(dphi12R)<0.01 && (ptR_rear < 10 || ptR_front < 10))
00322                 std::cout << "dphi12R = " << dphi12R << " ptR_rear = " << ptR_rear
00323                 << " ptR_front = " << ptR_front << " etaR = " << etaR << " mode = " << mode << std::endl;
00324         }
00325       break;
00326     case 13:
00327       type = 4;
00328 
00329       if(charge) absPhi12 = address.delta_phi();
00330       else
00331         {
00332           int temp_phi = address.delta_phi();
00333           absPhi12 = static_cast<unsigned>(-temp_phi) & 0xfff;
00334         }
00335       if(absPhi12 < (1<<9))
00336         {
00337           dphi12R = (static_cast<float>(absPhi12)) / (static_cast<float>(1<<12)) * CSCTFConstants::SECTOR_RAD;
00338           ptR_front = ptMethods.Pt2Stn(type, etaR, dphi12R, 1);
00339           ptR_rear  = ptMethods.Pt2Stn(type, etaR, dphi12R, 0);
00340         }
00341       else
00342         {
00343           ptR_front = trigger_ptscale->getPtScale()->getLowEdge(1);
00344           ptR_rear  = trigger_ptscale->getPtScale()->getLowEdge(1);
00345         }
00346 
00347       if(pt_method == 4) // param method 2010
00348         {
00349               dphi12R = (static_cast<float>(absPhi12)) / (static_cast<float>(1<<12)) * CSCTFConstants::SECTOR_RAD;
00350 
00351               ptR_front = ptMethods.Pt2Stn2010(mode, etaR, dphi12R, 1);
00352               ptR_rear  = ptMethods.Pt2Stn2010(mode, etaR, dphi12R, 0);
00353         }
00354 
00355       break;
00356     case 11:
00357       // singles trigger
00358       ptR_front = trigger_ptscale->getPtScale()->getLowEdge(5);
00359       ptR_rear  = trigger_ptscale->getPtScale()->getLowEdge(5);
00360       //ptR_front = trigger_ptscale->getPtScale()->getLowEdge(31);
00361       //ptR_rear  = trigger_ptscale->getPtScale()->getLowEdge(31);
00362       break;
00363     case 15:
00364       // halo trigger
00365       ptR_front = trigger_ptscale->getPtScale()->getLowEdge(5);
00366       ptR_rear  = trigger_ptscale->getPtScale()->getLowEdge(5);
00367       break;
00368     case 1:
00369       // tracks that fail delta phi cuts
00370       ptR_front = trigger_ptscale->getPtScale()->getLowEdge(5);
00371       ptR_rear  = trigger_ptscale->getPtScale()->getLowEdge(5); 
00372      break;
00373     default: // Tracks in this category are not considered muons.
00374       ptR_front = trigger_ptscale->getPtScale()->getLowEdge(0);
00375       ptR_rear  = trigger_ptscale->getPtScale()->getLowEdge(0);
00376     };
00377 
00378   front_pt = trigger_ptscale->getPtScale()->getPacked(ptR_front);
00379   rear_pt  = trigger_ptscale->getPtScale()->getPacked(ptR_rear);
00380 
00381   // kluge to set arbitrary Pt for some tracks with lousy resolution (and no param)
00382   if(pt_method != 4) 
00383     {
00384       if ((front_pt==0 || front_pt==1) && (eta<3) && quality==1 && pt_method != 2) front_pt = 31;
00385       if ((rear_pt==0  || rear_pt==1) && (eta<3) && quality==1 && pt_method != 2) rear_pt = 31;
00386     }
00387   if(pt_method != 2 && pt_method != 4 && quality == 1)
00388     {
00389       if (front_pt < 5) front_pt = 5;
00390       if (rear_pt  < 5) rear_pt  = 5;
00391     }
00392 
00393   // in order to match the pt assignement of the previous routine
00394   if(isBeamStartConf && pt_method != 2 && pt_method != 4) {
00395     if(quality == 3 && mode == 5) {
00396       
00397       if (front_pt < 5) front_pt = 5;
00398       if (rear_pt  < 5) rear_pt  = 5;
00399     }
00400 
00401     if(quality == 2 && mode > 7 && mode < 11) {
00402       
00403       if (front_pt < 5) front_pt = 5;
00404       if (rear_pt  < 5) rear_pt  = 5;
00405     }
00406   }
00407 
00408  
00409   result.front_rank = front_pt | front_quality << 5;
00410   result.rear_rank  = rear_pt  | rear_quality << 5;
00411 
00412   result.charge_valid_front = 1; //ptMethods.chargeValid(front_pt, quality, eta, pt_method);
00413   result.charge_valid_rear  = 1; //ptMethods.chargeValid(rear_pt, quality, eta, pt_method);
00414 
00415 
00416   /*  if (mode == 1) { 
00417     std::cout << "F_pt: "      << front_pt      << std::endl;
00418     std::cout << "R_pt: "      << rear_pt       << std::endl;
00419     std::cout << "F_quality: " << front_quality << std::endl;
00420     std::cout << "R_quality: " << rear_quality  << std::endl;
00421     std::cout << "F_rank: " << std::hex << result.front_rank << std::endl;
00422     std::cout << "R_rank: " << std::hex << result.rear_rank  << std::endl;
00423   }
00424   */
00425   return result;
00426 }
00427 
00428 
00429 unsigned CSCTFPtLUT::trackQuality(const unsigned& eta, const unsigned& mode) const
00430 {
00431  // eta and mode should be only 4-bits, since that is the input to the large LUT
00432     if (eta>15 || mode>15)
00433       {
00434         //std::cout << "Error: Eta or Mode out of range in AU quality assignment" << std::endl;
00435         edm::LogError("CSCTFPtLUT::trackQuality()")<<"Eta or Mode out of range in AU quality assignment";
00436         return 0;
00437       }
00438     unsigned int quality;
00439     switch (mode) {
00440     case 2:
00441       quality = 3;
00442       break;
00443     case 3:
00444       quality = 3;
00445       break;
00446     case 4:
00448       //        quality = 2;
00449       quality = 3;
00450       break;
00451     case 5:
00452       quality = 1;
00453       if (isBeamStartConf && eta >= 12) // eta > 2.1
00454         quality = 3;
00455       break;
00456     case 6:
00457       if (eta>=3)
00458         quality = 2;
00459       else
00460         quality = 1;
00461       break;
00462     case 7:
00463       quality = 2;
00464       break;
00465     case 8:
00466       quality = 1;
00467       if (isBeamStartConf && eta >= 12) // eta > 2.1
00468         quality = 2;
00469       break;
00470     case 9:
00471       quality = 1;
00472       if (isBeamStartConf && eta >= 12) // eta > 2.1
00473         quality = 2;
00474       break;
00475     case 10:
00476       quality = 1;
00477       if (isBeamStartConf && eta >= 12) // eta > 2.1
00478         quality = 2;
00479       break;
00480     case 11:
00481       // single LCTs
00482       quality = 1;
00483       break;
00484     case 12:
00485       quality = 3;
00486       break;
00487     case 13:
00488       quality = 2;
00489       break;
00490     case 14:
00491       quality = 2;
00492       break;
00493     case 15:
00494       // halo triggers
00495       quality = 1;
00496       break;
00497       //DEA: keep muons that fail delta phi cut
00498     case 1:
00499       quality = 1;
00500       break;
00501     default:
00502       quality = 0;
00503       break;
00504     }
00505 
00506     // allow quality = 1 only in overlap region or eta = 1.6 region
00507     //    if ((quality == 1) && (eta >= 4) && (eta != 6) && (eta != 7)) quality = 0;
00508     //    if ( (quality == 1) && (eta >= 4) ) quality = 0;
00509 
00510     if ( (quality == 1) && (eta >= 4) && (eta < 11)
00511          && ((lowQualityFlag&4)==0) ) quality = 0;
00512     if ( (quality == 1) && (eta < 4) && ((lowQualityFlag&1)==0)
00513          && ((lowQualityFlag&4)==0) ) quality = 0;
00514     if ( (quality == 1) && (eta >=11) && ((lowQualityFlag&2)==0)
00515          && ((lowQualityFlag&4)==0) ) quality = 0;
00516 
00517     return quality;
00518 
00519 }
00520 
00521 void CSCTFPtLUT::readLUT()
00522 {
00523   std::ifstream PtLUT;
00524 
00525   if(isBinary)
00526     {
00527       PtLUT.open(pt_lut_file.fullPath().c_str(), std::ios::binary);
00528       PtLUT.seekg(0, std::ios::end);
00529       int length = PtLUT.tellg();;
00530       if( length == (1<<CSCBitWidths::kPtAddressWidth)*sizeof(short) )
00531         {
00532           PtLUT.seekg(0, std::ios::beg);
00533           PtLUT.read(reinterpret_cast<char*>(pt_lut),length);
00534         }
00535       else
00536         {
00537           edm::LogError("CSCPtLUT") << "File " << pt_lut_file.fullPath() << " is incorrect size!\n";
00538         }
00539       PtLUT.close();
00540     }
00541   else
00542     {
00543       PtLUT.open(pt_lut_file.fullPath().c_str());
00544       unsigned i = 0;
00545       unsigned short temp = 0;
00546       while(!PtLUT.eof() && i < 1 << CSCBitWidths::kPtAddressWidth)
00547         {
00548           PtLUT >> temp;
00549           pt_lut[i++] = (*reinterpret_cast<ptdat*>(&temp));
00550         }
00551       PtLUT.close();
00552     }
00553 }
00554 
00555