CMS 3D CMS Logo

CSCTFPtLUT.cc

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

Generated on Tue Jun 9 17:39:42 2009 for CMSSW by  doxygen 1.5.4