CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/L1TriggerOffline/L1Analyzer/src/BSCTrigger.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    BSCTrigger
00004 // Class:      BSCTrigger
00005 // 
00013 //
00014 // Original Author:  Muriel VANDER DONCKT *:0
00015 //         Created:  Wed Jul 16 16:11:05 CEST 2008
00016 // $Id: BSCTrigger.cc,v 1.10 2010/10/07 22:02:55 yjlee Exp $
00017 //
00018 //
00019 
00020 
00021 // system include files
00022 #include <memory>
00023 
00024 // user include files
00025 #include "FWCore/Framework/interface/Frameworkfwd.h"
00026 #include "FWCore/Framework/interface/EDProducer.h"
00027 
00028 #include "FWCore/Framework/interface/Event.h"
00029 #include "FWCore/Framework/interface/MakerMacros.h"
00030 
00031 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00032 #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h"
00033 #include "DataFormats/L1GlobalTrigger/interface/L1GtTechnicalTrigger.h"
00034 #include "DataFormats/L1GlobalTrigger/interface/L1GtTechnicalTriggerRecord.h"
00035 #include "FWCore/Utilities/interface/InputTag.h"
00036 
00037 #include "SimDataFormats/CrossingFrame/interface/CrossingFrame.h"
00038 #include "SimDataFormats/CrossingFrame/interface/MixCollection.h"
00039 
00040 
00041 //
00042 // class declaration
00043 //
00044 
00045 class BSCTrigger : public edm::EDProducer {
00046 public:
00047   explicit BSCTrigger(const edm::ParameterSet&);
00048   ~BSCTrigger();
00049 
00050 private:
00051   virtual void beginJob() ;
00052   virtual void produce(edm::Event&, const edm::EventSetup&);
00053   virtual void endJob() ;
00054   int   getBSCNum(int id, float z);
00055   bool  isInner(int id);
00056   bool  isZplus(int id);
00057     // ----------member data ---------------------------
00058   std::vector<unsigned> ttBits_;
00059   std::vector<std::string> names_;
00060   unsigned nEvt_;
00061   float theCoincidence_;
00062   float theResolution_;
00063   int theNinner_;
00064   int theNouter_;      
00065   int nevt_;
00066   edm::InputTag TheHits_tag_;
00067 };
00068 
00069 //
00070 // constants, enums and typedefs
00071 //
00072 
00073 
00074 //
00075 // static data member definitions
00076 //
00077 
00078 //
00079 // constructors and destructor
00080 //
00081 BSCTrigger::BSCTrigger(const edm::ParameterSet& iConfig)
00082 {
00083   ttBits_=iConfig.getParameter< std::vector<unsigned> >("bitNumbers");
00084   names_= iConfig.getParameter< std::vector<std::string> >("bitNames");
00085   theCoincidence_= iConfig.getParameter<double>("coincidence");
00086   theResolution_= iConfig.getParameter<double>("resolution");
00087   TheHits_tag_= iConfig.getParameter<edm::InputTag>("theHits");
00088   produces<L1GtTechnicalTriggerRecord>();  
00089   nevt_=0;
00090 }
00091 
00092 
00093 BSCTrigger::~BSCTrigger()
00094 {
00095  
00096   // do anything here that needs to be done at desctruction time
00097   // (e.g. close files, deallocate resources etc.)
00098 
00099 }
00100 
00101 
00102 //
00103 // member functions
00104 //
00105 
00106 // ------------ method called to produce the data  ------------
00107 void BSCTrigger::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00108 {
00109   std::vector<L1GtTechnicalTrigger> ttVec(ttBits_.size());
00110   std::vector<float>EnergyBX(32);
00111   std::vector<float>EnergyBXMinusDt(32);
00112   int ZMinnerBX=0, ZMouterBX=0;
00113   int ZPinnerBX=0, ZPouterBX=0;
00114   int ZMinnerBXMinusDt=0, ZMouterBXMinusDt=0;
00115   int ZPinnerBXMinusDt=0, ZPouterBXMinusDt=0;
00116   ++nevt_;
00117   std::auto_ptr<L1GtTechnicalTriggerRecord> BscRecord;
00118   float MipFraction=0.5;
00119   float MipEnergy=0.0027;
00120   float theThreshold=MipFraction*MipEnergy;
00121 
00122   edm::Handle<CrossingFrame<PSimHit> > cf;
00123   iEvent.getByLabel(TheHits_tag_, cf);
00124    
00125   if (!cf.failedToGet()) {
00126     for ( int c=0;c<32;++c){
00127       EnergyBX[c]=0;
00128       EnergyBXMinusDt[c]=0;
00129     }
00130     std::auto_ptr<MixCollection<PSimHit> > theBSCHitContainer( new MixCollection <PSimHit>(cf.product()));
00131     MixCollection<PSimHit>::MixItr itHit;
00132     float dt1,dt2;
00133     dt1=theCoincidence_/2 + theResolution_;
00134     dt2=theCoincidence_/2 - theResolution_;
00135     if ( edm::isDebugEnabled() ) LogDebug("BSCTrig")<<" ----------------new event ---with "<<theBSCHitContainer->size()<<" hits in the BSC";
00136     
00137     // collect total deposited energy in BSC segments -> EnergyBX[segment id], in GeV units ---------------------------------------------------------------
00138     for (itHit = theBSCHitContainer->begin(); itHit != theBSCHitContainer->end(); ++itHit) {
00139       float zh=itHit->entryPoint().z()/10;    
00140       int id=getBSCNum(itHit->detUnitId(),zh);
00141       if ( id > 31 ) continue;   // the small 2 paddles further from the IP
00142       float t=itHit->timeOfFlight();
00143 
00144       if ( edm::isDebugEnabled() ) {
00145         float rh=sqrt(itHit->entryPoint().x()*itHit->entryPoint().x()+itHit->entryPoint().y()*itHit->entryPoint().y())/10;    
00146         LogTrace("BSCTrig")<<" BSC Num "<<id<<" z="<<zh<<" isZplus="<<isZplus(id)<<" Hit DetId="<<getBSCNum(id,zh)<<" r="<<rh<<" isInner="<<isInner(id);
00147         LogTrace("BSCTrig")<<" Hit time="<<t<<" accepted range=["<<dt2<<","<<dt1<<"] from a "<<abs(itHit->particleType())<<" with energy " <<itHit->energyLoss();
00148       }
00149       if (fabs(t)> dt1 || fabs(t) <dt2 ) continue;
00150       if (t>0) EnergyBX[id]+=itHit->energyLoss();
00151       else EnergyBXMinusDt[id]+=itHit->energyLoss();    
00152     }
00153 
00154     // count number of segments hit in inner/outer and +z, -z ---------------------------------------------------------------------------------------------
00155     for ( unsigned int ipad = 0 ; ipad<32; ipad++) {
00156       if ( edm::isDebugEnabled() ) LogTrace("BSCTrig")<<" EnergyBX["<<ipad<<"]="<<EnergyBX[ipad];
00157       // hits after the bunch crossing
00158       if ( EnergyBX[ipad] > theThreshold ) {
00159         if ( isZplus(ipad)) {
00160           if ( isInner(ipad) ) ZPinnerBX++;
00161           else ZPouterBX++;
00162         } else {
00163           if ( isInner(ipad) ) ZMinnerBX++;
00164           else ZMouterBX++;     
00165         }
00166       } 
00167       // hits before the bunch crossing
00168       if ( EnergyBXMinusDt[ipad] > theThreshold ) {
00169         if ( isZplus(ipad)) {
00170           if ( isInner(ipad) ) ZPinnerBXMinusDt++;
00171           else ZPouterBXMinusDt++;
00172         } else {
00173           if ( isInner(ipad) ) ZMinnerBXMinusDt++;
00174           else ZMouterBXMinusDt++;      
00175         }
00176       } 
00177     }
00178 
00179     if ( edm::isDebugEnabled() ) LogTrace("BSCTrig")<<" Zplus I="<<ZPinnerBX<<" Zminus I="<<ZMinnerBX<<" Zplus O="<<ZPouterBX<<"  Zminus O="<<ZMouterBX;
00180 
00181     // minimum bias technical triggers that are also connected to 'external condition' triggers -----------------
00182     bool bit32=false;    // min bias inner >=1
00183     if(ZPinnerBX >= 1 && ZMinnerBX >= 1) bit32 = true;
00184 
00185     bool bit33=false;    // min bias inner >=2
00186     if(ZPinnerBX >= 2 && ZMinnerBX >= 2) bit33 = true;
00187 
00188     bool bit34=false;    // min bias OR
00189     if(ZPinnerBX + ZMinnerBX + ZPouterBX + ZMouterBX >= 1) bit34 = true;
00190 
00191     bool bit35=false;    // high multiplicity
00192     if(ZPinnerBX == 8 && ZMinnerBX == 8) bit35 = true;
00193 
00194     // beam halo technical triggers ----------------------------------------------------------------
00195     bool bit36=false;    // beam 2 halo inner
00196     if(ZPinnerBX >= 1 && ZMinnerBXMinusDt >= 1) bit36 = true;
00197 
00198     bool bit37=false;    // beam 2 halo outer
00199     if(ZPouterBX >= 1 && ZMouterBXMinusDt >= 1) bit37 = true;
00200 
00201     bool bit38=false;    // beam 1 halo inner
00202     if(ZMinnerBX >= 1 && ZPinnerBXMinusDt >= 1) bit38 = true;
00203 
00204     bool bit39=false;    // beam 1 halo outer
00205     if(ZMouterBX >= 1 && ZPouterBXMinusDt >= 1) bit39 = true;
00206 
00207     // minimum bias technical triggers ---------------------------------------------------------
00208     bool bit40=false;    // min bias all >=1
00209     if(ZPinnerBX + ZPouterBX >= 1 && ZMinnerBX + ZMouterBX >= 1) bit40 = true;
00210 
00211     bool bit41=false;    // min bias all >=2
00212     if(ZPinnerBX + ZPouterBX >= 2 && ZMinnerBX + ZMouterBX >= 2) bit41 = true;
00213 
00214     bool bit42=false;    // beam 1 splash (-z)
00215     if(ZMinnerBX >= 2) bit42 = true;
00216 
00217     bool bit43=false;    // beam 2 splash (+z)
00218     if(ZPinnerBX >= 2) bit43 = true;
00219 
00220     for ( unsigned i=0; i< ttBits_.size();++i ){
00221       bool bit = false;
00222       if ( names_.at(i) == names_[0] ) bit = bit32;
00223       if ( names_.at(i) == names_[1] ) bit = bit33;
00224       if ( names_.at(i) == names_[2] ) bit = bit34;
00225       if ( names_.at(i) == names_[3] ) bit = bit35;
00226       if ( names_.at(i) == names_[4] ) bit = bit36;
00227       if ( names_.at(i) == names_[5] ) bit = bit37;
00228       if ( names_.at(i) == names_[6] ) bit = bit38;
00229       if ( names_.at(i) == names_[7] ) bit = bit39;
00230       if ( names_.at(i) == names_[8] ) bit = bit40;
00231       if ( names_.at(i) == names_[9] ) bit = bit41;
00232       if ( names_.at(i) == names_[10]) bit = bit42;
00233       if ( names_.at(i) == names_[11]) bit = bit43;
00234       ttVec.at(i)=L1GtTechnicalTrigger(names_.at(i), ttBits_.at(i), 0, bit) ;
00235       if ( edm::isDebugEnabled() ) LogTrace("AnaBsc") << "bit: "<<ttBits_[i] << " VALUE:"<<bit ;
00236     }
00237   } else ttVec.clear();
00238   std::auto_ptr<L1GtTechnicalTriggerRecord> output(new L1GtTechnicalTriggerRecord());
00239   output->setGtTechnicalTrigger(ttVec);    
00240   iEvent.put(output);
00241 }
00242 // ------------ method called once each job just before starting event loop  ------------
00243 void BSCTrigger::beginJob()
00244 {
00245 }
00246 
00247 // ------------ method called once each job just after ending the event loop  ------------
00248 void BSCTrigger::endJob() {
00249 }
00250 
00251 int BSCTrigger::getBSCNum( int id, float z ) {
00252   int zside = 0;
00253   if ( z > 0 ) zside = 1;
00254   if ( edm::isDebugEnabled() ) {
00255     int det    = (id&24)>>3;
00256     int station = id&7;
00257     LogTrace("BSCTrig")<<"id="<<id<<" zside="<<zside<<" det="<<det<<" station="<<station;
00258   }
00259   int BSCNum;
00260   if (id&16) BSCNum=32+(id&1)+(zside<<1) ;  // small paddles further from IP
00261   else BSCNum= (id&15)+(zside<<4);          // the BSC on the HF
00262   return BSCNum;
00263 }
00264 
00265 bool BSCTrigger::isInner( int id ){ 
00266   return ( (id&8)>>3 ) ;
00267 }
00268 
00269 bool BSCTrigger::isZplus( int id ){ 
00270   return ( (id&16)>>4 ) ;
00271 }
00272 
00273 //define this as a plug-in
00274 DEFINE_FWK_MODULE(BSCTrigger);