CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/SimCalorimetry/EcalSimAlgos/src/EcalHitResponse.cc

Go to the documentation of this file.
00001 #include "SimCalorimetry/EcalSimAlgos/interface/EcalHitResponse.h" 
00002 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVSimParameterMap.h"
00003 #include "SimCalorimetry/CaloSimAlgos/interface/CaloSimParameters.h"
00004 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVShape.h"
00005 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVHitCorrection.h"
00006 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVHitFilter.h"
00007 #include "SimCalorimetry/CaloSimAlgos/interface/CaloVPECorrection.h"
00008 #include "Geometry/CaloGeometry/interface/CaloGenericDetId.h"
00009 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00010 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00011 #include "FWCore/ServiceRegistry/interface/Service.h"
00012 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00013 #include "CLHEP/Random/RandPoissonQ.h"
00014 #include "CLHEP/Random/RandGaussQ.h"
00015 #include "FWCore/Utilities/interface/Exception.h"
00016 
00017 #include "CLHEP/Units/GlobalPhysicalConstants.h"
00018 #include "CLHEP/Units/GlobalSystemOfUnits.h" 
00019 #include <iostream>
00020 
00021 
00022 
00023 EcalHitResponse::EcalHitResponse( const CaloVSimParameterMap* parameterMap ,
00024                                   const CaloVShape*           shape         ) :
00025    m_parameterMap  ( parameterMap ) ,
00026    m_shape         ( shape        ) ,
00027    m_hitCorrection ( 0            ) ,
00028    m_PECorrection  ( 0            ) ,
00029    m_hitFilter     ( 0            ) ,
00030    m_geometry      ( 0            ) ,
00031    m_RandPoisson   ( 0            ) ,
00032    m_RandGauss     ( 0            ) ,
00033    m_minBunch      ( -10          ) ,
00034    m_maxBunch      (  10          ) ,
00035    m_phaseShift    ( 1            ) 
00036 {
00037    edm::Service<edm::RandomNumberGenerator> rng ;
00038    if ( !rng.isAvailable() ) 
00039    {
00040       throw cms::Exception("Configuration")
00041          << "EcalHitResponse requires the RandomNumberGeneratorService\n"
00042          "which is not present in the configuration file.  You must add the service\n"
00043          "in the configuration file or remove the modules that require it.";
00044    }
00045    m_RandPoisson = new CLHEP::RandPoissonQ( rng->getEngine() ) ;
00046    m_RandGauss   = new CLHEP::RandGaussQ(   rng->getEngine() ) ;
00047 }
00048 
00049 EcalHitResponse::~EcalHitResponse()
00050 {
00051    delete m_RandPoisson ;
00052    delete m_RandGauss   ;
00053 }
00054 
00055 CLHEP::RandPoissonQ* 
00056 EcalHitResponse::ranPois() const
00057 {
00058    return m_RandPoisson ;
00059 }
00060 
00061 CLHEP::RandGaussQ* 
00062 EcalHitResponse::ranGauss() const
00063 {
00064    return m_RandGauss ;
00065 }
00066 
00067 const CaloSimParameters*
00068 EcalHitResponse::params( const DetId& detId ) const
00069 {
00070    assert( 0 != m_parameterMap ) ;
00071    return &m_parameterMap->simParameters( detId ) ;
00072 }
00073 
00074 const CaloVShape*
00075 EcalHitResponse::shape() const
00076 {
00077    assert( 0 != m_shape ) ;
00078    return m_shape ;
00079 }
00080 
00081 const CaloSubdetectorGeometry*
00082 EcalHitResponse::geometry() const
00083 {
00084    assert( 0 != m_geometry ) ;
00085    return m_geometry ;
00086 }
00087 
00088 void 
00089 EcalHitResponse::setBunchRange( int minBunch , 
00090                                 int maxBunch  ) 
00091 {
00092    m_minBunch = minBunch ;
00093    m_maxBunch = maxBunch ;
00094 }
00095 
00096 void 
00097 EcalHitResponse::setGeometry( const CaloSubdetectorGeometry* geometry )
00098 {
00099    m_geometry = geometry ;
00100 }
00101 
00102 void 
00103 EcalHitResponse::setPhaseShift( double phaseShift )
00104 {
00105    m_phaseShift = phaseShift ;
00106 }
00107 
00108 double
00109 EcalHitResponse::phaseShift() const
00110 {
00111    return m_phaseShift ;
00112 }
00113 
00114 void 
00115 EcalHitResponse::setHitFilter( const CaloVHitFilter* filter)
00116 {
00117    m_hitFilter = filter ;
00118 }
00119 
00120 void 
00121 EcalHitResponse::setHitCorrection( const CaloVHitCorrection* hitCorrection)
00122 {
00123    m_hitCorrection = hitCorrection ;
00124 }
00125 
00126 void 
00127 EcalHitResponse::setPECorrection( const CaloVPECorrection* peCorrection )
00128 {
00129    m_PECorrection = peCorrection ;
00130 }
00131 
00132 void 
00133 EcalHitResponse::blankOutUsedSamples()  // blank out previously used elements
00134 {
00135    const unsigned int size ( m_index.size() ) ;
00136 
00137    for( unsigned int i ( 0 ) ; i != size ; ++i )
00138    {
00139       vSamAll( m_index[i] )->setZero() ;
00140    }
00141    m_index.erase( m_index.begin() ,    // done and make ready to start over
00142                   m_index.end()    ) ;
00143 }
00144 
00145 void 
00146 EcalHitResponse::run( MixCollection<PCaloHit>& hits ) 
00147 {
00148    blankOutUsedSamples() ;
00149 
00150    for( MixCollection<PCaloHit>::MixItr hitItr ( hits.begin() ) ;
00151         hitItr != hits.end() ; ++hitItr )
00152    {
00153       const PCaloHit& hit ( *hitItr ) ;
00154       const int bunch ( hitItr.bunch() ) ;
00155       if( m_minBunch <= bunch  &&
00156           m_maxBunch >= bunch  &&
00157           !isnan( hit.time() ) &&
00158           ( 0 == m_hitFilter ||
00159             m_hitFilter->accepts( hit ) ) ) putAnalogSignal( hit ) ;
00160    }
00161 }
00162 
00163 void
00164 EcalHitResponse::putAnalogSignal( const PCaloHit& inputHit )
00165 {
00166    PCaloHit hit ( inputHit ) ;
00167 
00168    if( 0 != m_hitCorrection ) m_hitCorrection->correct( hit ) ;
00169 
00170    const DetId detId ( hit.id() ) ;
00171 
00172    const CaloSimParameters* parameters ( params( detId ) ) ;
00173 
00174    const double signal ( analogSignalAmplitude( hit ) ) ;
00175 
00176    const double jitter ( hit.time() - timeOfFlight( detId ) ) ;
00177 
00178    const double tzero = ( shape()->timeToRise()
00179                           + parameters->timePhase() 
00180                           - jitter 
00181                           - BUNCHSPACE*( parameters->binOfMaximum()
00182                                          - m_phaseShift             ) ) ;
00183    double binTime ( tzero ) ;
00184 
00185    EcalSamples& result ( *findSignal( detId ) ) ;
00186 
00187    const unsigned int rsize ( result.size() ) ;
00188 
00189    for( unsigned int bin ( 0 ) ; bin != rsize ; ++bin )
00190    {
00191       result[ bin ] += (*shape())( binTime )*signal ;
00192       binTime += BUNCHSPACE ;
00193    }
00194 }
00195 
00196 EcalHitResponse::EcalSamples* 
00197 EcalHitResponse::findSignal( const DetId& detId )
00198 {
00199    const unsigned int di ( CaloGenericDetId( detId ).denseIndex() ) ;
00200    EcalSamples* result ( vSamAll( di ) ) ;
00201    if( result->zero() ) m_index.push_back( di ) ;
00202    return result ;
00203 }
00204 
00205 double 
00206 EcalHitResponse::analogSignalAmplitude( const PCaloHit& hit ) const
00207 {
00208    const DetId& detId ( hit.id() ) ;
00209 
00210    const CaloSimParameters& parameters ( *params( detId ) ) ;
00211 
00212    // OK, the "energy" in the hit could be a real energy, deposited energy,
00213    // or pe count.  This factor converts to photoelectrons
00214 
00215    double npe ( hit.energy()*parameters.simHitToPhotoelectrons( detId ) ) ;
00216 
00217    // do we need to doPoisson statistics for the photoelectrons?
00218    if( parameters.doPhotostatistics() ) npe = ranPois()->fire( npe ) ;
00219 
00220    if( 0 != m_PECorrection ) npe = m_PECorrection->correctPE( detId, npe ) ;
00221 
00222    return npe ;
00223 }
00224 
00225 double 
00226 EcalHitResponse::timeOfFlight( const DetId& detId ) const 
00227 {
00228    const CaloCellGeometry* cellGeometry ( geometry()->getGeometry( detId ) ) ;
00229    assert( 0 != cellGeometry ) ;
00230    return cellGeometry->getPosition().mag()*cm/c_light ; // Units of c_light: mm/ns
00231 }
00232 
00233 void 
00234 EcalHitResponse::add( const EcalSamples* pSam )
00235 {
00236    EcalSamples& sam ( *findSignal( pSam->id() ) ) ;
00237    sam += (*pSam) ;
00238 }
00239 
00240 int 
00241 EcalHitResponse::minBunch() const 
00242 {
00243    return m_minBunch ; 
00244 }
00245 
00246 int 
00247 EcalHitResponse::maxBunch() const 
00248 {
00249    return m_maxBunch ; 
00250 }
00251 
00252 EcalHitResponse::VecInd& 
00253 EcalHitResponse::index() 
00254 {
00255    return m_index ; 
00256 }
00257 
00258 const EcalHitResponse::VecInd& 
00259 EcalHitResponse::index() const
00260 {
00261    return m_index ; 
00262 }
00263 
00264 const CaloVHitFilter* 
00265 EcalHitResponse::hitFilter() const 
00266 { 
00267    return m_hitFilter ; 
00268 }
00269 
00270 const EcalHitResponse::EcalSamples* 
00271 EcalHitResponse::findDetId( const DetId& detId ) const
00272 {
00273    const unsigned int di ( CaloGenericDetId( detId ).denseIndex() ) ;
00274    return vSamAll( di ) ;
00275 }