CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/SimCalorimetry/HcalTrigPrimProducers/src/HcalTTPDigiProducer.cc

Go to the documentation of this file.
00001 #include "SimCalorimetry/HcalTrigPrimProducers/src/HcalTTPDigiProducer.h"
00002 
00003 #include "DataFormats/HcalDigi/interface/HFDataFrame.h"
00004 #include "DataFormats/HcalDetId/interface/HcalSubdetector.h"
00005 #include "DataFormats/HcalDigi/interface/HcalDigiCollections.h"
00006 #include "CalibFormats/HcalObjects/interface/HcalTPGRecord.h"
00007 #include "CalibFormats/HcalObjects/interface/HcalTPGCoder.h"
00008 #include "DataFormats/Common/interface/Handle.h"
00009 #include "FWCore/Framework/interface/ESHandle.h"
00010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00011 #include <cstdio>
00012 
00013 // DO NOT MODIFY: Mapping between iphi (array index) and TTP input (value) for HF
00014 const int HcalTTPDigiProducer::inputs_[] = { 30,66,4,44,4,44,0,68,
00015                                              0,68,16,48,16,48,6,46,
00016                                              6,46,2,70,2,70,18,50,
00017                                              18,50,12,40,12,40,8,52,
00018                                              8,52,20,36,20,36,14,42,
00019                                              14,42,10,54,10,54,22,38,
00020                                              22,38,24,56,24,56,32,60,
00021                                              32,60,28,64,28,64,26,58,
00022                                              26,58,34,62,34,62,30,66 } ;
00023 
00024 HcalTTPDigiProducer::HcalTTPDigiProducer(const edm::ParameterSet& ps) 
00025 {
00026     hfDigis_        = ps.getParameter<edm::InputTag>("HFDigiCollection") ; 
00027     maskedChannels_ = ps.getParameter< std::vector<unsigned int> >("maskedChannels") ;
00028     bit_[0] = ps.getParameter<std::string>("defTT8") ; 
00029     bit_[1] = ps.getParameter<std::string>("defTT9") ; 
00030     bit_[2] = ps.getParameter<std::string>("defTT10") ; 
00031     bit_[3] = ps.getParameter<std::string>("defTTLocal") ; 
00032 
00033     for (int i=0; i<4; i++) { 
00034         nHits_[i] = -1 ; nHFp_[i] = -1 ; nHFm_[i] = -1 ; 
00035         pReq_[i] = ' ' ; mReq_[i] = ' ' ; pmLogic_[i] = ' ' ;
00036         calc_[i] = sscanf(bit_[i].c_str(),"hits>=%d:hfp%c=%d%chfm%c=%d",
00037                           &(nHits_[i]),&(pReq_[i]),&(nHFp_[i]),
00038                           &(pmLogic_[i]),&(mReq_[i]),&(nHFm_[i])) ;
00039         if ( calc_[i] == 1 ) {
00040             if ( nHits_[i] < 0 )
00041                 throw cms::Exception("HcalTTPDigiProducer")
00042                     << "Unable to read logic for technical trigger" ;
00043         } else if ( calc_[i] == 6 ) {
00044             if ( nHits_[i] < 0 || nHFp_[i] < 0 || nHFm_[i] < 0 )
00045                 throw cms::Exception("HcalTTPDigiProducer")
00046                     << "Unable to read logic for technical trigger" ;
00047             if ( (pReq_[i] != '>' && pReq_[i] != '<') || 
00048                  (mReq_[i] != '>' && mReq_[i] != '<') ||
00049                  (pmLogic_[i] != ':' && pmLogic_[i] != '|') )
00050                 throw cms::Exception("HcalTTPDigiProducer")
00051                     << "Technical Trigger logic must obey the following format:\n"
00052                     "\"hits>=[A1]:hfp[B1]=[A2][C]hfm[B2]=[A3]\",\n"
00053                     "or \"hits>=[A1]\",\n"
00054                     "with A# >= 0, B# = (</>) and C = (:/|)" ;
00055         } else {
00056             throw cms::Exception("HcalTTPDigiProducer")
00057                 << "Unable to read logic for technical trigger" ;
00058         }
00059     }
00060 
00061     id_         = ps.getUntrackedParameter<int>("id",-1) ; 
00062     samples_    = ps.getParameter<int>("samples") ; 
00063     presamples_ = ps.getParameter<int>("presamples") ; 
00064     iEtaMin_    = ps.getParameter<int>("iEtaMin") ; 
00065     iEtaMax_    = ps.getParameter<int>("iEtaMax") ;
00066     threshold_  = ps.getParameter<unsigned int>("threshold") ;
00067     fwAlgo_     = ps.getParameter<int>("fwAlgorithm") ;
00068 
00069     SoI_ = ps.getParameter<int>("HFSoI") ;
00070 
00071     if ( samples_ > 8 ) {
00072         samples_ = 8 ;
00073         edm::LogWarning("HcalTTPDigiProducer") << "Samples forced to maximum value of 8" ; 
00074     }
00075     if ( presamples_ - SoI_ > 0 ) { // Too many presamples
00076         presamples_ = SoI_ ; 
00077         edm::LogWarning("HcalTTPDigiProducer") << "Presamples reset to HF SoI value" ; 
00078     }
00079         
00080     for (unsigned int i=0; i<maskedChannels_.size(); i++) {
00081         HcalDetId id(maskedChannels_.at(i)) ;
00082         if ( !id.validDetId(HcalForward,id.ieta(),id.iphi(),id.depth()) ) 
00083             throw cms::Exception("HcalTTPDigiProducer") << "Invalid HCAL Det ID" ; 
00084     }
00085     
00086     produces<HcalTTPDigiCollection>();
00087 }
00088 
00089 
00090 HcalTTPDigiProducer::~HcalTTPDigiProducer() {
00091 }
00092 
00093 bool HcalTTPDigiProducer::isMasked(HcalDetId id) {
00094 
00095     for ( unsigned int i=0; i<maskedChannels_.size(); i++ ) 
00096         if ( id.rawId() == maskedChannels_.at(i) ) return true ;
00097     return false ; 
00098 }
00099 
00100 bool HcalTTPDigiProducer::decision(int nP, int nM, int bit) {
00101 
00102     bool pOK = false ; bool mOK = false ;    
00103     if ( (nP + nM) < nHits_[bit] ) return false ;
00104     if ( calc_[bit] == 1 ) return ( (nP + nM) >= nHits_[bit] ) ;
00105 
00106     if ( pReq_[bit] == '>' ) pOK = ( nP >= nHFp_[bit] ) ; 
00107     else if ( pReq_[bit] == '<' ) pOK = ( nP <= nHFp_[bit] ) ; 
00108 
00109     if ( mReq_[bit] == '>' ) mOK = ( nM >= nHFm_[bit] ) ; 
00110     else if ( mReq_[bit] == '<' ) mOK = ( nM <= nHFm_[bit] ) ; 
00111 
00112     if ( pmLogic_[bit] == ':' ) return ( pOK && mOK ) ;
00113     else if ( pmLogic_[bit] == '|' ) return ( pOK || mOK ) ;
00114     
00115     // Should not ever get here...need to create a warning message
00116     edm::LogWarning("HcalTTPDigiProducer") << "Trigger logic exhausted.  Returning false" ; 
00117     return false ; 
00118 }
00119 
00120 void HcalTTPDigiProducer::produce(edm::Event& e, const edm::EventSetup& eventSetup) {
00121     
00122     // Step A: Get Inputs
00123     edm::Handle<HFDigiCollection> hfDigiCollection ; 
00124     e.getByLabel(hfDigis_,hfDigiCollection) ;
00125     edm::ESHandle<HcalTPGCoder> inputCoder ;
00126     eventSetup.get<HcalTPGRecord>().get(inputCoder) ;
00127 
00128     // Step B: Create empty output
00129     std::auto_ptr<HcalTTPDigiCollection> ttpResult(new HcalTTPDigiCollection()) ; 
00130     
00131     // Step C: Compute TTP inputs
00132     uint16_t trigInputs[40] ;
00133     int nP[8] ; int nM[8] ;
00134     for (int i=0; i<8; i++) {
00135         nP[i] = 0 ; nM[i] = 0 ; 
00136         for (int j=0; j<5; j++) trigInputs[j*8+i] = 0 ;
00137     }
00138     for (HFDigiCollection::const_iterator theDigi=hfDigiCollection->begin();
00139          theDigi!=hfDigiCollection->end(); theDigi++) {
00140         HcalDetId id = HcalDetId(theDigi->id()) ;
00141         if ( isMasked(id) ) continue ;
00142         if ( id.ietaAbs() < iEtaMin_ || id.ietaAbs() > iEtaMax_ ) continue ; 
00143 
00144         IntegerCaloSamples samples(id,theDigi->size()) ; 
00145         inputCoder->adc2Linear(*theDigi,samples) ;
00146 
00147         for (int relSample=-presamples_; relSample<(samples_-presamples_); relSample++) {
00148             if ( samples[SoI_+relSample] >= threshold_ ) {
00149                 int linSample = presamples_ + relSample ;
00150                 int offset = (-1+id.zside())/2 ; 
00151                 int shift = inputs_[id.iphi()+offset] ;
00152                 int group = 0 ;
00153                 while ( shift >= 16 ) { shift -= 16 ; group++ ; }
00154                 if ( !(trigInputs[(linSample*8)+group]&(1<<shift)) ) 
00155                     ( id.ieta() > 0 ) ? ( nP[linSample]++) : ( nM[linSample]++ ) ; 
00156                 trigInputs[(linSample*8)+group] |= (1<<shift) ;
00157             }
00158         }
00159     }
00160 
00161     // Step D: Compute trigger decision and fill TTP digi 
00162     uint8_t trigOutput[8] ;
00163     uint32_t algoDepBits[8] ;
00164     HcalTTPDigi ttpDigi(id_,samples_,presamples_,0,fwAlgo_,0) ;
00165     for (int linSample=0; linSample<8; linSample++) {
00166         trigOutput[linSample] = 0 ; algoDepBits[linSample] = 0 ;
00167         if ( linSample<samples_) {
00168             for (int j=0; j<4; j++) 
00169                 trigOutput[linSample] |= (decision(nP[linSample],nM[linSample],j)<<j) ;
00170             int nT = nP[linSample] + nM[linSample] ;
00171 
00172             // Algorithm Dependent bits for FW flavor = 1
00173             // NOTE: this disagrees with the fw var. names that implies (LSB) T,M,P (MSB)
00174             if ( fwAlgo_ == 1 ) algoDepBits[linSample] = (nT&0x7F) | ((nP[linSample]&0x3F)<<7) | ((nM[linSample]&0x3F)<<13) ; 
00175             ttpDigi.setSample((linSample-presamples_),&trigInputs[linSample*8],algoDepBits[linSample],trigOutput[linSample]) ;
00176         }
00177     }    
00178     ttpResult->push_back( ttpDigi ) ;
00179     
00180     // Step E: Put outputs into event
00181     e.put(ttpResult);
00182 }
00183