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
00009
00010
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
00063
00064
00065
00066 pt_method = pset.getUntrackedParameter<unsigned>("PtMethod",1);
00067
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
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
00147
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
00166
00167 if(pt_method == 1)
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)
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
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:
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
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 ){
00316 result.front_rank = 1;
00317 result.rear_rank = 1;
00318 } else {
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;
00323 result.charge_valid_rear = 1;
00324
00325 return result;
00326 }
00327
00328 #undef MODE_ACC
00329
00330 unsigned CSCTFPtLUT::trackQuality(const unsigned& eta, const unsigned& mode) const
00331 {
00332
00333 if (eta>15 || mode>15)
00334 {
00335
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
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
00389 case 1:
00390 quality = 1;
00391 default:
00392 quality = 0;
00393 break;
00394 }
00395
00396
00397
00398
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