CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/L1Trigger/RegionalCaloTrigger/src/L1RCT.cc

Go to the documentation of this file.
00001 #include "L1Trigger/RegionalCaloTrigger/interface/L1RCT.h"
00002 
00003 #include <vector>
00004 using std::vector;
00005 
00006 #include <fstream>
00007 #include <string>
00008 
00009 #include <iostream>
00010 using std::ostream;
00011 using std::cout;
00012 using std::cerr;
00013 using std::endl;
00014 
00015 #include <iomanip>
00016 
00017 //#include "DataFormats/L1CaloTrigger/interface/L1CaloEmCand.h"
00018 
00019 #include "L1Trigger/RegionalCaloTrigger/interface/L1RCTLookupTables.h"
00020 #include "CondFormats/L1TObjects/interface/L1RCTParameters.h"
00021 #include "CondFormats/L1TObjects/interface/L1CaloEtScale.h"
00022 
00023 //Main method to process a single event, hence the name.
00024 //First it sets up all the neighbors, sharing the pointers to the proper
00025 //regions.  This is done via the neighborMap auxiliary class, which
00026 //is very dry and contains the proper mappings from crate,card,and
00027 //region numbers to the crate,card, and region numbers of the neighbors.
00028 //The next step is to pass along the pointers for the regions
00029 //to their corresponding Electron Isolation Card
00030 //This is done in the crate method fillElectronIsolationCards
00031 //Then the actual processing of the data begins with the
00032 //processReceiverCards and processElectronIsolationCards methods.
00033 //Next the region sums, tau bits, mip bits, and electron
00034 //candidates are passed onto the Jet Summary Card, and that's where
00035 //the data flow ends for the Regional CaloTrigger.
00036 void L1RCT::processEvent(){
00037   for(int i=0; i<18;i++)
00038     crates.at(i).processReceiverCards();
00039   shareNeighbors();  
00040   for(int i=0; i<18;i++){
00041     crates.at(i).fillElectronIsolationCards();
00042     crates.at(i).processElectronIsolationCards();
00043     crates.at(i).fillJetSummaryCard();
00044     crates.at(i).processJetSummaryCard();
00045   }
00046 }
00047 
00048 void L1RCT::makeCrates()
00049 {
00050   for(int i = 0; i<18; i++){
00051     L1RCTCrate c(i, rctLookupTables_);
00052     crates.push_back(c);
00053   }
00054 }
00055 
00056 L1RCT::L1RCT(const L1RCTLookupTables* rctLookupTables) : 
00057   rctLookupTables_(rctLookupTables),
00058   empty(),
00059   neighborMap(),
00060   barrel(18,std::vector<std::vector<unsigned short> >(7,std::vector<unsigned short>(64))),
00061   hf(18,std::vector<unsigned short>(8))
00062 {
00063   makeCrates();
00064 }
00065 
00066 void L1RCT::input()
00067 {
00068   for(int i = 0; i<18; i++){
00069     crates.at(i).input(barrel.at(i),hf.at(i));
00070   }
00071 }
00072 
00073 void L1RCT::input(std::vector<std::vector<std::vector<unsigned short> > > barrelIn,
00074                   std::vector<std::vector<unsigned short> > hfIn)
00075 {
00076   for(int i = 0; i<18; i++){
00077     crates.at(i).input(barrelIn.at(i),hfIn.at(i));
00078   }
00079 }
00080 
00081 //This is a method for taking input from a file.  Any entries in excess
00082 //of 18*7*64 will simply be ignored.  This *only* fills input for a single
00083 //event.  At the moment you cannot put a ton of data and have it be
00084 //read as separate events.
00085 void L1RCT::fileInput(const char* filename){            // added "const" also in .h
00086   unsigned short x;
00087   std::ifstream instream(filename);
00088   if(instream){
00089     for(int i = 0; i<18;i++){
00090       for(int j = 0; j<7; j++){
00091         for(int k = 0; k<64; k++){
00092           if(instream >> x){
00093             unsigned short bit = x/256;             // added J.Leonard Aug. 16 06
00094             unsigned short energy = x&255;          //
00095             unsigned short input = energy*2 + bit;  //
00096             barrel.at(i).at(j).at(k) = input;
00097           }
00098           else
00099             break;
00100         }
00101       }
00102       for(int j = 0; j<8; j++){
00103         if(instream >> x){
00104           hf.at(i).at(j) = x;
00105         }
00106         else
00107           break;
00108       }
00109     }
00110   }
00111   input();
00112 }
00113 
00114 
00115 // takes hcal and ecal digi input, including HF
00116 void L1RCT::digiInput(const EcalTrigPrimDigiCollection& ecalCollection,
00117                       const HcalTrigPrimDigiCollection& hcalCollection)
00118 {
00119   // fills input vectors with 0's in case ecal or hcal collection not used
00120   for (int i = 0; i < 18; i++)
00121     {
00122       for (int j = 0; j < 7; j++)
00123         {
00124           for (int k = 0; k < 64; k++)
00125             {
00126               barrel.at(i).at(j).at(k) = 0;
00127             }
00128         }
00129       for (int j = 0; j < 8; j++)
00130         {
00131           hf.at(i).at(j) = 0;
00132         }
00133     }
00134 
00135   int nEcalDigi = ecalCollection.size();
00136   if (nEcalDigi>4032) {nEcalDigi=4032;}
00137   for (int i = 0; i < nEcalDigi; i++){
00138     short ieta = (short) ecalCollection[i].id().ieta(); 
00139     // Note absIeta counts from 1-28 (not 0-27)
00140     unsigned short absIeta = (unsigned short) abs(ieta);
00141     unsigned short cal_iphi = (unsigned short) ecalCollection[i].id().iphi(); 
00142     unsigned short iphi = (72 + 18 - cal_iphi) % 72; // transform TOWERS (not regions) into local rct (intuitive) phi bins
00143 
00144     //map digis to crates, cards, and towers
00145     unsigned short crate = 999, card = 999, tower = 999;
00146     crate = rctLookupTables_->rctParameters()->calcCrate(iphi, ieta);
00147     card = rctLookupTables_->rctParameters()->calcCard(iphi, absIeta);
00148     tower = rctLookupTables_->rctParameters()->calcTower(iphi, absIeta);
00149 
00150     unsigned short energy = ecalCollection[i].compressedEt();
00151     unsigned short fineGrain = (unsigned short) ecalCollection[i].fineGrain();  // 0 or 1
00152     unsigned short ecalInput = energy*2 + fineGrain;
00153 
00154     // put input into correct crate/card/tower of barrel
00155     if ((crate<18) && (card<7) && (tower<32)) {             // changed 64 to 32 Sept. 19 J. Leonard, rm -1 7Nov07
00156       barrel.at(crate).at(card).at(tower) = ecalInput;        // rm -1
00157     }
00158     else { std::cerr << "L1RCT: ecal out of range! tower = " << tower << " iphi is " << iphi << " absieta is " << absIeta << std::endl; }
00159   }
00160 
00161 //same for hcal, once we get the hcal digis, just need to add 32 to towers:
00162 // just copied and pasted and changed names where necessary
00163   int nHcalDigi = hcalCollection.size();
00164   //if (nHcalDigi != 4176){ std::cout << "L1RCT: Warning: There are " << nHcalDigi << "hcal digis instead of 4176!" << std::endl;}
00165   // incl HF 4032 + 144 = 4176
00166   for (int i = 0; i < nHcalDigi; i++){
00167     short ieta = (short) hcalCollection[i].id().ieta(); 
00168     unsigned short absIeta = (unsigned short) abs(ieta);
00169     unsigned short cal_iphi = (unsigned short) hcalCollection[i].id().iphi();
00170     // All Hcal primitives (including HF) are reported
00171     // with phi bin numbering in the range 0-72.
00172     unsigned short iphi = (72 + 18 - cal_iphi) % 72;
00173     // transform Hcal TOWERS (1-72)into local rct (intuitive) phi bins (72 bins) 0-71
00174     // Use local iphi to work out the region and crate (for HB/HE and HF)
00175     // HF regions need to have local iphi 0-17
00176     if (absIeta >= 29) {
00177       iphi = iphi/4;
00178     }
00179 
00180     //map digis to crates, cards, and towers
00181     unsigned short crate = 999, card = 999, tower = 999;
00182     crate = rctLookupTables_->rctParameters()->calcCrate(iphi, ieta);
00183     if (absIeta < 29){
00184       card = rctLookupTables_->rctParameters()->calcCard(iphi, absIeta);
00185     }
00186     tower = rctLookupTables_->rctParameters()->calcTower(iphi, absIeta);
00187 
00188 
00189     unsigned short energy = hcalCollection[i].SOI_compressedEt();     // access only sample of interest
00190     unsigned short fineGrain = (unsigned short) hcalCollection[i].SOI_fineGrain();
00191     unsigned short hcalInput = energy*2 + fineGrain;
00192     if (absIeta <= 28){
00193       // put input into correct crate/card/tower of barrel
00194       if ((crate<18) && (card<7) && (tower<32)) {               // changed 64 to 32 Sept. 19 J. Leonard, rm -1 7Nov07
00195         barrel.at(crate).at(card).at(tower + 32) = hcalInput;  // hcal towers are ecal + 32 see RC.cc; rm -1 7Nov07
00196       }
00197       else { std::cout << "L1RCT: hcal out of range!  tower = " << tower << std::endl; }
00198     }
00199     else if ((absIeta >= 29) && (absIeta <= 32)){
00200       // put input into correct crate/region of HF
00201       if ((crate<18) && (tower<8)) {
00202         hf.at(crate).at(tower) = hcalInput;
00203       }
00204       else { std::cout << "L1RCT: hf out of range!  region = " << tower << std::endl; }
00205     }
00206 
00207   }
00208   
00209   input();
00210 
00211   return;
00212 
00213 }
00214 
00215 //As the name implies, it will randomly generate input for the 
00216 //regional calotrigger.
00217 void L1RCT::randomInput()
00218 {
00219   for(int i = 0; i<18;i++){
00220     for(int j = 0; j<7;j++){
00221       for(int k = 0; k<64; k++){
00222         barrel.at(i).at(j).at(k) = rand()%511;
00223       }
00224     }
00225     for(int j = 0; j<8;j++){
00226       hf.at(i).at(j) = rand()%255;  // changed from 1023 (10 bits)
00227     }
00228   }
00229   input();
00230   return;
00231 }
00232 
00233 
00234 //This method handles the bulk of the pointer passing, giving
00235 //to each region pointers to its neighbors.  If it does *not*
00236 //have a neighbor in that direction then it passes it a pointer
00237 //to an empty region that contains no data and is disconnected
00238 //from anything else.  This makes the electron finding algorithm simpler
00239 //as then all regions can be treated equally.
00240 void L1RCT::shareNeighbors(){
00241   L1RCTRegion *north;
00242   L1RCTRegion *south;
00243   L1RCTRegion *west;
00244   L1RCTRegion *east;
00245   L1RCTRegion *se;
00246   L1RCTRegion *sw;
00247   L1RCTRegion *nw;
00248   L1RCTRegion *ne;
00249   L1RCTRegion *primary;
00250 
00251 
00252   for(int i = 0; i < 18; i++){
00253     for(int j = 0; j < 7; j++){
00254       for(int k = 0; k < 2; k++){
00255 
00256         primary = crates.at(i).getReceiverCard(j)->getRegion(k);
00257 
00258         vector<int> northIndices = neighborMap.north(i,j,k);
00259         if(northIndices.at(0) != -1)
00260           north = crates.at(northIndices.at(0)).getReceiverCard(northIndices.at(1))->getRegion(northIndices.at(2));
00261         else north = &empty;
00262 
00263         vector<int> southIndices = neighborMap.south(i,j,k);
00264         if(southIndices.at(0) != -1)
00265           south = crates.at(southIndices.at(0)).getReceiverCard(southIndices.at(1))->getRegion(southIndices.at(2));
00266         else south = &empty;
00267 
00268         vector<int> westIndices = neighborMap.west(i,j,k);
00269         if(westIndices.at(0) != -1)
00270           west = crates.at(westIndices.at(0)).getReceiverCard(westIndices.at(1))->getRegion(westIndices.at(2));
00271         else west = &empty;
00272 
00273         vector<int> eastIndices = neighborMap.east(i,j,k);
00274         if(eastIndices.at(0) != -1)
00275           east = crates.at(eastIndices.at(0)).getReceiverCard(eastIndices.at(1))->getRegion(eastIndices.at(2));
00276         else east = &empty;
00277 
00278         vector<int> seIndices = neighborMap.se(i,j,k);
00279         if(seIndices.at(0) != -1)
00280           se = crates.at(seIndices.at(0)).getReceiverCard(seIndices.at(1))->getRegion(seIndices.at(2));
00281         else se = &empty;
00282 
00283         vector<int> swIndices = neighborMap.sw(i,j,k);
00284         if(swIndices.at(0) != -1)
00285           sw= crates.at(swIndices.at(0)).getReceiverCard(swIndices.at(1))->getRegion(swIndices.at(2));
00286         else sw = &empty;
00287 
00288         vector<int> neIndices = neighborMap.ne(i,j,k);
00289         if(neIndices.at(0) != -1)
00290           ne= crates.at(neIndices.at(0)).getReceiverCard(neIndices.at(1))->getRegion(neIndices.at(2));
00291         else ne = &empty;
00292 
00293         vector<int> nwIndices = neighborMap.nw(i,j,k);
00294         if(nwIndices.at(0) != -1)
00295           nw= crates.at(nwIndices.at(0)).getReceiverCard(nwIndices.at(1))->getRegion(nwIndices.at(2));
00296         else nw = &empty;
00297 
00298         primary->setNorthEt(north->giveNorthEt());
00299         primary->setNorthHE_FG(north->giveNorthHE_FG());
00300         primary->setSouthEt(south->giveSouthEt());
00301         primary->setSouthHE_FG(south->giveSouthHE_FG());
00302         primary->setEastEt(east->giveEastEt());
00303         primary->setEastHE_FG(east->giveEastHE_FG());
00304         primary->setWestEt(west->giveWestEt());
00305         primary->setWestHE_FG(west->giveWestHE_FG());
00306         primary->setSEEt(se->giveSEEt());
00307         primary->setSEHE_FG(se->giveSEHE_FG());
00308         primary->setSWEt(sw->giveSWEt());
00309         primary->setSWHE_FG(sw->giveSWHE_FG());
00310         primary->setNWEt(nw->giveNWEt());
00311         primary->setNWHE_FG(nw->giveNWHE_FG());
00312         primary->setNEEt(ne->giveNEEt());
00313         primary->setNEHE_FG(ne->giveNEHE_FG());
00314 
00315 
00316 
00317       }
00318     }
00319   }
00320 
00321 }
00322 
00323 void L1RCT::print(){
00324   for(int i = 0; i<18; i++){
00325     std::cout << "Crate " << i << std::endl;
00326     crates.at(i).print();
00327   } 
00328 }
00329 
00330 // Returns the top four isolated electrons from given crate
00331 // in a vector of L1CaloEmCands
00332 L1CaloEmCollection L1RCT::getIsolatedEGObjects(unsigned crate){
00333   std::vector<unsigned short> isoEmObjects = crates.at(crate).getIsolatedEGObjects();
00334   L1CaloEmCollection isoEmCands;
00335   for (uint16_t i = 0; i < 4; i++){
00336     unsigned rgn = ((isoEmObjects.at(i)) & 1);
00337     unsigned crd = (((isoEmObjects.at(i))/2) & 7);
00338     unsigned energy = ((isoEmObjects.at(i))/16);
00339     unsigned rank = rctLookupTables_->emRank(energy);
00340     L1CaloEmCand isoCand(rank, rgn, crd, crate, 1, i, 0);  // includes emcand index
00341     isoEmCands.push_back(isoCand);
00342   }
00343   return isoEmCands;
00344 }
00345 
00346 
00347 // Returns the top four nonisolated electrons from the given crate
00348 // in a vector of L1CaloEmCands
00349 L1CaloEmCollection L1RCT::getNonisolatedEGObjects(unsigned crate){
00350   std::vector<unsigned short> nonIsoEmObjects = crates.at(crate).getNonisolatedEGObjects();
00351   L1CaloEmCollection nonIsoEmCands;
00352   for (uint16_t i = 0; i < 4; i++){
00353     unsigned rgn = ((nonIsoEmObjects.at(i)) & 1);
00354     unsigned crd = (((nonIsoEmObjects.at(i))/2) & 7);
00355     unsigned energy = ((nonIsoEmObjects.at(i))/16);
00356     unsigned rank = rctLookupTables_->emRank(energy);
00357     L1CaloEmCand nonIsoCand(rank, rgn, crd, crate, 0, i, 0);  // includes emcand index
00358     nonIsoEmCands.push_back(nonIsoCand);
00359   }
00360   return nonIsoEmCands;
00361 }
00362 
00363 vector<L1CaloRegion> L1RCT::getRegions(unsigned crate){
00364   // barrel regions
00365   std::bitset<14> taus( (long) crates.at(crate).getTauBits());
00366   std::bitset<14> mips( (long) crates.at(crate).getMIPBits());
00367   std::bitset<14> quiets( (long) crates.at(crate).getQuietBits());
00368   std::bitset<14> overflows( (long) crates.at(crate).getOverFlowBits());
00369   std::vector<unsigned short> barrelEnergies = crates.at(crate).getBarrelRegions();
00370   std::vector<L1CaloRegion> regionCollection;
00371   for (unsigned card = 0; card < 7; card++){
00372     for (unsigned rgn = 0; rgn < 2; rgn++){
00373       bool tau = taus[card*2+rgn];
00374       bool mip = mips[card*2+rgn];
00375       bool quiet = quiets[card*2+rgn];
00376       bool overflow = overflows[card*2+rgn];
00377       unsigned barrelEnergy = barrelEnergies.at(card*2+rgn);
00378       L1CaloRegion region(barrelEnergy, overflow, tau, mip, quiet, crate, card, rgn);
00379       regionCollection.push_back(region);
00380     }
00381   }
00382 
00383   // hf regions
00384   std::vector<unsigned short> hfEnergies = crates.at(crate).getHFRegions();
00385   // fine grain bits -- still have to work out digi input
00386   std::vector<unsigned short> hfFineGrainBits = crates.at(crate).getHFFineGrainBits();
00387   for (unsigned hfRgn = 0; hfRgn<8; hfRgn++){  // region number, see diagram on paper.  make sure know how hf regions come in. 
00388     unsigned energy = hfEnergies.at(hfRgn);
00389     bool fineGrain = hfFineGrainBits.at(hfRgn);
00390     L1CaloRegion hfRegion(energy, fineGrain, crate, hfRgn);
00391     regionCollection.push_back(hfRegion);
00392   }
00393   return regionCollection;
00394 }